Текст, которого нет

Автор: admin от 8-10-2016, 14:30, посмотрело: 437

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


Но есть нюанс


В Unicode есть символы, видеть которые не положено.
Текстовый редактор может просто отрендерить текст с таким символом, а может предпринять какие-то действия, чтобы сделать его заметным.


Кто же они?

























































КодПримерНазвание
U+2060foobarWORD JOINER
U+2061foobarFUNCTION APPLICATION
U+2062foobarINVISIBLE TIMES
U+2063foobarINVISIBLE SEPARATOR
U+180Efoo?barMONGOLIAN VOWEL SEPARATOR
U+200BfoobarZERO WIDTH SPACE
U+200Cfoo???barZERO WIDTH NON-JOINER
U+200Dfoo?barZERO WIDTH JOINER
U+FEFFfoobarZERO WIDTH NO-BREAK SPACE

Word joiner, U+2060

Пришёл на смену zero-width no-break space (U+FEFF), потому что U+FEFF стал использоваться для кодирования BOM (byte-order mask, несколько байт в начале файла, обозначающие его кодировку и порядок байт). Этот символ запрещает перенос строки там, где он встречается.


Zero-width no-break space, U+FEFF

Устаревший символ, заменён на word joiner, использовался в тех же целях.


Zero-width joiner, U+200D

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


Zero-width non-joiner, U+200C

В начертаниях с лигатурами можно вставить его между буквами, чтобы лигатуры не было:


Текст, которого нет


Он втречаетя даже на клавиатурах:


Текст, которого нет


Zero-width space, U+200B

Используется, когда нужно обозначить границу слов, не вставляя пробел. Этот текст будет переноситься по словам:


WordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWord


А этот нет:


WordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWord


Invisible Operators: function application U+2061, invisible times U+2062, invisible separator U+2063

"Невидимые операторы", добавленные в Unicode 3.2. Нужны для обозначения математических операций в выражениях.


Например, эта запись: Aij
Может означать или индекс (i, j) в двумерном массиве, или индекс i*j в одномерном. Для устранения неоднозначности можно использовать или Invisible times, или Invisible separator, чтобы было понятно, что имелось в виду.


Аналогчино, f (x + y), это или умножение, или функция.


Визуально они не должны отличаться, но некоторые парсеры смогут понять, что имелось в виду.


Mongolian vowel separator, U+180E

Из названия понятно, для чего он. Этот символ уже не раз вызывал проблемы. Очень хорошо описан в этом ответе.


Как это выглядит


Конечно же, отображение зависит не только от редактора, но ещё и от шрифта, посмотрим на рендеринг текста, не меняя настроек редакторов.


Atom, Sublime, VSCode, Xamarin Studio, XCode, Notepad++:


Текст, которого нет


Cat не показывает их:


Текст, которого нет


Vim тоже не сообщает о некоторых символах, даже с включённой настройкой set list, а вот less справляется лучше:


Текст, которого нет


Web


GitHub, вот так показываются эти символы в pull request-ах и diff-ах:


Текст, которого нет


Один из популярных редакторов кода, CodeMirror:


Текст, которого нет


В том же CodeMirror, используемом jsbin, в IE часть символов видна:


Текст, которого нет


ACE догадывается, что там бяка, и говорит, что что-то тут нечисто, но вот что именно — показывает не всегда:


Текст, которого нет


Редакторы кода и diff tools


Редакторы на платформе IntelliJ:


Текст, которого нет


Разные инструменты сравнения кода под macOS (P4Merge, FileMerge, KDiff3):


Текст, которого нет


KDiff3, попытка засчитана, но этого не достаточно.


SourceTree: не обрабатывает текст вообще никак, плохо:


Текст, которого нет


Tortoise, тоже почти ничего:


Текст, которого нет


git diff: молодец, показал всё, ещё и выделил. Просто прекрасно, для diff tools это образец для подражания:


Текст, которого нет


Anguish: brainfuck, которого нет


Кто-то сделал язык программирования Anguish, использующий только невидимые символы.


Он основан на brainfuck, но использует не знаки пунктуации, а символы, о которых мы говорили выше.


Есть даже интерпретатор на Perl и примеры использования.


Эксплуатация


Плохой код, фу таким быть, сделать закладку можно совсем просто:


function f() {
  // ну вы поняли, на что заменить
  return 'access_denined';
}
let code = f();
if (code === 'access_denied') {
  return 401;
}

Что делать


Пиши чистый код, %username%. Следуй best practices, их придумали не просто так, а для того чтобы держать меньше вещей в голове, в том числе своевременно замечая такие штуки. Увидел магическую строчку, странный или непроверяемый default case, ещё что-то: есть время — не поленись, перепиши как надо. Проводи код-ревью, смотри что коммитят в твою репу, поддерживай хорошее покрытие. Помни, что строке может быть не только то, что видно на экране, проверь в hex-редакторе, если возникло подозрение.


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


Почитать



  • Unicode Demystified, A Practical Programmer’s Guide to the Encoding Standard, by Richard Gillam (вы знаете, где искать) — хорошая книга про unicode, многое рассказано, в том числе и о таких символах



Источник: Хабрахабр

Категория: Программирование, Информационная безопасность

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *