提问人:Bert W 提问时间:11/27/2022 最后编辑:Bert W 更新时间:11/28/2022 访问量:629
密码中的特殊字符导致内部服务器错误“通过 libinjection 检测到 SQL 注入攻击”
Special characters in password causing internal server error "SQL Injection attack detected via libinjection"
问:
我有一个旧的自定义 php 网站,我一直在工作。我已经更新了 php 代码并具有密码重置功能。我将 Connections 文件夹移到了根文件夹之外,因为这是我读到的推荐操作方案。我的客户要求能够在密码重置中使用特殊字符。我有正则表达式,效果很好。一切似乎都在工作,除了当我尝试连续使用多个字符时,我收到内部服务器错误。当我检查错误日志时,它是这样说的:
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;
}
我以前从未遇到过这个问题。有没有人对如何纠正这个问题有任何建议?
答:
3赞
Egret
11/28/2022
#1
用于 SQL 注入的 ModSecurity 规则正在阻止看起来像 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 手册中的“从审计日志中删除敏感数据”。
评论
1赞
Bert W
11/28/2022
感谢@Egret我联系了 Dreamhost 支持,他们能够最终解决问题。
上一个:如何防止PHP中的SQL注入?
评论
$lastEditTime = date('M j Y');