Découvrez comment l'API Local Font Access vous permet d'accéder aux polices installées localement par l'utilisateur et d'obtenir des informations de bas niveau les concernant.
Polices Web sécurisées
Si vous développez des sites Web depuis suffisamment longtemps, vous vous souvenez peut-être
polices Web.
Ces polices sont connues pour être disponibles sur presque toutes les instances des systèmes d'exploitation les plus utilisés
(à savoir Windows, macOS, les distributions Linux les plus courantes, Android et iOS). Au début des années 2000,
Microsoft a même ouvert la voie
cette initiative
appelées polices de base TrueType pour le Web, qui permettaient de télécharger sans frais ces polices
objectif que "chaque fois que vous visitez un site Web qui les spécifie, vous voyez les pages exactement comme le
prévu par le concepteur de site. Oui, cela incluait les sites définis dans
Comic Sans MS. Voici un
une pile de polices standard sécurisée sur le Web (avec la solution de remplacement ultime
sans-serif
police) peut se présenter comme suit:
body {
font-family: Helvetica, Arial, sans-serif;
}
Polices Web
L'époque où les polices Web étaient vraiment essentielles est révolue depuis longtemps. Aujourd'hui, nous avons
polices Web, dont certaines sont
et même des polices variables, que nous pouvons ajuster davantage en modifiant les valeurs des
différents axes exposés. Vous pouvez utiliser des polices Web en déclarant
@font-face
au début du CSS,
qui spécifie le ou les fichiers de police à télécharger:
@font-face {
font-family: 'FlamboyantSansSerif';
src: url('flamboyant.woff2');
}
Vous pouvez ensuite utiliser la police Web personnalisée en spécifiant la
font-family
, comme d'habitude:
body {
font-family: 'FlamboyantSansSerif';
}
Polices locales comme vecteur d'empreinte
La plupart des polices Web viennent du Web. Fait intéressant,
Propriété src
dans @font-face
, à l'exception de la déclaration
url()
accepte également
local()
. Cela permet (surprise) de charger localement des polices personnalisées. Si l’utilisateur a
FlamboyantSansSerif installé sur le système d'exploitation, la copie locale sera utilisée à la place
en cours de téléchargement:
@font-face {
font-family: 'FlamboyantSansSerif';
src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}
Cette approche fournit un mécanisme de secours
qui permet potentiellement d'économiser de la bande passante. Sur Internet,
Malheureusement, nous ne pouvons pas avoir de belles choses. Le problème avec la fonction local()
est qu'elle peut être
utilisés de manière abusive pour le fingerprinting des navigateurs. Il s'avère que la liste des polices
installées par un utilisateur peut être assez
identifier. De nombreuses entreprises ont leurs propres polices d'entreprise qui sont installées sur les
les ordinateurs portables. Par exemple, Google utilise une police d'entreprise appelée Google Sans.
Un attaquant peut essayer de déterminer pour quelle entreprise quelqu’un travaille en testant l’existence d’une de nombreuses polices d'entreprise connues, comme Google Sans. L’attaquant tente de rendre du texte dans ces polices sur un canevas et mesurer les glyphes. Si les glyphes correspondent à la forme connue du la police d’entreprise, l’attaquant a un coup. Si les glyphes ne correspondent pas, l’attaquant sait qu’un la police de remplacement par défaut a été utilisée, car la police d'entreprise n'a pas été installée. Pour en savoir plus sur et d'autres attaques par empreinte digitale des navigateurs, lisez le étude rédigée par Laperdix et al.
Les polices de l’entreprise à part, même la seule liste des polices installées peut permettre d’identifier. La situation avec ce vecteur d'attaque est devenu tellement mauvais que récemment l'équipe WebKit décidé "N'incluez [dans la liste des polices disponibles] que les polices Web et les polices fournies avec le système de fichiers, mais pas celles installées localement par l'utilisateur". Voici un article sur l'octroi d'un accès aux polices locales.)
API Local Font Access
Au début de cet article, vous avez peut-être été de mauvaise humeur. Peut-on vraiment ne pas avoir des choses ? Ne vous inquiétez pas. Nous pensons pouvoir, et peut-être, que tout n'est pas sans espoir. Mais d'abord, laissez-moi répondre à une question que vous vous posez peut-être.
Pourquoi avons-nous besoin de l'API Local Font Access quand il existe des polices Web ?
Les outils de conception et de graphisme de qualité professionnelle ont toujours été difficiles à appliquer Web. L'un des obstacles a été l'impossibilité d'accéder à l'ensemble des ressources professionnelles et de les utiliser les polices construites et suggérées que les concepteurs ont installées localement. Les polices Web permettent de publier mais n'autorise pas l'accès programmatique aux formes de glyphes vectoriels et aux tables de polices utilisées par rastériseurs pour afficher les contours des glyphes. De même, il n'existe aucun moyen d'accéder au binaire d'une police Web données.
- Les outils de conception ont besoin d'accéder aux octets de police pour effectuer leur propre implémentation de mise en page OpenType et permettre des outils de conception à s'associer à des niveaux inférieurs, pour des actions telles que l'exécution de filtres vectoriels ou sur les formes des glyphes.
- Les développeurs peuvent avoir d'anciennes piles de polices pour leurs applications qu'ils importent sur le Web. Pour utiliser ces piles, elles nécessitent généralement un accès direct aux données de police, ce qui n'est pas le cas des polices Web que vous fournissez.
- Il est possible que certaines polices ne soient pas concédés sous licence pour une diffusion sur le Web. Par exemple, Linotype dispose d'une licence pour Certaines polices ne peuvent être utilisées que sur ordinateur.
L'API Local Font Access tente de résoudre ces problèmes. Il se compose de deux parties :
- Une API d'énumération des polices, qui permet aux utilisateurs d'accorder l'accès à l'ensemble des systèmes disponibles et les polices de caractères.
- À partir de chaque résultat d'énumération, la possibilité de demander un conteneur SFNT de bas niveau (orienté octet) l'accès, qui inclut les données de police complètes.
Prise en charge des navigateurs
Navigateurs pris en charge
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
Utiliser l'API Local Font Access
Détection de caractéristiques
Pour vérifier si l'API Local Font Access est compatible, utilisez:
if ('queryLocalFonts' in window) {
// The Local Font Access API is supported
}
Énumérer les polices locales
Pour obtenir la liste des polices installées localement, vous devez appeler window.queryLocalFonts()
. La
première fois, une invite d'autorisation s'affiche, que l'utilisateur peut approuver ou refuser. Si l'utilisateur
approuve l'interrogation de ses polices locales, le navigateur renvoie un tableau contenant les données de police.
que vous pouvez lire en boucle. Chaque police est représentée par un objet FontData
avec les propriétés family
.
(par exemple, "Comic Sans MS"
), fullName
(par exemple, "Comic Sans MS"
), postscriptName
(par
par exemple, "ComicSansMS"
) et style
(par exemple, "Regular"
).
// Query for all available fonts and log metadata.
try {
const availableFonts = await window.queryLocalFonts();
for (const fontData of availableFonts) {
console.log(fontData.postscriptName);
console.log(fontData.fullName);
console.log(fontData.family);
console.log(fontData.style);
}
} catch (err) {
console.error(err.name, err.message);
}
Si vous n'êtes intéressé que par un sous-ensemble de polices, vous pouvez également les filtrer en fonction du PostScript.
en ajoutant un paramètre postscriptNames
.
const availableFonts = await window.queryLocalFonts({
postscriptNames: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});
Accéder aux données SFNT
L'accès complet au SFNT est disponible via la méthode blob()
du
FontData
. SFNT est un format de fichier de police
qui peut contenir d’autres polices, telles que PostScript,
Polices TrueType, OpenType, Web Open Font Format (WOFF), etc.
try {
const availableFonts = await window.queryLocalFonts({
postscriptNames: ['ComicSansMS'],
});
for (const fontData of availableFonts) {
// `blob()` returns a Blob containing valid and complete
// SFNT-wrapped font data.
const sfnt = await fontData.blob();
// Slice out only the bytes we need: the first 4 bytes are the SFNT
// version info.
// Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
const sfntVersion = await sfnt.slice(0, 4).text();
let outlineFormat = 'UNKNOWN';
switch (sfntVersion) {
case '\x00\x01\x00\x00':
case 'true':
case 'typ1':
outlineFormat = 'truetype';
break;
case 'OTTO':
outlineFormat = 'cff';
break;
}
console.log('Outline format:', outlineFormat);
}
} catch (err) {
console.error(err.name, err.message);
}
Démo
Vous pouvez voir l'API Local Font Access en action dans le fichier
demo ci-dessous. N'oubliez pas de consulter également les
code source. La version de démonstration
présente un élément personnalisé appelé <font-select>
qui
et implémente un sélecteur de police local.
Considérations liées à la confidentialité
L'autorisation "local-fonts"
semble fournir une surface hautement exploitable par empreinte digitale. Toutefois,
les navigateurs sont libres de renvoyer
ce qu’ils veulent. Par exemple, les navigateurs axés sur l'anonymat peuvent choisir
pour ne fournir qu'un ensemble de polices
par défaut intégrées au navigateur. De même, les navigateurs ne sont pas obligatoires
pour fournir les données de table exactement
telles qu'elles apparaissent sur le disque.
Dans la mesure du possible, l'API Local Font Access est conçue pour n'exposer que les informations exactes nécessaires pour activer les cas d'utilisation mentionnés. Les API système peuvent générer une liste de polices installées qui ne sont pas dans un aléatoire ou dans un ordre trié, mais dans l’ordre d’installation des polices. Renvoyer exactement la liste de les polices installées fournies par une telle API système peuvent exposer des données supplémentaires pouvant être utilisées pour le fingerprinting et les cas d'utilisation que nous souhaitons activer ne sont pas facilités par le maintien de cet ordre. En tant que résultat, cette API exige que les données renvoyées soient triées avant d'être renvoyées.
Sécurité et autorisations
L'équipe Chrome a conçu et mis en œuvre l'API Local Font Access selon les principes fondamentaux définies dans la section Contrôler l'accès à des fonctionnalités puissantes de plate-forme Web, y compris les règles le contrôle, la transparence et l'ergonomie.
Contrôle des utilisateurs
L'accès aux polices d'un utilisateur est entièrement sous son contrôle et ne lui sera pas autorisé à moins que
Autorisation "local-fonts"
, comme indiqué dans
registre d'autorisations est accordée.
Transparence
Si un site a été autorisé à accéder aux polices locales de l'utilisateur est visible dans le fiche d'information du site.
Persistance des autorisations
L'autorisation "local-fonts"
sera conservée entre les actualisations de la page. Elle peut être révoquée via la
informations sur le site.
Commentaires
L'équipe Chrome aimerait connaître votre avis sur l'API Local Font Access.
Présentez-nous la conception de l'API
Y a-t-il un aspect de l'API qui ne fonctionne pas comme prévu ? Ou manque-t-il des méthodes ou les propriétés dont vous avez besoin pour mettre en œuvre votre idée ? Vous avez une question ou un commentaire sur la sécurité ? Signalez un problème de spécification dans le dépôt GitHub correspondant ou ajoutez vos commentaires à un problème existant.
Signaler un problème d'implémentation
Avez-vous détecté un bug dans l'implémentation de Chrome ? Ou l'implémentation est-elle différente des spécifications ?
Signalez un bug sur new.crbug.com. Veillez à inclure autant
de détails que possible,
des instructions simples pour le reproduire et saisissez Blink>Storage>FontAccess
dans la zone Composants.
Glitch est idéal pour partager des répétitions rapidement et facilement.
Apportez votre soutien à l'API
Prévoyez-vous d'utiliser l'API Local Font Access ? Votre assistance publique aide l'équipe Chrome à hiérarchisent les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge.
Envoyez un tweet à @ChromiumDev en utilisant le hashtag.
#LocalFontAccess
et laissez
où et comment vous l'utilisez.
Liens utiles
- Vidéo explicative
- Brouillon de la spécification
- Bug Chromium relatif à l'énumération des polices
- Bug Chromium concernant l'accès au tableau des polices
- Entrée ChromeStatus
- Dépôt GitHub
- Examen TAG
- Position des normes de Mozilla
Remerciements
La spécification de l'API Local Font Access a été modifiée par Emil A. Eklund Alex Russell, Joshua Bell et Olivier Yiptong. Cet article a été examiné par Joe Medley, Dominik Röttsches Olivier Yiptong. Image héros de Brett Jordan sur Unsplash.