Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用PHP和Zend框架防止SQL注入?_Php_Mysql_Zend Framework_Sql Injection - Fatal编程技术网

如何使用PHP和Zend框架防止SQL注入?

如何使用PHP和Zend框架防止SQL注入?,php,mysql,zend-framework,sql-injection,Php,Mysql,Zend Framework,Sql Injection,我试图保护我页面上的登录表单不受SQL注入的影响。在服务器端,我使用Zend Framework(Zend_Db,Zend_Db_Table\u Abstract),但其内置的注入预防功能:quote,quoteInto,quoteIdentifier不能很好地工作(就我所知如何使用它们)。其他方式,如mysql\u real\u escape\u string,addslashes似乎根本不起作用 这是我试图为国防部实施的: function prevent_from_sql_injectio

我试图保护我页面上的登录表单不受SQL注入的影响。在服务器端,我使用Zend Framework(
Zend_Db
Zend_Db_Table\u Abstract
),但其内置的注入预防功能:
quote
quoteInto
quoteIdentifier
不能很好地工作(就我所知如何使用它们)。其他方式,如mysql\u real\u escape\u string,
addslashes
似乎根本不起作用

这是我试图为国防部实施的:

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扩展,它显示了14个错误(有时是21个或17个,我不知道为什么结果不同):


那么,防止所有这些SQL注入攻击的最佳方法是什么?使用占位符是好的,但在某些情况下并不好。也许这个扩展是错误的,我有妄想症?

使用准备好的SQL语句,而不是值转义

 $st = $pdo->prepare("SELECT * FROM tbl WHERE x = ?");
 $st->execute($x);
将几个SQL语句列入黑名单不是一种明智的方法。Firefox的扩展有误导性,给人错误的印象


显然,您不应该开始接受随机SQL命令作为输入。最多使用一些请求变量作为查询数据。准备好的陈述足以为该案件提供担保。连接SQL命令和变量是一种过时的做法(这个可疑的Firefox扩展似乎表明了这一点)。

我强烈建议使用。它使用。
编制报表的参数不需要引用;司机会自动处理这个问题

如果应用程序专门使用 准备好的语句,开发者可以 确保不会有SQL注入 发生(但是,如果 查询正在使用 未切换的输入,SQL注入是 仍然可能


将此代码放入您的标题页

function clean_header($string)
{
$string = trim($string);

// From RFC 822: “The field-body may be composed of any ASCII
// characters, except CR or LF.”
if (strpos($string, “\n“) !== false) {
$string = substr($string, 0, strpos($string, “\n“));
}
if (strpos($string, “\r“) !== false) {
$string = substr($string, 0, strpos($string, “\r“));
}

return $string;
}

定义您提到的其他选项“不起作用”的方式。您是否考虑过其中一些只是flase报告?仅仅因为服务器返回302代码,并不意味着注入成功。也许您是对的,而此ext返回的结果不正确。但我如何测试sql注入?看到如此荒谬的代码片段,我总是在想,如果发布它的站点使用了同样的“保护”方法?你怎么能发布一个
elseif(preg_匹配('/(and | and | or | null | not)/i',$str))
string如果这里有这样的检查,那么?
但是它内置的注射预防功能:quote、quoteInto、quoteIdentifier不能很好地工作
LOL。它对每个人都有效。所以,问题出在其他地方。在椅子和显示器之间的某个地方……这正是Zend_Db提供的功能。我应该如何处理Zend_Auth_Adapter_DbTable?如果在数组中正确使用这些参数,实际上转义没有问题-它们是自动引用的还是什么?是的。这就是准备好的语句的用途。“准备好的语句的参数不需要被引用;驱动程序会自动处理。”请阅读链接源以了解更多信息。我同意Benjamin的观点,使用Zend_Db消除了预处理语句的所有顾虑,我没有任何问题。有时预处理语句也可以允许SQL注入:@FractalizeR如果查询的其他部分是使用未扫描的输入构建的,则SQL注入仍然是可能的
$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'];
function clean_header($string)
{
$string = trim($string);

// From RFC 822: “The field-body may be composed of any ASCII
// characters, except CR or LF.”
if (strpos($string, “\n“) !== false) {
$string = substr($string, 0, strpos($string, “\n“));
}
if (strpos($string, “\r“) !== false) {
$string = substr($string, 0, strpos($string, “\r“));
}

return $string;
}