Экранирование символов
Экранирование символов — замена в тексте управляющих символов на соответствующие текстовые подстановки.
Содержание
Определение
Обычно языки программирования, текстовые командные интерфейсы, языки разметок текста (HTML, TEX, wiki) имеют дело со структурированным текстом, в котором некоторые символы (и их комбинации) используются в качестве управляющих, в том числе управляющих структурой текста. В ситуации, когда необходимо использовать такой символ в качестве «обычного символа языка», применяют экранирование.
Условно экранирование может быть разделено на три типа:
Отсутствие экранирования как причина уязвимости
Экранирование символов привлекает особое внимание, когда структурированный текст генерируется автоматически. Включение в текст произвольных строковых данных предполагает обязательное экранирование в них управляющих символов. В то же время, очень часто реальные строки таких символов не содержат, что позволяет программисту пропускать эту операцию совсем и получать более простую программу, корректно работающую с «любыми разумными» строковыми данными. Однако, такой упрощенный код имеет скрытую уязвимость, потому что стороннее лицо (автор строковых данных) получает несанкционированную возможность влиять на структуру генерируемого текста. Уязвимость становится серьёзной, если созданный текст является чьей-то программой. Традиционно таким проблемам подвержены системы, использующие языки SQL (см. SQL-injection) и HTML (см. Сross Site Sсriрting).
Примеры
Экранирование одиночного символа
Экранирование группы символов
Экранирование текста с завершающим символом
Полезное
Смотреть что такое «Экранирование символов» в других словарях:
ГОСТ 27459-87: Системы обработки информации. Машинная графика. Термины и определения — Терминология ГОСТ 27459 87: Системы обработки информации. Машинная графика. Термины и определения оригинал документа: 5. Абсолютная команда визуализации Absolute command Команда визуализации, в которой используются абсолютные координаты… … Словарь-справочник терминов нормативно-технической документации
Инъекция SQL — Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия
Внедрение SQL-кода — (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL кода. Внедрение SQL, в зависимости от типа используемой СУБД и условий… … Википедия
SQL-инъекция — Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия
SQL injection — Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия
SQL инъекция — Внедрение SQL кода (англ. SQL injection) один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL, в зависимости от типа используемой СУБД и условий внедрения,… … Википедия
Base64 — буквально означает позиционная система счисления с основанием 64. Здесь 64 это наибольшая степень двойки (26), которая может быть представлена с использованием печатных символов ASCII. Эта система широко используется в электронной… … Википедия
@ — У этого термина существуют и другие значения, см. AT (значения). Не следует путать с «А в круге» Ⓐ. @ … Википедия
Advanced Direct Connect — (ADC) протокол для пиринговых сетей, основанный на протоколе Direct Connect (DC). ADC клиенты подключаются к центральному серверу и обмениваются файлами напрямую между участниками сети. Эту статью следует викифицировать … Википедия
Позиционная система счисления с основанием 64 — Base64 буквально означает позиционная система счисления с основанием 64. Здесь 64 это наибольшая степень двойки (26), которая может быть представлена с использованием печатных символов электронной почте для представления бинарных файлов в… … Википедия
Экранирование (или что нужно знать для работы с текстом в тексте)
SQL инъекции, подделка межсайтовых запросов, поврежденный XML… Страшные, страшные вещи, от которых мы все бы хотели защититься, да вот только знать бы почему это все происходит. Эта статья объясняет фундаментальное понятие, стоящее за всем этим: строки и обработка строк внутри строк.
Основная проблема
Это всего лишь текст. Да, просто текст — вот она основная проблема. Практически все в компьютерной системе представлено текстом (который, в свою очередь, представлен байтами). Разве что одни тексты предназначены для компьютера, а другие — для людей. Но и те, и те, всё же остаются текстом. Чтобы понять, о чем я говорю, приведу небольшой пример:
Не поверите: это — текст. Некоторые люди называют его XML, но это — просто текст. Возможно, он не подойдет для показа учителю английского языка, но это — всё еще просто текст. Вы можете распечатать его на плакате и ходить с ним на митинги, вы можете написать его в письме своей маме… это — текст.
Тем не менее, мы хотим, чтобы определенные части этого текста имели какое-то значение для нашего компьютера. Мы хотим, чтобы компьютер был в состоянии извлечь автора текста и сам текст отдельно, чтобы с ним можно было что-то сделать. Например, преобразовать вышеупомянутое в это:
Иными словами, мы использовали определенные правила в нашем тексте, чтобы обозначить некое особое значение, которое кто-то, соблюдая те же правила, мог бы использовать.
Ладно, это всё не так уж и трудно понять. А что если мы хотим использовать эти забавные скобки, имеющие какое-то особое значение, в нашем тексте, но без использования этого самого значения. Примерно так:
Теперь, текст должен стать полностью однозначным. » » — «>».
Техническое определение этого — экранирование, мы избегаем специальные символы, когда не хотим, чтобы они имели свое особое значение.
Если определенные символы или последовательности символов в тексте имеют особое значение, то должны быть правила, определяющие, как разрешить ситуации, когда эти символы должны использоваться без привлечения своего особого значения. Или, другими словами, экранирование отвечает на вопрос: «Если эти символы такие особенные, то как мне их использовать в своем тексте?».
Как можно было заметить в примере выше, амперсанд (&) — это тоже специальный символ. Но что делать, если мы хотим написать » & «, т.е. мы должны написать: » < «
Другие примеры
XML — не единственный случай «страдания» от специальных символов. Любой исходный код, в любом языке программирования может это продемонстрировать:
Всё просто — обычный текст четко отделяется от «не текста» двойными кавычками. Таким же образом можно использовать и мой текст из курса математического анализа:
Клево! И даже не нужно прибегать к экранированию! Но, подождите, а что, если я хочу процитировать кого-нибудь?
Хм… печаль, тоска. Как человек, Вы можете определить где начинается и заканчивается текст и где находится цитата. Однако это снова стало неоднозначным для любого компьютера. Мы должны придумать какие-то правила экранирования, которые помогали бы нам различить буквальный » и «, который означает конец текста. Большинство языков программирование используют косую черту:
«\» делает символ после него не специальным. Но это, опять-таки, значит, что «\» — специальный символ. Для однозначного написания этого символа в тексте, к нему нужно добавить такой же символ, написав: «\\». Забавно, не так ли?
Атака!
Не всё было бы так плохо, если бы просто должны были прибегать к экранированию. Напрягает конечно, но это не так ужасно. Проблемы начинаются, когда одни программы пишут текст для других программ, чтобы те могли его «читать». И нет, это не научная фантастика, это происходит постоянно. Например, на этом сайте, вы, публикуя сообщение, не набираете его в ручную в формате HTML, а пишите лишь только текст, который, в последствие, преобразуется этим сайтом в HTML, после чего, уже браузер, преобразует «сгенерированный» HTML снова в читабельный текст.
Другой распространенный пример и источник многих проблем безопасности — SQL запросы. SQL — язык, предназначенный для упрощения общения с базами данных:
В этом тексте практически нет никаких специальных символов, в основном английские слова. И все же, фактически у каждого слова в SQL есть особое значение. Это используется во многих языках программирования во всем мире в той или иной форме, например:
Эти две простые строки абстрагируют от нас ужасно сложную задачу запроса программой у БД данных, удовлетворяющих нашим требованиям. БД «просеивает», возможно, терабайты битов и байтов, чтобы вернуть красиво отформатированный результат программе, сделавшей запрос. Серьезно, вся эта хрень инкапсулирована в простом англо-подобном предложении.
Для того, чтобы сделать это полезным, подобные запросы не хард-кодятся, а строятся на основе пользовательского ввода. Это же предложение, направленное на использование разными пользователями:
В случае, если Вы просто просматриваете эту статью: Это — анти-пример! Это худшее, что Вы когда-либо могли сделать! Это кошмар безопасности! Каждый раз, когда Вы будете писать что-то подобное, будет погибать один невинный котенок! Ктулху сожрет Вашу душу за это!
Вроде бы звучит все не так ужасно, да? Давайте попробуем ввести несколько случайных значений, которые можно ввести на вашем случайном веб-сайте и какие запросы из этого получатся:
Первый запрос выглядит не страшно, а вполне себе мило, правда? Номер 2, кажется, «несколько» повреждает наш синтаксис из-за неоднозначного ‘. Чертов немец! Номер 4 какой-то дурацкий. Кто бы такое написал? Это ведь не имеет смысла…
Но не для БД, обрабатывающей запрос… БД понятия не имеет от куда этот запрос поступил, и что он должен значить. Единственное, что она видит — это два запроса: найти номер пользователя по имени Joe, а затем удалить таблицу users (что сопровождается комментарием ‘), и это будет успешно сделано.
Для вас это не должно быть новостью. Если это так, то, пожалуйста, прочитайте эту статью еще раз, ибо Вы либо новичок в программировании, либо последние 10 лет жили в пещере. Этот пример иллюстрирует основы SQL-инъекций, применяемых во всем мире. для того, чтобы удалить данные, или получить данные, которые не должны быть просто так получены, или войти в систему, не имея на то прав и т.д. А все потому, что БД воспринимает англо-подобный «приговор» слишком буквально.
Впереееееед!
Следующий шаг: XSS атаки. Действуют они аналогично, только применяются к HTML.
Допустим, Вы решили проблемы с БД, получаете данные от пользователя, записываете в базу и выводите их назад на веб-сайт, для доступа пользователям. Это то, что делает типичный форум, система комментариев и т.д. Где-то на вашем сайте есть что-то подобное:
Если ваши пользователи будут хорошими и добрыми, то они будут размещать цитаты старых философов, а сообщения будут иметь примерно следующий вид:
Если пользователи будут умниками, то они, наверное, будут говорить о математике, и сообщения будут такие:
Хм… Опять эти осквернители наших скобок. Ну, с технической точки зрения они могут быть неоднозначными, но браузер простит нам это, правда?
Хорошо, СТОП, что за черт? Какой-то шутник ввел javascript теги на ваш форум? Любой, кто смотрит на это сообщение на вашем сайте, сейчас загружает и выполняет скрипты в контексте вашего сайта, которые могут сделать не весть что. А это не есть хорошо.
Не следует понимать буквально
В вышеупомянутых случаях, мы хотим каким-то образом сообщить нашей БД или браузеру, что это просто текст, ты с ним ничего не делай! Другими словами, мы хотим «удалить» особые значения всех специальных символов и ключевых слов из любой информации, предоставленной пользователем, ибо мы ему не доверяем. Что же делать?
Что? Что говоришь, мальчишка? Ах, ты говоришь, «экранирование»? И ты абсолютно прав, возьми печеньку!
Если мы применим экранирование к пользовательским данным до объединения их с запросом, то проблема решена. Для наших запросов к БД это будет что-то вроде:
Просто одна строка кода, но теперь больше никто не может «взломать» нашу базу данных. Давайте снова посмотрим как будут выглядеть SQL-запросы, в зависимости от ввода пользователя:
Alex
mysql_real_escape_string без разбора помещает косую черту перед всем, у чего может быть какое-то особое значение.
Далее, заменим наш скрипт на форуме:
Мы применяем функцию htmlspecialchars ко всем пользовательским данным, прежде, чем вывести их. Теперь сообщение вредителя выглядит так:
Обратите внимание, что значения, полученные от пользователи, на самом деле не «повреждены». Любой браузер парсит этот как HTML и выведет на экран все в правильной форме.
Что возвращает нас к.
Все вышеупомянутое демонстрирует проблему, характерную для многих систем: текст в тексте должно быть подвергнут экранированию, если предполагается, что он не должен иметь специальных символов. Помещая текстовые значения в SQL, они должны быть экранированы по правилам SQL. Помещая текстовые значения в HTML, они должны быть экранированы по правилам HTML. Помещая текстовые значения в (название технологии), они должны быть экранированы по правилам (название технологии). Вот и все.
Для полноты картины
При этом отправка происходит в два этапа, четко разграничивая запрос и переменные. БД имеет возможность сначала понять структуру запроса, а потом заполнить его значениями.
В реальном мире, все это используется вместе для различных ступеней защиты. Вы должны всегда использовать проверку допустимости (валидацию), чтобы быть уверенным, что пользователь вводит корректные данные. Затем вы можете (но не обязаны) сканировать введенные данные. Если пользователь явно пытается «втюхать» вам какой-то скрипт, вы можете просто удалить его. Затем, вы всегда, всегда должны экранировать пользовательские данные прежде, чем поместить их в SQL-запрос (это же касается и HTML).
Шпаргалка для разработчика: создаём безопасное веб-приложение
Эта статья — своего рода ‘cheat sheet’ для веб-разработчика. Она даёт представление о «программе-минимум» для создания веб-приложения, защищённого от самых распространённых угроз.
Экранирование пользовательского ввода
Что это?
В случае если данные пользовательского ввода, отображаемые в браузере, не предполагают наличия активного контента (HTML-разметки, CSS-стилей, JavaScript), данные пользовательского ввода должны быть закодированы (экранированы) перед использованием (отображением). Экранирование предполагает замену специальных символов (набор специальных символов зависит от контекста — HTML, JavaScript и т.д) для того, чтобы обработанные данные трактовались как тест, а не как активный контент. С точки зрения безопасности это делается главным образом для защиты от XSS.
Что делать?
Следует избегать хранения закодированных данных. Кодирование должно выполняться на стороне клиента, как можно ближе к месту использования данных. Главным образом это связано с тем, что только клиент знает, в каком контексте данные отображаются и от чего зависит необходимый тип кодирования.
Возможные контексты экранирования:
HTML-контекст — необходимо экранирование для HTML.
HTML-атрибут — необходимо экранирование для HTML-атрибута.
JavaScript — необходимо экранирование для JavaScript.
URL — необходимо экранирование для URL.
Кроме того, хранение закодированных данных может привести к двойному экранированию. Многие фреймворки экранируют текст по умолчанию (например ASP.NET Core).
Многие фреймворки предоставляют встроенный набор методов для данных целей.
Примеры
Экранирование HTML
Экранирование HTML-атрибута
Экранирование JavaScript
Экранирование JSON
Экранирование URL
Санитайзинг пользовательского ввода
Что это?
В случае если данные пользовательского ввода, отображаемые в браузере, предполагают наличие активного контента (HTML-разметки, CSS-стилей, JavaScript), необходимо выполнять санитайзинг пользовательского ввода — удаление/экранирование всего неразрешённого (например, в контексте HTML это касается тегов и атрибутов). С точки зрения безопасности это делается главным образом для защиты от XSS.
Что делать?
Предпочтительным подходом в таком случае является whitelisting — явное перечисление того, что разрешено. Конкретная логика и список разрешённых тегов и атрибутов сильно зависят от конкретного приложения. Реализовать санитайзинг безопасным образом в целом довольно сложно, предпочтительно использовать готовые протестированные решения и библиотеки. В контексте ASP.NET таким решением может быть использование Html Agility Pack — HTML-парсера, на основе которого можно создать необходимую логику санитайзинга HTML, удовлетворяющую необходимым требованиям приложения.
Пример
Пользователь может оставлять комментарии, содержащие теги . Пользовательский ввод:
Пользовательский ввод после санитайзинга:
Контроль над произвольным пользовательским вводом
Что это?
В большинстве случаев данные пользовательского ввода должны проходить проверку на соответствие допустимым значениям, бизнес-правилам и т.п. Проверка может осуществляться как на клиентской, так и на серверной стороне. Проверка на клиентской стороне положительно влияет на user experience, позволяя получить более ранний отклик, но сама по себе не является достаточной. Проверка на сервере должна проводиться обязательно, вне зависимости от наличия клиентской проверки. С точки зрения безопасности это делается главным образом для защиты от фишинга.
Что делать?
Валидация пользовательского ввода
Пример
Система принимает сообщение об ошибке как часть URL:
Экранирование символов
Экранирование символов — замена в тексте управляющих символов на соответствующие текстовые подстановки. Один из видов управляющих последовательностей.
Содержание
Определение
Обычно языки программирования, текстовые командные интерфейсы, языки разметок текста (HTML, TeX, wiki-разметка) имеют дело со структурированным текстом, в котором некоторые символы (и их комбинации) используются в качестве управляющих, в том числе управляющих структурой текста. В ситуации, когда необходимо использовать такой символ в качестве «обычного символа языка», применяют экранирование.
Условно экранирование может быть разделено на три типа:
Отсутствие экранирования как причина уязвимости
Экранирование символов привлекает особое внимание, когда структурированный текст генерируется автоматически. Включение в текст произвольных строковых данных предполагает обязательное экранирование в них управляющих символов. В то же время, очень часто реальные строки таких символов не содержат, что позволяет программисту пропускать эту операцию совсем и получать более простую программу, корректно работающую с «любыми разумными» строковыми данными. Однако, такой упрощенный код имеет скрытую уязвимость, потому что стороннее лицо (автор строковых данных) получает несанкционированную возможность влиять на структуру генерируемого текста. Уязвимость становится серьёзной, если созданный текст является чьей-то программой. Традиционно таким проблемам подвержены системы, использующие языки SQL (см. SQL-injection) и HTML (см. Сross Site Scripting).
Экранирование символов
1. Причины возникновения экранирования символов
А что делать, если нам нужно, чтобы кавычки были внутри строкового литерала? Строка, содержащая кавычки — что может быть проще.
Код | Примечания |
---|---|
Этот вариант работать не будет! |
Все дело в том, что по мнению компилятора тут записан совсем другой код:
Код | Примечания |
---|---|
Этот вариант работать не будет! |
После того, как компилятор встретит двойные кавычки в коде, он будет считать их началом строкового литерала. Следующие двойные кавычки — окончанием строкового литерала.
Так как же записать в двойные кавычки внутри литерала?
2. Экранирование символов
Вот как будет выглядеть правильно записанный строковой литерал:
Код | Примечания |
---|---|
Это сработает! |
Более того, если вывести данную строку на экран, кавычки с обратной косой чертой будут правильно обработаны, и на экран будет выведена надпись без обратной косой черты: Фильм «Друзья» номинирован на «Оскар»
Еще важный момент. Кавычки, предваренные обратной косой чертой — это один символ: мы просто пользуемся таким хитрым способом записи, чтобы не мешать компилятору распознавать строковые литералы в коде. Вы можете присвоить кавычки в переменную char :
Код | Примечания |
---|---|
\» — это один символ, а не два | |
так тоже можно: двойная кавычка внутри одинарных кавычек |
3. Часто возникающие ситуации при экранировании символов
Кроме двойных кавычек, есть еще много символов, которые по-особому обрабатываются компилятором. Например, перенос строки.
Как добавить в литерал перенос строки? Для этого тоже есть специальная комбинация:
Код | Вывод на экран |
---|
Код | Описание |
---|---|
\t | Вставить символ табуляции |
\b | Вставить символ возврата на один символ |
\n | Вставить символ новой строки |
\r | Вставить символ возврата каретки |
\f | Вставить символ прогона страницы |
\’ | Вставить одинарную кавычку |
\» | Вставить двойную кавычку |
\\ | Вставить обратный слеш |
С двумя из них вы познакомились, а что значат остальные 6?
Символ табуляции – \t
Данный символ в тексте эквивалентен нажатию на клавиатуре клавиши Tab при наборе текста. Он сдвигает следующий за ним текст с целью его выровнять.
Код | Вывод на экран |
---|
Возврат на один символ назад – \b
Данный символ в тексте эквивалентен нажатию на клавиатуре клавиши Backspace при наборе текста. Он удаляет последний выведенный символ перед ним:
Код | Вывод на экран |
---|
Символ возврата каретки – \r
Этот символ переносит курсор в начало текущей строки, не меняя текста. Следующий выводимый текст будет перетирать существующий.
Код | Вывод на экран |
---|
Символ прогона страницы – \f
Это символ дошел до нас из эпохи первых матричных принтеров. Если подать такой символ на печать, это приводило к тому, что принтер просто прокручивал текущий лист, не печатая текст, пока не начнется новый.
Обратный слэш – \\
Ну а тут вообще все просто. Если мы используем обратную косую черту (обратный слэш) в тексте, чтобы экранировать символы, то как тогда записать в текстовой строке сам символ косой черты?
Код | Вывод на экран |
---|---|
Компилятор будет ругаться на неизвестные экранированные символы. | |
Вот так правильно! |
4. Кодировка Unicode
ASCII (англ. American Standard Code for Information Interchange) — американская стандартная кодировочная таблица для печатных символов и некоторых специальных кодов.
Она состояла из 33 непечатных управляющих символов (влияющих на обработку текста и пробелов) и 95 печатных символов, включая цифры, буквы латинского алфавита в строчном и прописном вариантах и ряд пунктуационных символов.
Рост популярности компьютеров привел к тому, что каждая страна начала выпускать свою кодировку. Обычно за основу брали ASCII и заменяли редко используемые символы на символы национальных алфавитов.
Со временем появилась идея: создать одну кодировку, в которой разместить все символы всех мировых кодировок.
И хотя Unicode сам по себе является стандартом, у него есть несколько форм представления (Unicode transformation format, UTF): UTF-8, UTF-16 и UTF-32, и пр.
В Java используется продвинутая разновидность кодировки Unicode – UTF-16: каждый символ в которой кодировался 16 битами (2 байтами). Она способна вместить до 65,536 символов!
В этой кодировке можно найти почти все символы всех алфавитов мира. Но наизусть ее, естественно, никто не знает: нельзя знать все, но все можно загуглить.