gpt4 book ai didi

php - mysql_real_escape_string() 和 mysql_escape_string() 是否足以保证应用安全?

转载 作者:IT老高 更新时间:2023-10-28 23:50:44 26 4
gpt4 key购买 nike

mysql_real_rescape_string() 是否足以保护我免受黑客和 SQL 攻击?问是因为我听说这些对所有攻击媒介都没有帮助吗?寻求专家的建议。

编辑:另外,LIKE SQL 攻击呢?

最佳答案

@Charles 非常正确!

您将自己置于多种已知 SQL 攻击的风险之中,包括您提到的

  • SQL 注入(inject):是的! Mysql_Escape_String 可能仍然让您容易受到 SQL 注入(inject)的影响,具体取决于您在查询中使用 PHP 变量的位置。

考虑一下:

$sql = "SELECT number FROM PhoneNumbers " .
"WHERE " . mysql_real_escape_string($field) . " = " . mysql_real_escape_string($value);

这样可以安全准确地逃脱吗?不!为什么?因为黑客仍然可以这样做:

跟着我重复:

mysql_real_escape_string()仅用于转义变量数据、NOT 表名、列名,尤其是 LIMIT 字段。

  • LIKE 漏洞利用:LIKE "$data%"其中 $data 可能是 "%",这将返回所有记录...很可能是安全漏洞...只是想象一下通过信用卡的最后四位数字进行查找...哎呀!现在,黑客可能会收到您系统中的每个信用卡号! (顺便说一句:几乎不建议存储完整的信用卡!)

  • Charset Exploits:不管讨厌的人怎么说,Internet Explorer 仍然,在 2011 年,容易受到 Character Set Exploits 的攻击,这就是 如果你设计的您的 HTML 页面正确,相当于 <meta name="charset" value="UTF-8"/> !这些攻击非常讨厌,因为它们给了黑客与直接 SQL 注入(inject)一样多的控制权:例如满的。

这里有一些示例代码来演示所有这些:

// 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);
}

这是传递各种输入时这段代码的结果:

$ 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 --

$ php sql_exploits.php 1=1 'http://www.reddit.com' id Results: Returns every column and every result.

然后是真正令人讨厌的 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.

你是否理解攻击中的 SQL 无关紧要。这表明 mysql_real_escape_string() 可以轻松被最不成熟的黑客绕过。那是因为它是一种 react 性防御机制。它只修复了数据库中非常有限且已知的漏洞。

所有转义永远不足以保护数据库。事实上,您可以明确地对每一个已知的漏洞使用react,并且在未来,您的代码很可能会受到 future 发现的攻击。<​​/p>

正确且唯一(真正)的防御是一种主动防御:使用准备好的语句。准备好的语句在设计时特别小心,以便只执行有效和已编程的 SQL。这意味着,如果操作正确,能够执行意外 SQL 的几率会大大降低。

理论上,完美实现的准备好的语句将不受所有已知和未知的攻击,因为它们是一种服务器端技术,由数据库服务器自己和与编程语言接口(interface)的库处理。因此,您始终可以得到保护,至少免受所有已知的黑客攻击。

而且代码更少:

$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())) { }

现在这不是那么难,是吗?而且它代码减少了 47%(195 个字符 (PDO) 与 375 个字符 (mysql_)。这就是我所说的“充满胜利”。

编辑:为了解决这个答案引发的所有争议,请允许我重申我已经说过的话:

Using prepared statements allows one to harness the protective measures of the SQL server itself, and therefore you are protected from things that the SQL server people know about. Because of this extra level of protection, you are far safer than by just using escaping, no matter how thorough.

关于php - mysql_real_escape_string() 和 mysql_escape_string() 是否足以保证应用安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5414731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com