TL; DR — правило ModSecurity по умолчанию на моем сервере генерирует внутреннюю ошибку сервера 500 при попытке отправить поле формы PHP, содержащее слово «from», так как оно рассматривает его как возможное внедрение SQL, даже если я использую ЗОП подготовил заявления. Не уверен, что это лучший способ исправить это.
При попытке отправить форму с текстовой областью, которая содержит «измененный адрес электронной почты с x на x», я получаю ошибку 500 Internal Server, и я сузил ее до слова «from», являющегося виновником. Исходя из того, что я вижу в журналах, создается впечатление, что отправка формы рассматривается как возможная инъекция SQL. Я отключил это конкретное правило (300016) в качестве теста, и форма начала работать правильно.
Из журнала ошибок Apache:
[:error] [pid 39495] [client x.x.x.x] ModSecurity: Access denied with code 500 (phase 2). Pattern match "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\\\\(.*from)" at ARGS:notes. [file "/etc/apache2/conf.d/modsec/modsec2.user.conf"] [line "247"] [id "300016"] [rev "2"] [msg "Generic SQL injection protection"] [severity "CRITICAL"] [hostname "xxxxxxxxxx.com"] [uri "/path/to/page/with/form.php"] [unique_id "WiGVQoP7XCbNIjL9nZzrKAAAAAo"]
Из журнала аудита ModSecurity:
Message: Access denied with code 500 (phase 2). Pattern match "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\\(.*from)" at ARGS:notes. [file "/etc/apache2/conf.d/modsec/modsec2.user.conf"] [line "247"] [id "300016"] [rev "2"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]
Action: Intercepted (phase 2)
Stopwatch: 1512150338540293 2147 (- - -)
Stopwatch2: 1512150338540293 2147; combined=549, p1=96, p2=449, p3=0, p4=0, p5=3, sr=32, sw=1, l=0, gc=0
Producer: ModSecurity for Apache/2.9.0 (http://www.modsecurity.org/).
Server: Apache
Engine-Mode: "ENABLED"
Правило ModSecurity:
#Generic SQL sigs
SecRule REQUEST_URI "!(/node/[0-9]+/edit|/forum/posting\.php|/admins/wnedit\.php|/alt_doc\.php\?returnUrl=.*edit|/admin/categories\.php\?cPath=.*|modules\.php\?name=Forums&;file=posting&;mode=.*)" "chain,id:300016,t:lowercase,rev:2,severity:2,msg:'Generic SQL injection protection'"SecRule ARGS "(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\(.*from)"
Я не очень разбираюсь в ModSecurity, и я действительно не уверен, каким будет лучший способ решить эту проблему, поэтому я подумал, что я посмотрю, есть ли у кого-нибудь здесь какие-либо предложения.
PS — Поскольку форма работает, когда правило ModSecurity отключено, я не думаю, что сама форма является проблемой, но на всякий случай …
форма
<form method="post">
<textarea class="form-control" placeholder="Notes" name="notes" cols="40" rows="10" wrap="VIRTUAL">
<input class="form-control" type="submit" name="Submit" value="Save Changes">
</form>
Обработка форм
$notes = $_POST['notes'];
$stmt = $pdo->prepare("UPDATE links
SET notes = :notes
WHERE id = :link_id");
$stmt->bindValue('notes', $notes, PDO::PARAM_LOB);
$stmt->bindValue('link_id', $link_id, PDO::PARAM_INT);
$stmt->execute();
У меня была эта ошибка сегодня, и во время моего расследования я заметил, что либо регулярное выражение неверно, либо сообщается с ошибкой в сообщении об ошибке
(insert[[:space:]]+into.+values|select.*from.+[a-z|A-Z|0-9]|select.+from|bulk[[:space:]]+insert|union.+select|convert.+\\\\(.*from)
В выражении регулярного выражения есть лишние скобки (первый символ).
Вы всегда можете добавить фиксированную версию в качестве пользовательского правила (при этом отключив исходное правило 300016) и подождать, пока Apache не исправит его.
Других решений пока нет …