У меня есть старый пользовательский веб-сайт php, над которым я работаю. Я обновил php-код и добавил функцию сброса пароля. Я переместил папку «Подключения» за пределы корневой папки, так как я прочитал, что это рекомендуемый курс действий. Мой клиент попросил возможность использовать спецсимволы при сбросе пароля. У меня есть регулярное выражение для этого, которое отлично работает. Кажется, все работает, за исключением того, что когда я пытаюсь использовать несколько символов подряд, я получаю внутреннюю ошибку сервера. Когда я проверяю журнал ошибок, это то, что он говорит:
ModSecurity: Warning. detected SQLi using libinjection with fingerprint 'novc' [file "/dh/apache2/template/etc/mod_sec3_CRS/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"][msg "SQL Injection Attack Detected via libinjection"] [data "Matched Data: novc found within ARGS:newPassword2: Abcd1234!@#$"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.2"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/66"]
Это не было проблемой на тестовом веб-сайте, который я создал, но у меня также есть файл подключения к базе данных в корне папки тестового веб-сайта. На живом веб-сайте у меня есть файл подключения за пределами папки проекта, поскольку я читал, что это лучшая практика.
Connections folder
--connection.php
live website folder
--index.php
--other files, etc.
test website folder
--Connection.php
--other files
Вот мой запрос на обновление пароля:
// if form is submitted and the value equals the value of the hidden input
if (isset($_POST['newPassword'])) {
// password regex match
if (!preg_match('/^(?=.*[A-Za-z])(?=.*\d)(?=.*[!#$%&()*@?^])[A-Za-z\d!#$%&()*@?^]{8,30}$/', $_POST['newPassword'])) {
exit('password should be between 8 and 30 characters and contain at least one number and one special character');
}
// Check if both the password and confirm password fields match
if ($_POST['newPassword'] != $_POST['newPassword2']) {
exit('Passwords do not match!');
}
// set the date
$month = date ("M");
$year = date ("Y");
$day = date ("j");
// lastEditTime and lastEditedBy
$lastEditTime = $month." ".$day.", ".$year;
$lastEditedBy = $_SESSION['MM_Username'];
$userId = $_SESSION['MM_UserID'];
$newPassword = password_hash($_POST['newPassword'],PASSWORD_DEFAULT);
$updateStmt = $connection->prepare("UPDATE tbl_users SET newPassword= ?, lastEditedBy= ?, lastEditTime= ? WHERE userID= ?");
$updateStmt->bind_param('sssi',$newPassword,$lastEditedBy,$lastEditTime,$userId);
$updateStmt->execute();
$updateStmt->close();
header("Location: reset4.php");
exit;
}
Я никогда не сталкивался с этой проблемой раньше. Есть ли у кого-нибудь совет, как это исправить?
Также обратите внимание, что вы можете сделать $lastEditTime = date('M j Y');
в одной строке.
В противном случае код выглядит хорошо, вы используете сильное хэширование и связанные параметры. Единственное предложение, которое я бы сделал с точки зрения безопасности, - это также запрашивать старый пароль при запросе нового пароля, а затем проверять его перед запуском обновления.
@AlexHowansky, веб-сайт размещен на Dreamhost, и я использую SFTP для внесения изменений. Знаете ли вы, смогу ли я получить доступ к конфигурации ModSecurity через SFTP? На Dreamhost Cpanel нет ничего, что позволяло бы мне вносить изменения в ModSecurity.
Без понятия. Если это виртуальный хостинг, вам, вероятно, не повезло. Если это выделенный VPS, файл конфигурации, скорее всего, находится где-то в /etc.
Ваши правила ModSecurity для SQL-инъекций блокируют вещи, которые выглядят как SQL-инъекции, и это может привести к ложным срабатываниям. Эти правила, вероятно, взяты из Базового набора правил OWASP ModSecurity
Как правило, вы хотите исключить поле пароля из проверки основного набора правил ModSecurity. Обычно это делается путем добавления в конфигурацию ModSec такого правила, как:
SecRule REQUEST_URI "@streq /your/page/uri" \
"id:12345,phase:1,t:none,nolog,pass,\
ctl:ruleRemoveTargetByTag=.*;ARGS:password"
Подпишите свой собственный URL и ваши конкретные параметры.
Я не знаю, как бы вы изменили свою конфигурацию в среде Dreamhost (и даже разрешили ли они это). Это отдельный вопрос.
Также обратите внимание, что ModSecurity следует настроить таким образом, чтобы избежать регистрации значений пароля и других конфиденциальных полей. См. «Удаление конфиденциальных данных из журналов аудита» в отличном Руководстве по ModSecurity.
Спасибо @Egret. Я связался со службой поддержки Dreamhost, и они смогли решить проблему со своей стороны.
Пожалуйста, добавьте соответствующий код к вопросу - например, вы используете параметризованные запросы?