Using character escapes in markup and CSS
Character escapes are a way of writing a character in markup using only ASCII code points. They are useful if you are unable to type in the actual character, or sometimes if you want to clearly show invisible characters.
This article addresses the question: How can I use character escapes in markup and CSS, and when should I use or not use them?
Quick answer
In HTML you can escape the euro sign € in the following ways.
| Format | Name |
|---|---|
| € | hexadecimal numeric character reference |
| € | decimal numeric character reference |
| € | named character reference |
In CSS syntax you would use one of the following.
| Format | Notes |
|---|---|
| \20AC | must be followed by a space if the next character is one of a-f, A-F, 0-9 |
| \0020AC | must be 6 digits long, no space needed (but can be included) |
A trailing space is treated as part of the escape, so use 2 spaces if you actually want to follow the escaped character with a space. If using escapes in CSS identifiers, see the additional rules below.
Because you should use UTF-8 for the character encoding of the page, you won’t normally need to use character escapes. You may however find them useful to represent invisible or ambiguous characters, or characters that would otherwise interact in undesirable ways with the surrounding source code or text.
For more details, see below.
Character escapes in markup
You can use a to represent any Unicode character in HTML, XHTML or XML using only ASCII characters.
Different specifications give different names to these constructs. For example, named character references may be referred to as . We have chosen to use names for this article that are used for HTML5.
and are types of character escape used in markup. For example, the following are different ways of representing the character U+00A0 NO-BREAK SPACE .
(The NO-BREAK SPACE character looks like a space but prevents a line wrap between the characters on either side. In French it is commonly used with punctuation such as colons and exclamation marks, which are preceded by a space but should not appear at the beginning of a line during text wrap.)
—>   A hexadecimal numeric character reference. All numeric character references begin with &# and end with ; . The x indicates that what follows is a hexadecimal number representing the code point value of a Unicode character. The hex number is not case-sensitive.
A named character reference. This is a very different type of escape. Named character references are defined in the markup language definition. This means, for example, that for HTML only a specific range of characters (defined by the HTML specification) can be represented as named character references (and that includes only a small subset of the Unicode range).
Note that the name is case sensitive: in HTML, Á represents the uppercase letter Á , whereas á represents the lowercase á .
Some browsers allow you to omit the semicolon at the end of a numeric character reference, but this is not recommended, since it may lead to interoperability problems. Using the semicolon also avoids the potential problem of the end of the escape becoming undetectable when the escape is embedded in text.
Code point numbers
One point worth special note is that values of numeric character references (such as € or € for the euro sign € ) are interpreted as Unicode characters – no matter what encoding you use for your document.
For example, the code point number of the euro sign in Windows code page 1252 is 80. It is a common error for people working on content in that encoding to represent the euro sign using € . This HTML should actually produce a control character, since the escape would be expanded as the character at position 80 in the Unicode repertoire. (In fact, browsers tend to silently correct that particular error. See the test pages.)
CSS escapes
CSS represents escaped characters in a different way. Escapes start with a backslash followed by the hexadecimal number that represents the character’s hexadecimal Unicode code point value.
If there is a following character that is not in the range A–F, a–f or 0–9, that is all you need. The following example represents the word émotion .
There is no actual need to escape the é in these examples. It’s just for the purposes of illustration. The sequence of characters ‘émotion’ would also work fine. (See, however, the next subsection for issues related to using digits at the start of an identifier.)
If, on the other hand, the next character is one that can be used in hexadecimal numbers, it won’t be clear where the end of the number is. In these cases there are two options. The first is to use a space after the escape. This space is part of the escape syntax, and does not remain after the character escape is parsed. The following example shows how you could represent the word édition so that the d is not assumed to be part of the escape.
Alternatively, you can use a 6-digit hexadecimal number, with or without a space. Here is an alternative way of writing édition .
Because any white-space following the hexadecimal number is swallowed up as part of the escape, if you actually want a space to appear after the escaped character you will need to add two spaces (after a hexadecimal number of any length).
Using escapes with CSS identifiers
Identifiers in CSS, such as class names in CSS selectors, can begin with — _ a-z or A-Z or a non-ASCII character, but cannot begin with any other ASCII character. However, escaped characters of any type can appear in any location.
This means that you can’t start an identifier with an ASCII digit 0-9 (although you can use digits after the first character). So if the class name you want to refer to happens to begin with a digit you will need to escape it.
For example, to select an element in HTML with the class name "123", you would write the following.
Note the use of the space to separate the escaped part of the class name from the remainder, so that it’s clear where the end of the escape is. If you had written \3123 this would represent ㄣ [ U+3123 BOPOMOFO LETTER EN ]. (You could also have written \00003123 , since the CSS escape ends after the 6th character past the backslash.)
There is no need to also escape the ’23’ part of the identifier, since digits are allowed after the first position.
Sequences and backslashes
The following all show valid ways of escaping a sequence of characters, such as those in the sequence of Egyptian hieroglyphs , meaning ‘voice’.
\13322 \13171 \13001
\013322 \013171 \013001
The backslash can also be used in CSS before a syntax character to prevent it being read as part of the code. For more information about CSS escapes, see the CSS Syntax Module.
When not to use escapes
It is almost always preferable to use an encoding that allows you to represent characters in their normal form, rather than using named character references or numeric character references.
Using escapes can make it difficult to read and maintain source code, and can also significantly increase file size.
Many English-speaking developers have the expectation that other languages only make occasional use of non-ASCII characters, but this is wrong.
Take for example the following passage in Czech.
Jako efektivnější se nám jeví pořádání tzv. Road Show prostřednictvím našich autorizovaných dealerů v Čechách a na Moravě, které proběhnou v průběhu září a října.
If you were to require numeric character references for all non-ASCII characters, the passage would become unreadable, difficult to maintain and much longer. It would, of course, be much worse for a language that didn’t use Latin characters at all.
Jako efektivnĕjší se nám jeví pořádání tzv. Road Show prostřednictvím našich autorizovaných dealerů v Čechách a na Moravě, které proběhnou v průběhu září a října.
As we said before, use characters rather than escapes for ordinary text.
Use in XHTML. Using named character references in a document that is parsed as XML may become problematic if the entities are defined externally to your document and the tools that process the XML do not read the external files. In such cases the entity references will not be replaced by characters. For this reason, if you need to use escapes, it may be safer to use numeric character references, or define the character entities you need inside the document.
If you use HTML-defined named character references (such as á ) to represent characters in XHTML, you should take care any time your content is processed using XML parsers or other tools.
When escapes can be useful
Syntax characters. There are three characters that should always appear in content as escapes, so that they do not interact with the syntax of the markup. These are part of the language for all documents based on HTML and for XML.
You may also want to represent the double-quote («) as " and the single quote (‘) as ' . This would certainly be the case in attribute text when you need to use the same type of quotes as those that surround the attribute value.
Invisible or ambiguous characters. A particularly useful role for escapes is to represent characters that are invisible or ambiguous in presentation.
One example would be Unicode character U+200F RIGHT-TO-LEFT MARK . This character can be used to clarify directionality in bidirectional text (eg. when using the Arabic or Hebrew scripts). It has no graphic form, however, so it is difficult to see where these characters are in the text, and if they are lost or forgotten they could create unexpected results during later editing. Using ‏ (or its numeric character reference equivalent ‏ ) instead makes it very easy to spot these characters.
An example of an ambiguous character is U+00A0 NO-BREAK SPACE . This type of space prevents line breaking, but it looks just like any other space when used as a character. Using (or   ) makes it quite clear where such spaces appear in the text.
Input problems. If your editing tool does not allow you to easily enter needed characters you may also resort to using escapes. Note that this is not a long-term solution, nor one that works well if you have to enter a lot of such characters – it takes longer and makes maintenance more difficult. Ideally you would choose an editing tool that allowed you to enter these characters as characters. Alternatively, if you only need the occasional character, use a character map tool or character picker.
Encoding gaps. Escapes can be useful to represent characters not supported by the encoding you choose for the document, for example, to represent Chinese characters in a document encoded as Windows-1252. You should ask yourself first, however, why you have not changed the encoding of the document to UTF-8, which covers all the characters you need.
Using escapes in style attributes
It is usually a good idea to put style information in an external style sheet or a style element in the head of an HTML file. Occasionally, or perhaps on a temporary basis, you may use a style attribute on a particular element, instead. Even more rarely, you may want to represent one or more characters in the style attribute using character escapes.
A style attribute in HTML can represent characters using numeric or named character references or CSS escapes. On the other hand, the style element in HTML can contain neither numeric nor named character references, and the same applies to an external style sheet.
Because there is a tendency to want to move styles declared in attributes to the style element or an external style sheet (for example, this might be done automatically using an application or script), it is safest to use only CSS escapes.
For example, it is better to use
By the way
Changing to UTF-8 means re-saving your file. Using the character encoding UTF-8 for your page means that you can avoid the need for most escapes and just work with characters. Note, however, that to change the encoding of your document, it is not enough to just change the encoding declaration at the top of the page or on the server. You need to re-save your document in that encoding. For help understanding how to do that with your application read Choosing & applying a character encoding .
Hex vs. decimal. Typically when the Unicode Standard refers to or lists characters it does so using a hexadecimal value. For instance, the code point for the letter á may be referred to as U+00E1 . Given the prevalence of this convention, it is often useful, though not required, to use hexadecimal numeric values in escapes rather than decimal values. You do not need to use leading zeros in escapes, ie. á could be represented as á .
Supplementary characters. Supplementary characters are those Unicode characters beyond the Basic Multilingual Plane (BMP). In UTF-16 a supplementary character is encoded using two 16-bit from the BMP. Because of this, or because of experience with older version s of JavaScript syntax, some people think that supplementary characters need to be represented using two escapes, but this is incorrect – you must use the single, code point value for that character. For example, use 𣎴 rather than �� .
Шпаргалка для разработчика: создаём безопасное веб-приложение
Эта статья — своего рода ‘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, удовлетворяющую необходимым требованиям приложения.
Пример
Пользователь может оставлять комментарии, содержащие теги <strong>. Пользовательский ввод:
Пользовательский ввод после санитайзинга:
Контроль над произвольным пользовательским вводом
Что это?
В большинстве случаев данные пользовательского ввода должны проходить проверку на соответствие допустимым значениям, бизнес-правилам и т.п. Проверка может осуществляться как на клиентской, так и на серверной стороне. Проверка на клиентской стороне положительно влияет на user experience, позволяя получить более ранний отклик, но сама по себе не является достаточной. Проверка на сервере должна проводиться обязательно, вне зависимости от наличия клиентской проверки. С точки зрения безопасности это делается главным образом для защиты от фишинга.
Что делать?
Валидация пользовательского ввода
Пример
Система принимает сообщение об ошибке как часть URL:
Данное сообщение затем отображается в HTML-разметке:
Примечание: В данном случае система также уязвима к XSS-атаке (защита достигается путём экранирования данных — см. следующий пункт).
Поскольку в данном случае система принимает абсолютно любое сообщение, система открыта для фишинга. Например:
Если набор ошибок известен заранее, более безопасным методом передачи типа ошибки будет использование перечисления:
Программная логика затем производит маппинг кода ошибки и заранее известного текста ошибки, который уже и отображается на HTML-странице.
Явное акцентирование на данных, не прошедших валидацию
В случае отсутствия контроля над данными, когда необходимо принимать произвольный пользовательский ввод, необходимо акцентировать внимание конечного пользователя на данном факте.
Пример
В контексте предыдущего примера, в случае если источником текста ошибки является внешняя система (например, в случае интеграции) можно добавить в пользовательский интерфейс сообщение, поясняющее конечному пользователю, что источником данного сообщения является иная система и что сообщение отображается «как есть».
Контроль за легитимностью запросов на изменение данных
Что это?
Позволяет удостовериться, что запрос к системе на изменение данных действительно инициирован пользователем. Основной целью данного механизма контроля является защита от таких атак как CSRF и фишинг.
Что делать?
Antiforgery токены
Каждый запрос, потенциально меняющий состояние данных на сервере, должен включать уникальный токен, привязанный к сессии пользователя. Значение токена должно быть либо случайным, либо получено с использованием шифрования.
Пример
Потенциально уязвимая форма:
Форма с токеном, включённым в виде скрытого поля:
На каждом запросе веб-приложение должно валидировать токен.
Использование атрибута SameSite для куки пользовательской сессии
Если приложение использует куки для хранения пользовательской сессии, крайне желательно использование атрибута SameSite со значением Strict или Lax. Это предотвратит отправку авторизованных запросов, источником которых не является само веб-приложение.
Пример
Подтверждение действия от пользователя
Механизм подтверждения действия от пользователя с помощью дополнительного диалога либо 2FA крайне затруднит атаку. Так как данный подход требует дополнительных действий со стороны пользователя, его имеет смысл использовать для наиболее важных действий.
GET-запросы не должны изменять данные на сервере
HTTP-запросы GET должны быть идемпотентными; в данном контексте — не вносить изменения в данные на сервере. Это связано главным образом с тем, что GET-запрос сделать намного проще, чем, например, POST, и намного сложнее сделать безопасным, если запрос меняет данные. Даже использование antiforgery токенов не гарантирует безопасности, т. к. GET-запросы не имеют тела, все их параметры являются частью URL, и относительно велика вероятность утечки токена через историю браузера, логи и т.д.
Валидация источника запроса
Проверка HTTP-заголовков Origin и/или Referer. Данный механизм защиты может рассматриваться в качестве дополнительного к вышеперечисленным методам, но не в качестве единственного, т. к. значение заголовков зачастую может быть пустым (по целому ряду причин — из-за VPN, firewall и т. д.) и также может быть потенциально недостоверным.
Контроль над фреймингом
Что это?
Контроль над фреймингом предполагает реализацию явной политики относительно того, может ли веб-приложение (сайт) отображаться во фрейме (HTML-тег <iframe>), какие части приложения могут отображаться во фрейме и при каких условиях. Основной целью такой политики является защита от clickjacking.
Что делать?
Использование HTTP-заголовка Content-Security-Policy
Данный заголовок позволяет с помощью директивы frame-src указать, в каких случаях ресурс может быть отображён в iframe.
Примеры
Фрейминг разрешён только для страниц самого веб-приложения:
Использование HTTP-заголовка X-Frame-Options
Данный заголовок не является стандартным. Тем не менее, он полезен для браузеров, не поддерживающих CSP (например, Internet Explorer) . Данный заголовок позволяет указать, в каких случаях ресурс может быть отображён в iframe.
Пример
Фрейминг разрешён только для страниц самого веб-приложения:
Использование специализированных HTTP-заголовков безопасности
Что это?
Различные HTTP-заголовки, позволяющие настраивать относящиеся к безопасности аспекты коммуникации через протокол HTTP.
Что делать?
Content-Security-Policy
Позволяет контролировать, какой контент и откуда может использовать веб-приложение (скрипты, стили, шрифты, изображения), в каких случаях приложение может отображаться в iframe, политику использования HTTPS и другие аспекты, связанные с безопасностью веб-приложения. Чем строже политика, заданная в CSP-директивах, тем лучше с точки зрения безопасности. Различные аспекты политики предоставляют защиту от различных видов атак. Например, директива script-src, предоставляющая контроль над разрешёнными источниками для JavaScript, является отличным средством защиты от XSS. Директива frame-src является хорошим подспорьем в борьбе с clickjaсking.
Пример
Разрешены скрипты, стили, шрифты и встроенный контент из файлов, предоставляемых самим сайтом; встроенные скрипты и стили запрещены.
Отправка форм — только с самого сайта.
Все запросы из страниц выполняются только по HTTPS.
Permissions-Policy (ex-Feature-Policy)
Данный HTTP-заголовок позволяет явным образом указать, какие клиентские (JavaScript) API может использовать приложение. Это может быть особенно полезно для ограничения использования камеры, микрофона и т. д.
Пример
Политика ниже запрещает использование микрофона, камеры, payment API. Геолокация разрешена только для самого приложения:
Strict-Transport-Security
Данный заголовок помогает реализовать политику использования защищённого HTTPS-соединения и в целом может быть полезен в контексте борьбы с утечкой данных, а также с атаками типа Man in the middle (подробнее см. в разделе «HTTPS»).
Referrer-policy
Данный заголовок помогает предотвратить утечку данных из URL в случае перехода из приложения по внешним ссылкам (подробнее см. в разделе «Меры по предотвращению утечки данных»).
X-Frame-Options
Данный заголовок не является стандартным. Тем не менее, он может быть полезен для браузеров, не поддерживающих CSP. Данный заголовок позволяет указать, в каких случаях ресурс может быть отображен в iframe (подробнее — в разделе «Контроль над фреймингом»).
X-XSS-Protection
Этот подход менее гибок и используется реже, чем Content-Security-Policy. Тем не менее, он полезен для браузеров, не поддерживающих CSP (например, Internet Explorer). Данный заголовок разрешает браузеру использовать встроенный механизм борьбы с XSS (если браузер имеет таковой) в режиме блокирования страницы либо удаления потенциально опасного кода.
Пример
Конфигурация ниже блокирует страницы, содержащие подозрительный (с точки зрения возможной XSS-атаки) код:
X-Content-Type-Options
Данный заголовок может быть полезен в контексте борьбы с различными атаками, связанными с выполнением содержимого файлов приложения. Использование данного заголовка полезно в том случае, если приложение предоставляет возможность хранения/работы с файлами (подробнее в разделе «Правильная организация хранения файлов и доступа к ним»).
HTTP-заголовки не должны быть основным и единственным средством защиты
Насколько перечисленные выше HTTP-заголовки эффективны — целиком и полностью зависит от уровня поддержки и качества реализации в конкретном браузере. Таким образом, HTTP-заголовки не должны рассматриваться как единственная мера защиты для каждого конкретного вектора атаки, и механизмы защиты на стороне сервера тоже необходимы.
Управление пользовательской сессией
Что это?
Механизм пользовательской сессии позволяет приложению распознавать запросы от уже аутентифицированного пользователя, не вынуждая его вводить логин и пароль для отправки каждого запроса. В общем случае это осуществляется путём использования некоего уникального идентификатора пользователя, который присваивается после успешной процедуры логина и затем отправляется с каждым запросом. С точки зрения безопасности особенно важно, чтобы выбранный механизм управления пользовательской сессией не был уязвим для таких атак, как session hijacking и session fixation.
Что делать?
Значение идентификатора сессии должно быть случайным
Значение должно быть случайным, сложным для предугадывания и не поддаваться простому перечислению.
Ротация идентификатора сессии
При каждом новом входе в систему пользователю должен присваиваться новый идентификатор сессии. Предыдущий идентификатор должен быть инвалидирован.
Пример
Чтобы предотвратить переиспользование идентификатора сессии в ASP.NET, куки с идентификатором необходимо инвалидировать в процессе разлогирования пользователя:
Защита куки сессии
Куки сессии должны использовать следующие атрибуты:
HttpOnly
Использование данного атрибута поможет предотвратить возможность получения значения идентификатора сессии с помощью клиентского скрипта.
Secure
Данный флаг предотвратит передачу идентификатора сессии по незащищённому HTTP-протоколу.
SameSite
Значения Strict и Lax данного атрибута предотвращают отправку куки с запросами, источниками которых не является сайт, создавший куки. Это помогает предотвратить CSRF-атаки.
Также для таких куки не должно быть установлено свойство Domain
Установка данного свойства открывает доступ к куки для поддоменов, что нежелательно, если не все поддомены находятся под контролем автора приложения.
Пример
Конфигурация для ASP.NET в файле web.config:
Избегать передачи незакодированного идентификатора сессии в URL
Некоторые приложения могут передавать идентификатор сессии как часть URL. Если идентификатор не закодирован, это может привести к утечке идентификатора, например через лог запросов на сервере, историю браузера. Использование куки для хранения идентификатора сессии является предпочтительным.
Использование HTTPS
Что это?
Приложение, не использующее протокол HTTPS, по умолчанию является уязвимым: данные передаются по сети в незашифрованном виде, что делает приложение подверженным таким атакам, как Man in the middle или content sniffing. Возможна утечка персональных данных, паролей и т. д. Любое приложение, имеющее дело с персональными данными и/или паролями, должно использовать протокол HTTPS.
Что делать?
Перенаправление всех запросов с HTTP на HTTPS либо отказ в обслуживании запросов HTTP
Веб-приложение должно осуществлять перенаправление всех запросов с HTTP на HTTPS. Данный подход работает в случае, если клиентом является браузер. В остальных случаях (например, мобильное или десктопное приложение) вместо перенаправления необходимо отвергать запрос с ошибкой.
HTTP-заголовок Strict-Transport-Security
Позволяет обеспечить доступ к ресурсу исключительно по протоколу HTTPS в случае, если клиентом ресурса является браузер. После ответа на первый запрос, содержащий данный заголовок, все последующие запросы браузер будет выполнять с использованием защищённого протокола HTTPS.
Пример
Использование HSTS с директивой preload
Браузер не имеет возможности заранее, до первого запроса, определить, требует ли ресурс доступа только по HTTPS. Например, пользователь запрашивает в браузере ресурс http://mysite.com. Данный запрос выполняется по протоколу HTTP. Если в ответе на этот запрос содержится заголовок Strict-Transport-Security, все последующие запросы будут выполняться по протоколу HTTPS. Очевидно, что первый запрос всё ещё может быть уязвим. Предотвратить этот риск помогает использование директивы preload и добавление ресурса в так называемый preload list (подробнее см. https://hstspreload.org).
Пример
Запрет HTTP-запросов к API — только HTTPS
В случае если клиентом API является не только браузер, существует вероятность, что перенаправление с HTTP на HTTPS (например, с помощью HSTS) не будет корректно обработано клиентом. В целом для API предпочтительно отвергать запросы по HTTP.
Защищённые куки
Что это?
Куки могут содержать важную с точки зрения безопасности информацию, например идентификатор пользовательской сессии. Передача таких куки по незащищённому HTTP-соединению и возможность доступа из клиентского кода могут стать источником таких атак, как session hijacking.
Что делать?
Флаг HttpOnly
Предотвращает возможность доступа к куки с помощью клиентского скрипта. Флаг должен быть установлен для всех куки, доступ к которым из клиентского скрипта не предполагается.
Флаг Secure
Куки с данным флагом будут переданы с запросом только в случае, если запрос выполняется по протоколу HTTPS.
Атрибут SameSite
Данный атрибут может принимать несколько значений. Значения Lax или Strict предотвратят отправку куки с запросами, выполняемыми не из приложения, что может сильно затруднить атаку типа CSRF.
Пример
HTTP-заголовок, устанавливающий куки “SessionId”:
Пример конфигурации в web.config для ASP.NET:
Правильная организация хранения файлов и доступа к ним
Что это?
В случае если приложение предоставляет пользователям возможность загрузки файлов и их хранения, данная функциональность должна быть реализована с учётом необходимости защиты от возможных атак и нецелевого использования.
Что делать?
Валидация и санитайзинг имён файлов
Имена файлов как минимум не должны иметь расширений, приводящих к выполнению кода на стороне сервера или на клиенте (например, .bat, .cmd, .vbs).
Ограничение типов файлов, разрешённых для загрузки
Типы файлов должны быть ограничены с использованием подхода whitelisting (явное задание списка разрешённых типов файлов).
Использование HTTP-заголовка X-Content-Type-Options
Использование данного заголовка помогает предотвратить выполнение содержимого файлов в браузере.
Пример
Хранение файлов в домене, отличном от домена приложения
Файлы должны храниться в домене, отличном от домена приложения (не в том же домене и не в его поддомене), с как можно более строгими политиками CSP и Permissions Policy, по возможности полностью запрещающими выполнение скриптов и использование различных клиентских API.
Пример
Данные, с утечкой которых надо бороться
Что это?
К таким данным относятся пользовательские данные и технические данные о работе приложения (сообщения об ошибках, стеки ошибок и т. п.).
Что делать?
Контроль над сообщениями об ошибках
Данная техника предполагает строгое ограничение информации об ошибках, доступной пользователям системы. Содержимое сообщения об ошибках должно быть строго определено. Сообщения об ошибках должны быть полезны для конечного пользователя, но не должны содержать излишних технических подробностей о системе либо других важных с точки зрения безопасности, но не важных для конечного пользователя данных (идентификаторов, информации о структуре хранилища данных, стеков ошибок и т. д.).
Пример
Для ASP.NET-приложения обработчик Application_Error в Global.asax файле может быть использован для перехвата необработанных ошибок:
Для ASP.NET Core обработчик исключений может быть зарегистрирован в методе Configure класса Startup:
URL не должен содержать конфиденциальные данные
В целом URL не должны содержать потенциально конфиденциальные данные, т. к. URL могут быть сохранены как часть внешней инфраструктуры логирования (история браузера, логи серверов; такие HTTP-заголовки, как Referer, и т. д.). В случае если передача таких данных через URL необходима, данные должны быть зашифрованы.
Использование HTTP-заголовка Referrer-Policy
Данный заголовок позволяет ограничить информацию, передаваемую в заголовке Referer. Может быть использован для исключения передачи параметров строки запроса либо URL целиком.
Пример
Исключение из ответа на HTTP-запрос HTTP-заголовков, раскрывающих детали серверной реализации приложения
Некоторые технологии и платформы по умолчанию добавляют в ответы на HTTP-запросы определённое количество различных HTTP-заголовков. Некоторые из них могут раскрывать такие технические подробности, как версия сервера, платформы и т. д. Данные заголовки, если они не несут функциональности для конечного пользователя, должны быть убраны из ответа на запрос.
Пример
Некоторые заголовки для IIS + ASP.NET, по умолчанию включённые в запрос:
Заголовок “Server” может быть удалён с помощью URL Rewrite rule:
Заголовок “XPowered-By” может быть удалён через конфигурацию IIS (“HTTP response headers item”).
Заголовок “X-AspNetMvc-Version» может быть удалён при использовании следующего кода в событии Application_Start:
Заголовок “X-AspNet-Version“ может быть удалён при помощи конфигурации в файле web.config:
Контроль за перенаправлением на внешние ресурсы
Что это?
Если приложение может перенаправлять пользователя на внешние ресурсы и такие перенаправления не валидируются, это может способствовать фишинговым атакам, особенно в случае, если URL внешнего ресурса является частью ввода (например, параметр строки запроса URL).
Что делать?
Валидация адресов внешних ресурсов
Адрес перенаправления всегда должен валидироваться. Если по каким-либо причинам валидация невозможна, необходимо предупреждать пользователя о том, что он будет перенаправлен на внешний ресурс. Это можно сделать с помощью промежуточной страницы или диалогового окна, требующего действия от пользователя.
Безопасное использование пользовательского ввода в параметрах запросов к БД
Что это?
Если какой-либо запрос к БД принимает один или более параметров, параметры должны быть должным образом закодированы (в контексте SQL) перед использованием. В противном случае система может быть уязвима к SQL-инъекциям. Это особенно актуально для SQL-запросов, использующих данные пользовательского ввода (поля форм, часть строки запроса URL и т. д.) в качестве параметров запроса.
Что делать?
Параметризация запросов
Большинство платформ для работы с БД предоставляют такие возможности. Например, Microsoft Entity Framework по умолчанию не является уязвимым к такому типу атаки, т. к. весь пользовательский ввод преобразуется в SQL-параметры. Но в то же время фреймворк даёт возможность выполнения «сырых» запросов напрямую, и в таком случае обязанностью разработчика является передача ввода в качестве параметров запроса.
Пример
Запрос, уязвимый к SQL-инъекции:
Политика предоставления наименьших необходимых разрешений
Политика предоставления наименьших необходимых разрешений также является полезной мерой защиты с точки зрения минимизации вреда в случае SQL-инъекции. Например, использование различных аккаунтов на чтение и доступ может предотвратить возможность изменения данных даже в случае успешной SQL-инъекции.
Заключение
Конечно, это руководство не исчерпывающее. Бывают и более экзотические виды атак, да и любой сайт можно взломать, если постараться. Однако реализация мер, приведённых в этой статье, обеспечит защиту от наиболее распространённых угроз и достойный уровень безопасности приложения в целом.
Онлайн экранирование кода для вставки в HTML
Удобный функциональный онлайн генератор для экранирования кода работает на лету без перезагрузки страницы. Просто вставьте ваш код и нажмите кнопку Копировать.

Данный инструмент позволяет на лету без перезагрузки страницы экранировать код для дальнейшей вставки его в HTML, заменяя в коде символы < > & » ` на соответствующие им коды Unicode.
Такое экранирование нужно для того, чтобы без проблем встраивать демонстрационные фрагменты кода в HTML-документы и страницы сайта.
Вставьте код:
Результат:
Ниже приведены символы и Unicode значения для них, которые заменяет данный генератор:
Описание настроек
Данное экранирование не зависит от языка программирования и нужно исключительно для вставки кода в HTML, потому что если не заменить упомянутые выше символы на unicode, браузер будет воспринимать их как часть HTML и проинпретирует (обработает) код как часть html.
Обернуть код тегами pre code
Данная настройка обернёт полученный результат тегами <pre><code></code></pre> .
Добавить класс языка в тег code
Эта настройка добавит в тег code класс с идентификатором языка. Пример class=»language-html» . Это нужно если блок pre обрабатывается скриптами осуществляющими подсветку синтаксиса кода.
Работает только если включена настройка "Добавить класс языка в тег code".
Языки
Выбор языка — эта настройка укажет в class=»language-. » выбранный язык.
Работает только если включена настройка "Обернуть код тегами pre code".
Какие символы нужно экранировать в HTML?
Они такие же, как XML, возможно, плюс пробел ( )?
Я нашел несколько огромных списков escape-символов HTML, но я не думаю, что они должен сбежать. Я хочу знать что потребности чтобы сбежать.
задан 11 сен ’11, 20:09
4 ответы
Если вы вставляете текстовое содержимое в свой документ в место, где ожидается текстовое содержимое 1 , обычно нужно экранировать только те символы, что и в XML.. Внутри элемента это просто включает экранирующий амперсанд сущности & и разделитель элементов знаков «меньше» и «больше» < > :
Внутри значений атрибутов вы также должны экранировать используемый символ кавычки:
В некоторых случаях может быть безопасно пропустить экранирование некоторых из этих символов, но я советую вам избегать всех пяти во всех случаях, чтобы снизить вероятность ошибки.
Если кодировка вашего документа не поддерживает все символы, которые вы используете, например, если вы пытаетесь использовать смайлики в документе с кодировкой ASCII, вам также необходимо их избежать. Большинство документов в наши дни кодируются с использованием полностью поддерживающей Unicode кодировки UTF-8, где в этом нет необходимости.
В общем, вам не следует избегать пробелов как . это не нормальное пространство, это неразрывный пробел. Вы можете использовать их вместо обычных пробелов, чтобы предотвратить вставку разрыва строки между двумя словами или для вставки лишнего пробела без его автоматического сворачивания, но обычно это редкий случай. Не делайте этого, если этого не требует конструктивное ограничение.
1 Под «местом, где ожидается текстовое содержимое» я имею в виду внутри элемента или значения атрибута в кавычках, где применяются обычные правила синтаксического анализа. Например: <p>HERE</p> or <p title=»HERE»>. </p> . Что я написал выше не применяется к контенту, имеющему особые правила синтаксического анализа или значение, например внутри тега скрипта или стиля, или в качестве имени элемента или атрибута. Например: <NOT-HERE>. </NOT-HERE> , <script>NOT-HERE</script> , <style>NOT-HERE</style> или <p NOT-HERE=». «>. </p> .
В этих контекстах правила усложняются, и гораздо проще внести уязвимость в систему безопасности. Я настоятельно не рекомендую вам когда-либо вставлять динамический контент в любое из этих мест. Я видел, как группы компетентных разработчиков, осведомленных о безопасности, вводили уязвимости, предполагая, что они правильно закодировали эти значения, но упустили крайний случай. Обычно есть более безопасная альтернатива, например, поместить динамическое значение в атрибут и затем обработать его с помощью JavaScript.
Если необходимо, прочтите Правила предотвращения XSS проекта Open Web Application Security чтобы понять некоторые проблемы, о которых вам нужно помнить.
Некоторые значения атрибутов HTML также могут иметь особое значение (JS / CSS). Так что это также не относится к ним, например: <p onclick=»NOT-HERE»>. </p> и <p style=»NOT-HERE»>. </p> . — гикли
Это зависит от контекста. Некоторые возможные контексты в HTML:
- тело документа
- внутри общих атрибутов
- внутри тегов скрипта
- внутри тегов стиля
- еще несколько!
ответ дан 23 мар ’20, в 10:03
В основном есть три главных героя которые всегда должны быть экранированы в ваших файлах HTML и XML, чтобы они не взаимодействовали с остальной разметкой, поэтому, как вы, вероятно, ожидаете, две из них будут оболочками синтаксиса, это <>, они перечислены ниже :
Также мы можем использовать двойные кавычки («) как» и одинарные кавычки (‘) как & apos
Избегайте размещения динамического контента в <script> и <style> На них эти правила не распространяются. Например, если вам нужно включить JSON в a, замените <на \ x3c, символ U + 2028 на \ u2028 и U + 2029 на \ u2029 после сериализации JSON.)
Поэтому вам нужно экранировать <или &, когда за ним следует что-нибудь, что может начинать ссылку на символ. Также Правило для амперсандов — единственное такое правило для атрибутов в кавычках, так как соответствующие кавычки — единственное, что завершает их. Но если вы не хотите заканчивать здесь значение атрибута, избегайте кавычек.
Переход на UTF-8 означает повторное сохранение файла:
Использование кодировки символов UTF-8 для вашей страницы означает, что вы можете избежать большинства экранирований и просто работать с символами. Однако обратите внимание, что для изменения кодировки документа недостаточно просто изменить объявление кодировки вверху страницы или на сервере. Вам необходимо повторно сохранить документ в этой кодировке. Чтобы понять, как это сделать с вашим приложением, прочтите «Настройка кодировки в приложениях для веб-разработки».
Невидимые или неоднозначные символы:
Особенно полезная роль для экранирования состоит в том, чтобы представлять символы, которые невидимы или неоднозначны в представлении.
Одним из примеров может быть символ Юникода U + 200F RIGHT-TO-LEFT MARK. Этот символ может использоваться для уточнения направленности двунаправленного текста (например, при использовании арабского алфавита или иврита). Однако он не имеет графической формы, поэтому трудно увидеть, где находятся эти символы в тексте, и если они потеряны или забыты, они могут привести к неожиданным результатам при последующем редактировании. Использование (или его эквивалента в виде ссылки на числовой символ) позволяет очень легко обнаружить эти символы.
Примером неоднозначного символа является U + 00A0 NO-BREAK SPACE. Этот тип пробела предотвращает разрыв строки, но при использовании в качестве символа он выглядит так же, как и любой другой пробел. Использование дает понять, где в тексте появляются такие пробелы.

Точный ответ зависит от контекста. Как правило, эти символы не должны присутствовать (HTML 5.2 §3.2.4.2.5):
Текстовые узлы и значения атрибутов должны состоять из символов Юникода, не должны содержать символов U + 0000, не должны содержать постоянно неопределенных символов Юникода (не символов) и не должны содержать управляющих символов, кроме символов пробела. Эта спецификация включает дополнительные ограничения на точное значение текстовых узлов и значений атрибутов в зависимости от их точного контекста.
Для элементов в HTML ограничения модели текстового содержимого также зависят от типа элемента. Например, «<» внутри элемента textarea не нужно экранировать в HTML, потому что textarea является экранируемым необработанным текстовым элементом.
Эти ограничения разбросаны по спецификации. Например, значения атрибутов (§8.1.2.3) не должен содержать неоднозначный амперсанд и быть либо (I) пустой, (II) в одинарных кавычках (и, следовательно, не должен содержать символ U + 0027 APOSTROPHE ‘ ), (III) в двойных кавычках (не должно содержать символа U + 0022 QUOTATION MARK » ), или (IV) без кавычек — со следующими ограничениями:
. не должен содержать никаких буквальных пробелов, любых символов U + 0022 QUOTATION MARK («), U + 0027 APOSTROPHE (‘), U + 003D EQUALS SIGN символов (=), U + 003C LESS-THAN SIGN символов ( <), Символы U + 003E GREATER-THAN SIGN (>) или символы U + 0060 GRAVE ACCENT (`), и не должны быть пустой строкой.