Как защитить веб-шрифты?

мой клиент купил шрифт, который я хотел бы использовать на своем веб-сайте, но компания, которая сделала шрифт (Adobe), сказала мне, что для этого текущего шрифта нет службы веб-шрифтов, и я могу использовать его на веб-сайте, только если я растрировать его или сделать невозможным загрузку/украсть шрифт каким-либо другим способом.

Поэтому вопрос:

Есть ли надежный способ защитить веб-шрифты?

(вторая необязательная часть)

Есть ли способ, который обычно считается достаточным для того, чтобы использование шрифта было юридически безопасным?

Что я узнал на данный момент:

1) Я слышал о Cufon, который использует файлы SVG, которые (согласно w3.org) предназначены для этой цели:

Целью шрифтов SVG является обеспечение доставки контуров глифов в средах, предназначенных только для отображения. Шрифты SVG, сопровождающие веб-страницы, должны поддерживаться только в ситуациях просмотра и просмотра. Приложения для редактирования графики или инструменты перевода файлов не должны пытаться преобразовывать шрифты SVG в системные шрифты. Цель состоит в том, чтобы файлы SVG были взаимозаменяемыми между двумя создателями контента, но не шрифты SVG, которые могут сопровождать эти файлы SVG. Вместо этого каждому создателю контента необходимо будет лицензировать данный шрифт, прежде чем он сможет успешно редактировать файл SVG.

Но я также видел несколько онлайн-конвертеров из SVG в обычные форматы шрифтов (на самом деле я их не пробовал).

2) Я также видел этот поток, в котором говорится, что это не совсем возможно, но ему два года, возможно, технологии продвинулись.: Как защитить веб-шрифты

3) Я также считаю, что в PDF есть какой-то способ сделать невозможным извлечение шрифта, несколько лет назад я видел PDF, из которого я не мог извлечь текст (даже с использованием сторонних инструментов), потому что внутри были намеренно перепутаны таблицы шрифтов, поэтому я пришлось преобразовать весь документ в изображение и использовать OCR. Однако это может быть не так, поскольку я пытался извлечь текст, а не шрифт.

4) Компании по продаже шрифтов должны как-то защищать свои шрифты (?)


person user2330401    schedule 30.01.2014    source источник
comment
Где есть желание, там и способ... Все, что видит ваш браузер, можно скачать/сохранить. Я не знаю, как они могут ожидать, что вы это сделаете, они не предлагают никакого надежного решения, потому что тогда они не несут ответственности за убытки. 99,9% ваших пользователей не будут думать о том, чтобы взять шрифт. Другие найдут способ...   -  person Lawrence Cherone    schedule 31.01.2014
comment
Отредактировал мой вопрос (добавил необязательную часть).   -  person user2330401    schedule 31.01.2014
comment
Даже если вы растеризовали изображения, кто-то может использовать эти изображения в качестве наложения для воссоздания шрифта :/   -  person crush    schedule 31.01.2014
comment
Достаточно ли юридически безопасно использовать шрифт возможный дубликат Как защитить WebFonts, Обратите внимание на часть сеанса в этом ответе, в основном это токен CSRF, этого может быть достаточно, чтобы остановить широкую публику.   -  person Lawrence Cherone    schedule 31.01.2014


Ответы (4)


По сути, если вы собираетесь использовать шрифт без изображений (что является ужасной практикой, и ее следует избегать, если вы говорите о более чем нескольких символах на странице!), вы не можете помешать людям реконструировать ваши шрифты. Например, обработка их как SVG до canvas (или SVG до VML), как это делает Cufon, заставит пользователей выполнять некоторую работу, если они хотят ее украсть, но есть множество конвертеров SVG->TFF.

Даже без конвертера вы все равно можете создать новый набор шрифтов на основе векторов, определенных SVG. Единственный способ предотвратить это — не предоставлять какую-либо систему векторных шрифтов (т. е. использовать растровые изображения), но это в основном разрушает доступность вашего сайта. И даже в этом случае, если вы написали динамическую систему для обслуживания шрифтов на основе изображений, если вы предоставляете пользователю растровое изображение изображения с достаточно высоким разрешением (т. векторы.

Все компании, продающие шрифты (по крайней мере, те, что я видел), предоставляют только версии своих шрифтов на основе изображений для предварительного просмотра и ограничивают максимальный размер шрифта, который вы можете продемонстрировать.

person Ben D    schedule 31.01.2014
comment
Я думаю о чем-то вроде javascript для рендеринга шрифта, но запрещающего доступ к этому файлу никому, кроме этого скрипта (разве Cufon не делает что-то подобное?). Также добавлена ​​необязательная часть к моему вопросу. - person user2330401; 31.01.2014
comment
Это то, что вам нужно будет настроить на вашем сервере (например, фильтровать по HTTP_REFERRER), но это заголовок, который можно подделать, поэтому вы не можете полагаться на него. И вы можете попробовать ограничить доступ по текущему URL-адресу (используя REQUEST_URI), но тогда злоумышленникам просто нужно изменить свой файл host, чтобы подделать запрошенный домен. Кто-то, кто знает, что делает, может восстановить оригиналы. - person Ben D; 31.01.2014
comment
У меня мало знаний в области интернет-безопасности, но на самом деле нет способа запретить просмотр файла всем пользователям, кроме сценария, который находится непосредственно на сервере? Просто мне это кажется странным. - person user2330401; 31.01.2014
comment
Ага. Браузеру требуется достаточно информации, чтобы иметь возможность отображать текст, и для любого масштабируемого шрифта (TTF, WOFF, SVG и т. д.) минимальной информацией, необходимой для отображения шрифта, являются математические выражения векторов букв. Но как только вы узнаете векторы, которые используются для создания букв, вы можете просто воссоздать шрифт. Растеризация позволяет обойти это (потому что вам никогда не придется открывать векторы для браузера), но, как я уже упоминал, она довольно неудобна для Интернета. Вы можете проделывать множество трюков с обфускацией, но в конце концов браузер должен иметь возможность отображать шрифт. - person Ben D; 31.01.2014

Возможно, вы могли бы использовать базовый подход CSRF и загружать шрифт только один раз за запрос, создавая ключи сеанса, срок действия которых истекает после одного использования, и проверяя реферер (который может сломаться, если пользователь очищает его при последующих запросах).

Но для того, чтобы что-то сделать ;p Я собрал пример того, что я имею в виду, это не 100%, но это предотвратит попытки широкой публики получить прямой доступ к шрифту. скачать исходный пример

Используя этот метод, чтобы получить шрифт, вам необходимо:

  1. Сделать запрос к странице, не загружая шрифт css. (фгк, завиток, т. д.)
  2. Разобрать исходники страниц и получить ключи из CSS.
  3. Затем сделайте собственный запрос к загрузчику шрифтов, установив реферер и используя пары ключ-значение.

    • Perhaps it will pass there expectations of protection.

CSS, что вы можете сделать, это вместо указания пути к шрифту использовать PHP для загрузки шрифта, таким образом вы можете добавить некоторые одноразовые номера в запрос.

@font-face {
    font-family: 'TheFontName';
    src: local('TheFontName'), url('<?php echo SITE_URL.'/fonts.php?font=TheFontName.woff&'.$_SESSION['font_csrf_key'].'='.$_SESSION['font_csrf_token']?>') format('woff');
    font-weight: normal;
    font-style: normal;
}

Пример (index.php)

<?php 
/**
 * @name ProtectFont
 * @link https://www.dropbox.com/s/xsbpw4g3xn4fzai/ProtectFont.zip
 */
session_start(); 

//Define paths
define('BASE_FOLDER', dirname($_SERVER['SCRIPT_NAME']));
define('SITE_ROOT',   pathinfo($_SERVER['SCRIPT_FILENAME'], PATHINFO_DIRNAME));
define('SITE_URL',    rtrim( 'http://'.$_SERVER['HTTP_HOST'].BASE_FOLDER, '/'));
//Site host will be checked against as the referrer host
define('SITE_HOST',   parse_url(SITE_URL, PHP_URL_HOST));

/* Now for the font protection, we create 2 CSRF keys, 
   one for the $_GET key and the other as the value.
*/
$_SESSION['font_csrf_key']     = sha1(uniqid());
$_SESSION['font_csrf_token']   = sha1(uniqid());
?>
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
@font-face {
    font-family: 'TheFontName';
    src: local('TheFontName'), url('<?php echo SITE_URL.'/fonts.php?font=TheFontName.woff&'.$_SESSION['font_csrf_key'].'='.$_SESSION['font_csrf_token']?>') format('woff');
    font-weight: normal;
    font-style: normal;
}
body {
  font-size: 110%;
}
h1{
  font-family: 'TheFontName',serif;
}
</style>
<body>

<h1>Your Font, try and nick me...</h1>

<p>This is the CSS thats on this page, the font is only accessible once for this request, if you try to link it will fail:<br>

<pre>
@font-face {
    font-family: 'TheFontName';
    src: local('TheFontName'), url(<span style="color:green">'<?php echo SITE_URL.'/fonts.php?font=TheFontName.woff&'.$_SESSION['font_csrf_key'].'='.$_SESSION['font_csrf_token']?></span>') format('woff');
    font-weight: normal;
    font-style: normal;
}
body {
  font-size: 110%;
}
h1{
  font-family: 'TheFontName',serif;
}
</pre>

<p>Using this method, to get the font you would need to:</p>

<ol>
  <li>Make a request to this page, without loading the css font. Can be done with file_get_content, curl 
  ect.</li>
  <li>Parse the pages source and get the <?php echo $_SESSION['font_csrf_key'].'='.$_SESSION['font_csrf_token']?> keys.</li>
  <li>Make a request to the font loader using the above key value pairs </li>
  <li>And set the referrer in that request to: <?php echo SITE_URL; ?></li>
</ol>

<p>Perhaps its enough to stop a few people but not everyone.</p>
<p>Where there's a will, there's a way... Anything 
that your browser sees can be downloaded/saved. I don't know how they can expect 
you todo this, they don't offer any reliable solution because then there not 
liable for loss. 99.9% of your users wont think about taking the font. Others 
will find a way...</p>

<p>Good luck</p>

</body>
</html>

Теперь мы переходим к загрузчику шрифтов fonts.php, этот файл загрузит шрифт только в том случае, если значения занавеса совпадают (токены CSRF и реферер), в противном случае он отправляет пустой 404.

Пример (fonts.php)

<?php
/**
 * Font loader, this file will only load the font if curtain values match
 */
session_start();

//Define script our paths
define('BASE_FOLDER', dirname($_SERVER['SCRIPT_NAME']));
define('SITE_ROOT',   pathinfo($_SERVER['SCRIPT_FILENAME'], PATHINFO_DIRNAME));
define('SITE_URL',    rtrim( 'http://'.$_SERVER['HTTP_HOST'].BASE_FOLDER, '/'));

//This will be checked against as the passed referer
define('SITE_HOST',   parse_url(SITE_URL, PHP_URL_HOST));

if(
    //Check required variables are set
    // -The tokens for the request
    isset($_SESSION['font_csrf_key']) &&
    isset($_SESSION['font_csrf_token']) &&

    // -The font you want to load
    isset($_GET['font']) &&

    // -The $_GET request key
    isset($_GET[$_SESSION['font_csrf_key']]) &&

    // -The referer
    isset($_SERVER["HTTP_REFERER"])&&

    // - Validate session keys with the passed token
    $_GET[$_SESSION['font_csrf_key']] == $_SESSION['font_csrf_token'] &&

    // - Validate the Referer
    parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST) == SITE_HOST
    ){
        //check font exists
        if(file_exists(SITE_ROOT.'/_fonts/'.basename($_GET['font']))){

            //no cache
            header("Cache-control: no-store, no-cache, must-revalidate");
            header("Expires: Mon, 26 Jun 1997 05:00:00 GMT");
            header("Pragma: no-cache");
            //I think this is the right header
            header("Content-Type: application/octet-stream");
            set_time_limit(0);
            //ok nows lets load and send the font
            $font = null;
            $h = fopen(SITE_ROOT.'/_fonts/'.basename($_GET['font']), 'rb');
            if($h){
                while ($line = fgets($h, 4096)){
                    $font .= $line;
                }
            }else{
                header("HTTP/1.0 404 Not Found");
            }
            fclose($h);
            header('Content-Length: '.strlen($font));
            echo $font;
        }else{
            header("HTTP/1.0 404 Not Found");
        }
}
else{
    header("HTTP/1.0 404 Not Found");
}

//Unset to stop second access
unset($_SESSION['font_csrf_key'], $_SESSION['font_csrf_token']);
?>

Надеюсь, это поможет. загрузите исходный код здесь. Вы также можете добавить файлы cookie к защите, чтобы добавить дополнительный уровень защиты. Или даже изменить имя файла TheFontName.woff на ключ сеанса и сохранить реальное значение имени файла в сеансе, или смешать его и добавить приманки в строку запроса, вы можете установить правильное значение или порядок в сеансе. Будьте изобретательны, но в конце концов это не пуленепробиваемый. Удачи

person Lawrence Cherone    schedule 31.01.2014
comment
Хорошо, но что помешает пользователю открыть инструменты разработчика и просмотреть сетевой трафик, а затем найти шрифт и получить его обратно из кеша браузера? - person kuroi neko; 31.01.2014
comment
Вы абсолютно правы ... спасибо, что не понизили голосование, ничто не является приватным, даже если бы не было таких инструментов разработки браузера, можно было бы вытащить данные из памяти или перехватить сетевые пакеты. Но он обеспечивает небольшой уровень защиты от широкой публики, загружающей шрифт напрямую, я заметил, что Возможно, он передаст ожидания защиты. это был вопрос ОП, он отметил, что это не 100% и не пуленепробиваемый в паре мест. просто пытаюсь помочь ОП - person Lawrence Cherone; 02.02.2014
comment
Я не минусовал тебя. Я думаю, что ваш пост очень ясно говорит о невозможности получить 100% гарантию, поэтому я считаю его действительным и полезным. - person kuroi neko; 02.02.2014
comment
@loz-cherone-ツ Можно ли добавить PHP-скрипты на однофайловую HTML-страницу? А если я хочу использовать только base64? - person ; 06.12.2014

Невозможно предотвратить обратное кодирование шрифтов в любой формат. В некоторых форматах, таких как TTF, есть информация об авторских правах, но онлайн-конвертеры могут ее игнорировать.

Однако вы можете сделать шрифт относительно непрактичным в использовании, то есть лишить его привлекательности для потенциальных хакеров.

Например, вы можете сократить его до подмножества настоящих глифов, если знаете, что на вашей странице не будут использоваться некоторые символы. Я не имею в виду разделение шрифта на части. Я имею в виду не предоставлять какой-либо глиф, который не используется на вашем сайте. Например, если ваш сайт на английском языке, удалите все диакритические знаки или нелатинские кодировки.

Кроме того, некоторая уточненная информация, такая как кернинг и хинтинг, теряется при использовании некоторых форматов (например, шрифты SVG представляют собой простые глифы). Обратное кодирование их в TTF дало бы версию исходного шрифта для бедняков.

С другой стороны, вывод SVG довольно плохой для небольших размеров шрифта. Использование SVG, скорее всего, навредит вашему сайту прежде, чем навредит ворам.

person kuroi neko    schedule 31.01.2014
comment
+1 за информацию о плохом выводе SVG, это, вероятно, сэкономило мне много времени - person user2330401; 31.01.2014
comment
Не за что. Был здесь, сделал это. Не вижу причин, почему вы должны страдать так, как я :) - person kuroi neko; 31.01.2014

Вероятно, нет юридически безопасного способа сделать это, так как даже урезанная версия шрифта все равно будет содержать информацию, защищенную авторским правом, и любые другие меры защиты можно будет обойти.

Если шрифт не предлагается с явной веб-лицензией с менее строгими условиями, лучше не использовать его в Интернете, кроме как в виде растровых изображений. Период.

Я хотел бы посмотреть, предлагают ли такие сервисы, как Google Fonts, шрифт, достаточно похожий по внешнему виду.

Вы также можете присмотреться, чтобы узнать, предоставляет ли другой лицензиар шрифтов веб-лицензию на тот же или, по крайней мере, похожий шрифт. Идентификатор шрифта, такой как Identifont, может помочь вам найти похожие шрифты.

person Pekka    schedule 31.01.2014
comment
+1 за это - почти всегда есть что-то достаточно близкое, чтобы все было хорошо, если только вы не имеете дело с очень придирчивым клиентом. - person ceejayoz; 31.01.2014