Назад | Перейти на главную страницу

Экранирование символов в .htaccess

Я не могу найти правильный список (или вам нужно быть зарегистрированным на каком-то форуме или неясным списком), из которых символы должны быть экранированы в .htaccess файл. Я обнаружил, что точки не нужно экранировать - но для меня это нелогично, потому что они имеют значение в «регулярном выражении».

Например это переписать ...

RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} /index.php\/component\/users\/\?task=registration.register [NC]
RewriteRule .* - [F,L]

Он избежал всех косых черт, которые не являются "началом", но тем не менее, POST "проходит"

Мой вопрос - есть ли у кого-нибудь список, какие символы следует избегать?

.htaccess поддерживает гораздо больше, чем просто mod_rewrite директивы.

Здесь перечислены все директивы, поддерживаемые Apache, и разрешены ли они в .htaccess файлы https://httpd.apache.org/docs/2.4/mod/quickreference.html

Не каждая директива, разрешенная в .htaccess, имеет одинаковые правила / требования для экранирования «специальных» символов, поскольку многие НЕ являются регулярными выражениями. Обычно в руководстве указывается, какой набор правил регулирует директиву.

Интересно может быть https://httpd.apache.org/docs/2.4/expr.html
https://httpd.apache.org/docs/2.4/rewrite/intro.html#regex

у кого-нибудь есть список, какие символы следует избегать?

Вы не найдете простого списка.

Нужно ли экранировать определенные символы в .htaccess (или файлы конфигурации Apache в целом) зависит от контекст (модуль / директива и аргумент) и то, что вы хотите сделать (используйте специальное значение метасимволов или сопоставьте буквальный символ).

Единственный персонаж, которому повсеместно нужно будет убежать в .htaccess это пространство. Поскольку пространство используется как разделитель между аргументы. Если сам аргумент содержит пробел, его необходимо экранировать, иначе директива просто не сможет правильно скомпилироваться. Если аргумент содержит пространство тогда вы можете либо экранировать его, либо заключить весь аргумент в двойные кавычки. (Если аргумент является регулярным выражением, тогда может быть проще / понятнее использовать пробел сокращенный класс символов \s вместо.)

Я обнаружил, что точки не нужно экранировать - но для меня это нелогично, потому что они имеют значение в "регулярном выражении"

Ну, точно, вы не можете обобщить и сказать, что точки не нужно экранировать - это не имеет смысла. Нужно ли вообще экранировать точку, зависит от контекста и значения. Например:

  • В обычном строковом аргументе (таком как RewriteCond TestString или RewriteRule замена) вам не нужно избегать точки. Точка здесь не имеет особого значения. Экранирование точки здесь не причиняет никакого вреда - ничего не делает - но может ухудшить читаемость, что является важным соображением.

  • В регулярном выражении (например, RewriteCond CondPattern или RewriteRule шаблон и любые другие директивы / аргументы Apache, которые принимают регулярное выражение):

    • Если вы хотите сопоставить любой символ (кроме новой строки), вы не должны избегать точки.
    • Если вы хотите сопоставить буквальную точку, вам нужно экранировать точку, чтобы свести на нет ее особое значение.
    • Однако, чтобы соответствовать буквальной точке внутри класса персонажей тогда вам не нужно избегать точки. Поскольку при использовании внутри класса символов регулярного выражения точка не имеет особого значения.

Обратите внимание, что Apache использует разновидность регулярных выражений PCRE (Perl Compatible Regular Expressions). Применяется то же экранирование.

Он избежал всех косых черт, которые не являются "началом" ...

И в этом нет никакого смысла. (К сожалению, существует множество примеров mod_rewrite / regex, которые не являются строго правильными.)

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


В стороне:

RewriteCond %{REQUEST_URI} /index.php\/component\/users\/\?task=registration.register [NC]

Однако все это состояние выглядит неправильно. Не из-за экранирования обратной косой черты, а потому, что похоже, что вы пытаетесь сопоставить строку запроса с REQUEST_URI серверная переменная. В REQUEST_URI Переменная server содержит только URL-путь. Это будет соответствовать, только если знак вопроса (?) кодируется URL как %3F в запросе (т. е. нет строки запроса) - что было бы необычно. Обычно такое условие никогда не выполняется, и запрос никогда не блокируется.

Почему не ускользнули обе точки? Похоже, они должны быть в этом контекст. Но только вы точно знаете, должны они быть или нет.

RewriteRule .* - [F,L]

В L флаг не требуется (это подразумевается при использовании с F флаг). В .* регулярное выражение не оптимально, однако RewriteCond директиву следует удалить и проверить URL-путь в RewriteRule шаблон вместо.