我刚写了一个简单的PHP类,我认为它可以帮助我防止或检测可能的SQL攻击。我不确定这是否真的有效,这就是为什么我在这里发布它来阅读你的想法和建议。
因此,让我们从经典的config.php文件开始,该文件创建与DB的连接并选择特定的数据库。我把它变成了一个类,它返回主页面中的连接链接。让我们看看:
<?php
class mysql_init
{
public function initDb(){
$con = mysqli_connect("localhost","user","password");
mysqli_select_db($con,"geneticDb");
return $con;
}
}
?>
所以在这之后让我们看一下主页safe.php的代码。它有一个简单的例子,通过用户通过GET请求提供的Id从数据库中获取数据。
<?php
require_once('filter.php');
require_once('config.php');
$connection = new mysql_init();
$con = $connection->initDb();
$safe = new filter($con,'GET');
$n_id = $_GET['noteId'];
$data = mysqli_query($con,"SELECT noteType FROM notes WHERE noteId = $n_id ");
if($data){
$row = mysqli_fetch_array($data, MYSQLI_BOTH);
echo $row["noteType"];
}
?>
正如您所看到的,我也包括了filter.php,它是一个扫描用户发送的GET或POST请求的类。如果它会发现一些奇怪的东西,它会占用与数据库的会话的线程ID并将其关闭。事实是,这还没有完成,我的意思是我会用一些期货来保存一些(攻击者的)日志到数据库,并将他/她重定向到另一页通知他/她的记录。
<?php
class filter
{
private $_activity = 0;
public function __construct($sql_connection,$method){
switch ($method) {
case 'GET':
$this->check_GET($sql_connection);
break;
case 'POST':
$this->check_POST($sql_connection);
break;
case 'ALL':
$this->check_POST($sql_connection);
$this->check_GET($sql_connection);
break;
default:
# code...
break;
}
}
private function check_GET($con){
if($_SERVER['REQUEST_METHOD'] == 'GET')
{
echo $_SERVER['REQUEST_URI']."<br>".$_SERVER['SCRIPT_NAME']."<br><br>";
foreach($_GET as $index => $value)
{
if(preg_match('/\s/', $value)) # no whitespaces
$this->_activity = 1;
if(preg_match('/[\'"]/', $value)) # no quotes
$this->_activity = 1;
if(preg_match('/[\/\\\\]/', $value)) # no slashes
$this->_activity = 1;
if(preg_match('/(and|or|null|not|if)/i', $value)) # no sqli boolean keywords
$this->_activity = 1;
if(preg_match('/(union|select|from|where)/i', $value)) # no sqli select keywords
$this->_activity = 1;
if(preg_match('/(group|order|having|limit)/i', $value)) # no sqli select keywords
$this->_activity = 1;
if(preg_match('/(into|file|case)/i', $value)) # no sqli operators
$this->_activity = 1;
if(preg_match('/(;|--|#|\/\*)/', $value)) # no sqli comments
$this->_activity = 1;
if(preg_match('/(=|&|\|)/', $value)) # no boolean operators
$this->_activity = 1;
if(isset($this->_activity) && $this->_activity == 1){
echo "Something detected => ".$index." : ".$value."<br>";
$thread_id = mysqli_thread_id($con);
mysqli_kill($con, $thread_id);
$this->_activity = 0;
}
}
}
}
private function check_POST($con){
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
echo $_SERVER['REQUEST_URI']."<br>".$_SERVER['SCRIPT_NAME']."<br><br>";
foreach($_POST as $index => $value)
{
if(preg_match('/\s/', $value)) # no whitespaces
$this->_activity = 1;
if(preg_match('/[\'"]/', $value)) # no quotes
$this->_activity = 1;
if(preg_match('/[\/\\\\]/', $value)) # no slashes
$this->_activity = 1;
if(preg_match('/(and|or|null|not|if)/i', $value)) # no sqli boolean keywords
$this->_activity = 1;
if(preg_match('/(union|select|from|where)/i', $value)) # no sqli select keywords
$this->_activity = 1;
if(preg_match('/(group|order|having|limit)/i', $value)) # no sqli select keywords
$this->_activity = 1;
if(preg_match('/(into|file|case)/i', $value)) # no sqli operators
$this->_activity = 1;
if(preg_match('/(;|--|#|\/\*)/', $value)) # no sqli comments
$this->_activity = 1;
if(preg_match('/(=|&|\|)/', $value)) # no boolean operators
$this->_activity = 1;
if(isset($this->_activity) && $this->_activity == 1){
echo "Something detected => ".$index." : ".$value."<br>";
$thread_id = mysqli_thread_id($con);
mysqli_kill($con, $thread_id);
$this->_activity = 0;
}
}
}
}
}
?>
所以现在一切都好。你认为这段代码是有效的,还是以某种方式可以绕过它?
谢谢。
答案 0 :(得分:1)
此类可以阻止或检测可能的SQL攻击吗?
没有。
它也适用于现实生活。
想象一下,在Stack Overflow这个站点上使用了类似的方法。您是否能够发布充满“危险”角色的问题?