Mon*_*ica 21 php mysql security
mysql_real_rescape_string()是否足以保护我免受黑客和SQL攻击?问,因为我听说这些对所有攻击媒介没有帮助?寻找专家的意见.
编辑:另外,LIKE SQL攻击怎么样?
The*_*ith 14
@Charles非常正确!
您将自己置于多种类型的已知 SQL攻击的风险之中,包括,如您所述
考虑一下:
$sql = "SELECT number FROM PhoneNumbers " .
"WHERE " . mysql_real_escape_string($field) . " = " . mysql_real_escape_string($value);
Run Code Online (Sandbox Code Playgroud)
这样可以安全准确地逃脱吗?没有!为什么?因为黑客很可能仍然这样做:
在我之后重复:
mysql_real_escape_string()
仅用于转义变量数据,而不是表名,列名,尤其不是LIMIT字段.
喜欢利用:喜欢"$ data%",其中$ data可能是"%",这将返回所有记录......这很可能是一个安全漏洞...只是想象一下信用卡的最后四位数的查找. OOP!现在,黑客可能会收到您系统中的每个信用卡号码!(顺便说一句:几乎不建议存储完整的信用卡!)
Charset漏洞利用:无论仇恨者说什么,2011年,Internet Explorer 仍然容易受到字符集漏洞利用的影响,如果您正确设计了HTML页面,那就相当于<meta name="charset" value="UTF-8"/>
!这些攻击是非常讨厌的,因为它们给黑客提供了与直接SQL注入一样多的控制权:例如完整.
这是一些示例代码来演示所有这些:
// Contains class DBConfig; database information.
require_once('../.dbcreds');
$dblink = mysql_connect(DBConfig::$host, DBConfig::$user, DBConfig::$pass);
mysql_select_db(DBConfig::$db);
//print_r($argv);
$sql = sprintf("SELECT url FROM GrabbedURLs WHERE %s LIKE '%s%%' LIMIT %s",
mysql_real_escape_string($argv[1]),
mysql_real_escape_string($argv[2]),
mysql_real_escape_string($argv[3]));
echo "SQL: $sql\n";
$qq = mysql_query($sql);
while (($data = mysql_fetch_array($qq)))
{
print_r($data);
}
Run Code Online (Sandbox Code Playgroud)
以下是传递各种输入时此代码的结果:
$ php sql_exploits.php url http://www.reddit.com id
SQL generated: SELECT url FROM GrabbedURLs
WHERE url LIKE 'http://www.reddit.com%'
ORDER BY id;
Returns: Just URLs beginning w/ "http://www.reddit.com"
$ php sql_exploits.php url % id
SQL generated: SELECT url FROM GrabbedURLs
WHERE url LIKE '%%'
ORDER BY id;
Results: Returns every result Not what you programmed, ergo an exploit --
Run Code Online (Sandbox Code Playgroud)
$ PHP sql_exploits.php 1 = 1 ' http://www.reddit.com '身份证结果:返回每列和每个结果.
然后是真正令人讨厌的LIMIT漏洞:
$ php sql_exploits.php url
> 'http://www.reddit.com'
> "UNION SELECT name FROM CachedDomains"
Generated SQL: SELECT url FROM GrabbedURLs
WHERE url LIKE 'http://reddit.com%'
LIMIT 1
UNION
SELECT name FROM CachedDomains;
Returns: An entirely unexpected, potentially (probably) unauthorized query
from another, completely different table.
Run Code Online (Sandbox Code Playgroud)
你是否理解攻击中的SQL是无关紧要的.这证明了mysql_real_escape_string()即使是最不成熟的黑客也很容易被绕过.那是因为它是一种反应性的防御机制.它只修复了数据库中非常有限且已知的漏洞.
所有转义都不足以保护数据库.实际上,您可以明确地对每个KNOWN漏洞进行REACT,并且将来,您的代码很可能会受到未来发现的攻击.
正确的,唯一的(真正的)防御是主动的:使用准备好的陈述.准备好的语句经过精心设计,因此只执行有效和PROGRAMMED SQL.这意味着,当正确完成时,能够执行意外SQL的几率大大降低.
从理论上讲,完全实现的预处理语句将不受所有已知和未知攻击的影响,因为它们是服务器端技术,由DATABASE SERVERS THEMSELVES和与编程语言交互的库处理.因此,您始终可以保证不受任何已知的黑客攻击.
它的代码更少:
$pdo = new PDO($dsn);
$column = 'url';
$value = 'http://www.stackoverflow.com/';
$limit = 1;
$validColumns = array('url', 'last_fetched');
// Make sure to validate whether $column is a valid search parameter.
// Default to 'id' if it's an invalid column.
if (!in_array($column, $validColumns) { $column = 'id'; }
$statement = $pdo->prepare('SELECT url FROM GrabbedURLs ' .
'WHERE ' . $column . '=? ' .
'LIMIT ' . intval($limit));
$statement->execute(array($value));
while (($data = $statement->fetch())) { }
Run Code Online (Sandbox Code Playgroud)
现在那不是很难吗?它的代码减少了47%(195个字符(PDO)和375个字符(mysql_).这就是我所说的"充满胜利".
编辑:为了解决所有争议,这个答案激起了,请允许我重申我已经说过的话:
使用预准备语句可以利用SQL服务器本身的保护措施,因此您可以免受SQL服务器人员所知道的事情的影响.由于这种额外的保护,无论多么彻底,您都比使用转义更安全.
重要更新:在测试了Col. Shrapnel提供的可能的漏洞利用代码并查看MySQL版本5.0.22,5.0.45,5.0.77和5.1.48之后,似乎GBK字符集和可能的其他版本与MySQL版本相结合如果您仅使用SET NAMES
而不是使用特定mysql_set_charset
/ mysqli_set_charset
函数,则5.0.77可能会使您的代码容易受到攻击.因为那些仅在PHP 5.2.x中添加,旧的PHP和旧的MySQL的组合可能产生潜在的SQL注入漏洞,即使您认为自己是安全的并且按照书本正确地完成了所有操作.
如果没有设置的字符集结合mysql_real_escape_string
,你会发现自己容易受到特定的字符集漏洞可能与旧的MySQL版本. 以前的研究更多信息.
如果可能,请使用mysql_set_charset
. SET NAMES ...
是不是足以防止这种特定漏洞,如果你正在使用MySQL的影响版本(前5.0.22 5.0.77).
是.如果你不会忘记:
mysql_real_rescape_string()
$id = (int)$_GET['id'];
)然后你受到了保护.
归档时间: |
|
查看次数: |
6218 次 |
最近记录: |