gpt4 book ai didi

php - 使用 PHP 和 Zend Framework 防止 SQL 注入(inject) - 如何?

转载 作者:可可西里 更新时间:2023-11-01 06:57:09 31 4
gpt4 key购买 nike

我正在尝试保护我页面上的登录表单免受 SQL 注入(inject)攻击。在服务器端,我使用了Zend Framework(Zend_Db,Zend_Db_Table_Abstract),但是它内置的防注入(inject)功能:quote, quoteInto quoteIdentifier 不能很好地工作(据我所知如何使用它们)。其他方法如 mysql_real_escape_stringaddslashes 似乎根本不起作用...

这就是我要为防御实现的内容:

function prevent_from_sql_injection($str) {
if(preg_match('/[\'"]/', $str))
{die('attack1'); exit; }// no quotes
elseif(preg_match('/[\/\\\\]/', $str))
{die('attack2'); exit; }// no slashes
elseif(preg_match('/(and|or|null|not)/i', $str))
{die('attack3'); exit; }// no sqli boolean keywords
elseif(preg_match('/(union|select|from|where)/i', $str))
{die('attack4'); exit; }// no sqli select keywords
elseif(preg_match('/(group|order|having|limit)/i', $str))
{die('attack5'); exit; }// no sqli select keywords
elseif(preg_match('/(into|file|case|LOAD_FILE|DUMPFILE|char|schema|AES_DECRYPT|AES_ENCRYPT)/i', $str))
{die('attack6'); exit; }// no sqli operators
elseif(preg_match('/(--|#|\/\*)/', $str))
{die('attack7'); exit; }// no sqli comments
elseif(preg_match('/(=|&|\|)/', $str))
{die('attack8'); exit; }// no boolean operators
elseif(preg_match('/(UNI\*\*ON|1 OR 1=1|1 AND 1=1|1 EXEC XP_)/', $str))
{die('attack9'); exit; }
elseif(preg_match('/(1|'| |O|R|=|&#49&#39&#32&#79&#82&#32&#39&#49&#39&#61&#39&#49|%31%27%20%4F%52%20%27%31%27%3D%27%31)/', $str))
{ die('attack10'); exit; }
elseif(preg_match('/(SELECT\s[\w\*\)\(\,\s]+\sFROM\s[\w]+)| (UPDATE\s[\w]+\sSET\s[\w\,\'\=]+)| (INSERT\sINTO\s[\d\w]+[\s\w\d\)\(\,]*\sVALUES\s\([\d\w\'\,\)]+)| (DELETE\sFROM\s[\d\w\'\=]+)/', $str))
{ die('attack11'); exit; }
elseif(preg_match('/(script)|(<)|(>)|(%3c)|(%3e)|(SELECT) |(UPDATE) |(INSERT) |(DELETE)|(GRANT) |(REVOKE)|(UNION)|(<)|(>)/', $str))
{ die('attack12'); exit; }
elseif(!preg_match('/^["a-zA-Z0-9\040]+$/', $str))
{ die('attack13'); exit; }
else return $str;

}

为了测试我的结果,我使用 Firefox 扩展 SQL Inject Me它显示了另外 14 个错误(有时是 21 或 17,我不知道为什么结果不同):

Server Status Code: 302 Found
Tested value: 1' OR '1'='1
Server Status Code: 302 Found
Tested value: 1 UNI/**/ON SELECT ALL FROM WHERE
Server Status Code: 302 Found
Tested value: &#49&#39&#32&#79&#82&#32&#39&#49&#39&#61&#39&#49
Server Status Code: 302 Found
Tested value: 1 OR 1=1
Server Status Code: 302 Found
Tested value: 1' OR '1'='1
Server Status Code: 302 Found
Tested value: 1 EXEC XP_
Server Status Code: 302 Found
Tested value: 1 UNION ALL SELECT 1,2,3,4,5,6,name FROM sysObjects WHERE xtype = 'U' --
Server Status Code: 302 Found
Tested value: %31%27%20%4F%52%20%27%31%27%3D%27%31
Server Status Code: 302 Found
Tested value: 1 AND 1=1
Server Status Code: 302 Found
Tested value: 1' OR '1'='1
Server Status Code: 302 Found
Tested value: 1 AND ASCII(LOWER(SUBSTRING((SELECT TOP 1 name FROM sysobjects WHERE xtype='U'), 1, 1))) > 116

那么防止所有这些 SQL 注入(inject)攻击的最佳方法是什么?使用占位符很好,但在某些情况下并不合适。也许这个扩展是错误的,我有偏执狂?

最佳答案

我强烈推荐使用 Zend_DB .它使用 prepared statements .
准备语句的参数不需要引用;驱动程序会自动处理这个。

If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible

$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));

$stmt = $db->query('SELECT * FROM bugs WHERE reported_by = ? AND bug_status = ?',
array('goofy', 'FIXED')
);

$rows = $stmt->fetchAll();

echo $rows[0]['bug_description'];

关于php - 使用 PHP 和 Zend Framework 防止 SQL 注入(inject) - 如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3383573/

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