htaccess отправляет 404, если строка запроса содержит ключевое слово

#apache #.htaccess #request.querystring

#apache #.htaccess #мод-перезапись #запрос.строка запроса

Вопрос:

Я вижу много трафика, который, как я подозреваю, проверяет наличие ошибки или эксплойта в формате запроса

 https://example.com/?testword
  

Я подумал, что, изучая это подробнее, я мог бы сэкономить ресурсы и прервать или препятствовать этим запросам с помощью ответа 404 или 500

Я пробовал

 RewriteEngine On
RewriteCond %{QUERY_STRING} !(^|amp;)testword($|amp;) [NC]
RewriteRule https://example.com/ [L,R=404]
  

И некоторые другие варианты строки запроса совпадают, но, похоже, ни один из них не возвращает 404 при тестировании. Другие вопросы, которые я нашел, ищите значения / пары строк запроса и переписывайте их, но, похоже, никакие примеры не завершаются только для одного значения.

Комментарии:

1. 404 не является перенаправлением, поэтому R = 404 не имеет смысла, вы можете изменить этот флаг, указав F (403 запрещено) или G (410 пропало)

2. кроме того, возможно, вы хотите взглянуть на mod_security.

3. И ваше выражение в условии должно быть отменено. Вы хотите перенаправить, если тестовое слово присутствует в строке запроса, поэтому отрицание («!») не имеет никакого смысла в условии.

4. @on8tom R=404 имеет смысл. R Флаг является многоцелевым. Это не только для внешних перенаправлений. Поведение отличается при указании HTTP-статуса, отличного от 3xx. (Так же, как вы можете использовать коды состояния, отличные от 3xx, с mod_alias Redirect и RedirectMatch директивами.)

Ответ №1:

 RewriteCond %{QUERY_STRING} !(^|amp;)testword($|amp;) [NC]
RewriteRule https://example.com/ [L,R=404]
  

Здесь есть несколько проблем:

  • CondPattern в вашем условии отрицается ( ! префикс), поэтому он выполняется успешно только тогда, когда testword отсутствует в строке запроса.

  • В RewriteRule директиве отсутствует аргумент шаблона (первый) (или аргумент подстановки (второй), в зависимости от того, как вы на это смотрите). RewriteRule Директива соответствует только URL-пути.

  • Когда вы указываете код состояния, отличный от 3xx, для R флага, замена игнорируется. Вы должны указать один дефис ( - ), чтобы указать отсутствие замены.

Чтобы проверить, что целочисленное «тестовое слово» существует где угодно в строке запроса, вы можете использовать регулярное btestwordb выражение — где b границы слов. Или, может быть, вы просто хотите, чтобы регулярное testword выражение соответствовало «testword» буквально в любом месте, в том числе когда оно появляется как часть другого слова? Для сравнения, в регулярном (^|amp;)testword($|amp;) выражении будут отсутствовать случаи, когда «testword» отображается как имя параметра URL.

Вместо этого попробуйте следующее:

 RewriteCond %{QUERY_STRING} btestwordb [NC]
RewriteRule ^$ - [R=404]
  

Это соответствует только домашней странице (т.е. пустой URL-путь). L Флаг не требуется при указании статуса возврата, отличного от 3xx, он подразумевается.

- (Второй аргумент) указывает на отсутствие замены. Как упоминалось выше, при указании HTTP-статуса, отличного от 3xx, строка подстановки в любом случае игнорируется.

Чтобы проверить любой URL-путь, просто удалите $ (привязку конца строки) в RewriteRule шаблоне. Например:

 RewriteCond %{QUERY_STRING} btestwordb [NC]
RewriteRule ^ - [R=404]
  

Если ваша домашняя страница не принимает никаких параметров строки запроса, вы можете просто отклонить запрос (т.Е. 404 Не найден) при наличии строки запроса. Например:

 RewriteCond %{QUERY_STRING} .
RewriteRule ^$ - [R=404]
  

Комментарии:

1. Лучший ответ MrWhite. Перепишите второй %{QUERY_STRING} . RewriteRule ^$ — [R=404]