我正在考虑这种逃避方法的实用解决方案。 mysql_query不会同时发出两个查询,因此攻击者无法使用“OR 1”之类的内容;从用户删除; select * from //他会在这里猜测其余的查询。 (它变得令人困惑)
(我显然不喜欢pdo,当你需要在每个类的每个函数中定义一个连接时,它在oop中是不实际的,否则我每次都必须使用$ this或global $ dbc。)
答案 0 :(得分:2)
不是,不。除了掩埋单独的DML或DDL或语句之外,查询还有多种方法可以“不安全”。例如:
并且必须审查每个特定查询,以便在中间插入随机代码。例如,如果查询结果将以某种方式呈现给用户,则指向具有认证信息的表的子查询可能潜在地让用户推断很多。 (想象一下一系列测试where exists (select 1 from app_users where username = 'JoeAdmin' and password like 'a%')
,然后password like 'ba%'
一旦确定b
,依此类推。即使黑客最初并不知道你有一个名为{{1的表他们可以通过在系统表上使用这种方法快速解决这个问题。)
答案 1 :(得分:2)
逃避的实际解决方案是:
$blah = mysql_real_escape_string($blah, $connection);
$num = (int)$num;
$sql = "select * from `test` where foo = '$blah' and num_col = $num";
每次将变量插入SQL字符串时,都需要对其进行转义。没有例外。您应该尽可能地将其转换到嵌入点,以便在验证读取代码时更容易验证是否正在进行此操作。
如果您只有一个连接,则可以定义自己的功能:
function qescape($var)
{
global $connection;
return mysql_real_escape_string($var, $connection);
}
我对你所做的陈述提出了一个大问题:
mysql_query不会同时发出两个查询,因此攻击者无法使用
之类的内容
虽然技术上是正确的,但他们可以做各种其他讨厌的事情,而无需运行多个查询。一个优秀的黑客可能能够查看,修改和插入他们想要的任何数据库,甚至无法运行多个查询。
答案 2 :(得分:2)
不,您仍需要转义每个非数字类型,而不仅仅是最后一个参数。
检查用户名/密码匹配是否应该登录用户的示例:
// Check username / password
SELECT user_id FROM users WHERE username = 'nickb' AND password = 'password'
如果只转义了最后一个参数(密码),那么我可以传递这个:
username="nickb' --"
导致:
SELECT user_id FROM users WHERE username = 'nickb'
此处,用户无需密码即可登录。
答案 3 :(得分:0)
我不明白整个想法。
你为什么选择这种方法?
有定期的逃避/绑定/白名单方法
为什么他们都不适合你?为什么设计一些不寻常和无法使用的东西?
我已经多次告诉你了 - 逃避不是“防止注射” 它只是SQL语法规则的一部分。只是作为一种副作用,它可以保护你的琴弦免受注射 所以,无论如何,你必须逃避(如果你不想绑定)你的字符串 因此,对于像“仅查询查询中的最后一个参数”所有这样的奇怪发明是没有用的。
有了主意吗?