Для чего зарезервирована точка с запятой в URL-адресах?

Спецификация RFC 3986 URI: Generic Syntax перечисляет точку с запятой как зарезервированный (подразделительный) символ:

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Какова зарезервированная цель ; точки с запятой в URI? Если уж на то пошло, какова цель других субразделителей (мне известны только цели &, + и =)?


person Nicole    schedule 29.01.2010    source источник


Ответы (6)


В конце раздела 3.3 есть объяснение.

Помимо точечных сегментов в иерархических путях, сегмент пути считается непрозрачным в соответствии с общим синтаксисом. Приложения, производящие URI, часто используют зарезервированные символы, разрешенные в сегменте, для разграничения подкомпонентов, специфичных для схемы или обработчика разыменования. Например, зарезервированные символы точки с запятой (;) и равенства (=) часто используются для разделения параметров и значений параметров, применимых к этому сегменту. Зарезервированный символ запятой (,) часто используется для аналогичных целей. Например, один производитель URI может использовать такой сегмент, как name;v=1.1, чтобы указать ссылку на версию 1.1 имени, тогда как другой может использовать такой сегмент, как name,1.1, чтобы указать то же самое. Типы параметров могут быть определены семантикой конкретной схемы, но в большинстве случаев синтаксис параметра зависит от реализации алгоритма разыменования URI.

Другими словами, он зарезервирован, чтобы люди, которым нужен список чего-либо с разделителями в URL-адресе, могли безопасно использовать ; в качестве разделителя, даже если части содержат ;, при условии, что содержимое закодировано в процентах. Другими словами, вы можете сделать это:

foo;bar;baz%3bqux

и интерпретировать его как три части: foo, bar, baz;qux. Если бы точка с запятой не была зарезервированным символом, ; и %3b были бы эквивалентны, поэтому URI неправильно интерпретировался бы как четыре части: foo, bar, baz, qux.

person Mark Byers    schedule 29.01.2010
comment
Словом, сдержанно, но ни за что конкретно. Мы используем его для кодирования некоторой информации в запросах RESTful. - person S.Lott; 29.01.2010
comment
Спасибо за пример, это действительно помогает. - person Nicole; 29.01.2010
comment
Может ли кто-нибудь поделиться примером этого, используемого в реальных веб-сервисах? - person Winny; 11.06.2014
comment
Какое-то особое значение для ; в URL-адресах HTTP? - person Jaime Hablutzel; 25.09.2015

Намерение становится более ясным, если вы вернетесь к старым версиям спецификации:

  path_segments = segment *( "/" segment )
  segment       = *pchar *( ";" param ) 

Каждый сегмент пути может включать в себя последовательность параметров, обозначенных точкой с запятой ";" персонаж.

Я считаю, что он берет свое начало в URI FTP.

person McDowell    schedule 29.01.2010

Раздел 3.3 описывает это — это непрозрачный разделитель, который может использовать приложение, создающее URI. если удобно:

Помимо точечных сегментов в иерархических путях, сегмент пути считается непрозрачным в соответствии с общим синтаксисом. Приложения, производящие URI, часто используют зарезервированные символы, разрешенные в сегменте, для разграничения подкомпонентов, специфичных для схемы или обработчика разыменования. Например, зарезервированные символы точки с запятой (;) и равенства (=) часто используются для разделения параметров и значений параметров, применимых к этому сегменту. Зарезервированный символ запятой (,) часто используется для подобных целей. Например, один производитель URI может использовать такой сегмент, как name;v=1.1, чтобы указать ссылку на версию 1.1 имени, тогда как другой может использовать такой сегмент, как name,1.1, чтобы указать то же самое. Типы параметров могут быть определены семантикой конкретной схемы, но в большинстве случаев синтаксис параметра зависит от реализации алгоритма разыменования URI.

person Paul Dixon    schedule 29.01.2010
comment
Что такое непрозрачный разделитель? В каком смысле непрозрачный? - person Peter Mortensen; 26.01.2021

Есть некоторые интересные соглашения относительно его текущего использования. Они говорят о том, когда использовать точку с запятой или запятую. Из книги "Веб-сервисы RESTful":

Используйте знаки пунктуации для разделения нескольких элементов данных на одном уровне иерархии. Используйте запятые, когда порядок элементов имеет значение, ... Используйте точку с запятой, когда порядок не имеет значения.

person Frank Schwieterman    schedule 04.07.2013

Известно, что с 2014 года сегменты пути способствуют Отраженные атаки загрузки файлов. Предположим, у нас есть уязвимый API, который отражает все, что мы ему отправляем:

https://google.com/s?q=rfd%22||calc||

{"results":["q", "rfd\"||calc||","I love rfd"]}

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

https://google.com/s;/setup.bat;?q=rfd%22||calc||

Все, что находится между точками с запятой (;/setup.bat;), не будет отправлено в веб-службу, а вместо этого браузер интерпретирует это как имя файла... для сохранения ответа API.

Теперь файл с именем setup.bat будет загружаться и запускаться, не спрашивая об опасности запуска файлов, загруженных из Интернета (поскольку в его имени содержится слово "setup"). Содержимое будет интерпретировано как пакетный файл Windows, и будет запущена команда calc.exe.

Профилактика:

  • дезинфицировать ввод вашего API (в этом случае они должны просто разрешать буквенно-цифровые символы); бегства недостаточно
  • добавить Content-Disposition: attachment; filename="whatever.txt" к API, которые не будут отображаться; В Google отсутствовала часть filename, что фактически упростило атаку.
  • добавить заголовок X-Content-Type-Options: nosniff в ответы API
person kravietz    schedule 21.10.2014

Я нашел следующие варианты использования:

Это последний символ объекта HTML:

Список ссылок на символы XML и HTML

Чтобы использовать одну из этих ссылок на символьные объекты в документе HTML или XML, введите амперсанд, за которым следует имя объекта и точку с запятой, например, & для амперсанда (&).

Apache Tomcat 7 (или более новые версии?!) использует его как path parameter:

Три уязвимости, связанные с точкой с запятой

Apache Tomcat — это один из примеров веб-сервера, который поддерживает параметры пути. Параметр пути — это дополнительное содержимое после имени файла, разделенное точкой с запятой. Любой произвольный контент после точки с запятой не влияет на целевую страницу веб-браузера. Это означает, что http://example.com/index.jsp;derp по-прежнему будет возвращать индекс .jsp, а не какая-то страница с ошибкой.

Схема URI разделяет по ней MIME и данные:

Схема URI данных

Он может содержать необязательный параметр набора символов, отделенный от предыдущей части точкой с запятой (;).

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

И в IIS 5 и IIS 6 была ошибка для обхода ограничений на загрузку файлов:

Неограниченная загрузка файлов

Добавление расширений файлов в черный список Эту защиту можно обойти: ... добавив символ точки с запятой после запрещенного расширения и перед разрешенным (например, file.asp;.jpg)

Вывод:

Не используйте точки с запятой в URL-адресах, иначе они могут случайно создать объект HTML или схему URI.

person mgutt    schedule 17.02.2017