Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.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 我是否在避免sql注入?_Php_Mysql_Sql Injection - Fatal编程技术网

Php 我是否在避免sql注入?

Php 我是否在避免sql注入?,php,mysql,sql-injection,Php,Mysql,Sql Injection,我这样做对吗?这有助于避免sql注入吗 $deleteid = htmlspecialchars(strip_tags(mysql_real_escape_string($_POST['listid']))); mysql_send("DELETE FROM stage where listid='$deleteid'"); 是的,在MySQL语句中的字符串声明中使用on值将阻止SQL注入。这正是这个函数的目的 但您不需要其他两个函数和。因为这些函数分别用于删除(HTML)标记和用字符引用替

我这样做对吗?这有助于避免sql注入吗

$deleteid = htmlspecialchars(strip_tags(mysql_real_escape_string($_POST['listid'])));

mysql_send("DELETE FROM stage where listid='$deleteid'");
是的,在MySQL语句中的字符串声明中使用on值将阻止SQL注入。这正是这个函数的目的

但您不需要其他两个函数和。因为这些函数分别用于删除(HTML)标记和用字符引用替换HTML特殊字符。它们不是为了保护您免受SQL注入的影响


事实上,在
mysql\u real\u escape\u string
之后使用
strip\u标记和/或
htmlspecialchars
可能会在某些情况下中断转义(例如,在使用非美国ASCII字符集时,另请参见)。因此,请确保在将其返回值插入SQL语句之前使用该函数


除了使用
mysql\u real\u escape\u string
对输出进行编码外,还可以使用以下方法验证输入:

此验证确保查询中只使用不需要转义的(正)整数值。


您应该只调用
mysql\u real\u escape\u string

htmlspecialchars
strip\u标签
函数用于对要显示为HTML的字符串进行编码。

它们不应该与SQL一起使用,因为它可以防止SQL注入攻击,但这是一种糟糕的方法。改用


既然你的评论说你正在系统地改变你的整个网站,那就用更好的方法吧。如果您以后想切换到另一个后端,那么您可能需要移动到一个非MySQL特定的数据库API。

除了上述建议(只有
MySQL\u real\u escape\u string
但更好的是准备好的语句),我想补充一点,准确分析您试图清理/确保安全的价值总是很有用的


如果您的ID应该是一个整数,我只需使用
intval($\u POST['listid'])
来确保结果是一个整数,并为字符串保留
mysql\u real\u escape\u string
(尽管我个人会使用预处理语句/PDO)。

使用存储过程,只向您的app db用户授予执行权限(再加上存储过程带来的无数其他好处)

我总是在我的所有项目上使用数据库助手类。这样我就不必使用
mysql\u real\u escape\u string
保持代码干净易读如果你忘记使用它,你就不会被注射

下面是我使用的一个例子

<?php 
    final class DatabaseException extends Exception {
        function __construct($strErrMessage, $intErrCode) {
            parent::__construct($strErrMessage, $intErrCode);   
        }
    }

    class Database {
        protected $host     = ""; //database server
        protected $user     = ""; //database login name
        protected $pass     = ""; //database login password
        protected $database = ""; //database name
        protected $prefix   = ""; //table prefix        
        protected $connected = false;
        protected $db = null;   
        protected $record = array();
        protected $error = "";
        protected $errno = 0;

                //table name affected by SQL query
        protected $field_table= "";

        //number of rows affected by SQL query
        protected $affected_rows = 0;

        protected $link_id = 0;
        protected $query_id = array(); 

        function __construct($server, $user, $pass, $database, $pre='') {
            $this->connected = false;
            $this->host = $server;
            $this->user = $user;
            $this->pass = $pass;
            $this->database = $database;
            $this->prefix = $pre;
            $this->connect();
        }

        function __destruct() {
            //mysql_close($this->link_id); 
        }

        public function connect() {
            if ($this->link_id > 0 && $this->connected && mysql_ping($this->link_id)) { return; }

            $this->link_id = mysql_pconnect($this->host, $this->user, $this->pass);
            if (!$this->link_id) { //open failed
                throw new DatabaseException("mysql_pconnect failed",0);    
            }

            if(!@mysql_select_db($this->database, $this->link_id)) {//no database
                throw new DatabaseException("mysql_select_db failed",0); 
            }
            $this->server='';
            $this->user='';
            $this->pass='';
            $this->database=''; 
            $this->connected = true;
            $this->query("SET time_zone = '".Settings::get('db.timezone_offset')."';",TRUE);
        }

        public function escape($string) {
            if(get_magic_quotes_gpc()) 
                $string = stripslashes($string);
            return mysql_real_escape_string($string);
        }

        public function insert($table,$data,$tbl_key='id') {
            $v=''; 
            $n='';
            foreach($data as $key=>$val) {
                $n.="`$key`, ";
                if(strtolower($val)=='null') 
                    $v.="NULL, ";
                elseif(strtolower($val)=='now()') 
                    $v.="NOW(), ";
                elseif(strcmp(substr($val,0,7),'**ESC**') == 0) 
                    $v .= str_replace('**ESC**','',$val);
                else 
                    $v.= "'".$this->escape($val)."', ";
            }

            if ($v=='' || $n=='') 
                return false;

            $q  = "INSERT INTO `".$this->prefix.$table."` ";
            $q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";
            if($this->query($q)){
                $id=mysql_insert_id();
                if ($id === 0) {  // The ID generated for an AUTO_INCREMENT column by the previous INSERT query on success, 
                                  // 0 if the previous query does not generate an AUTO_INCREMENT value, or FALSE if no MySQL 
                                  // connection was established.
                    return TRUE;
                } 
                return $id;
            }
            else {
                return false;
            }
        }

        public function replace($table,$data,$tbl_key='id') {
            $v=''; 
            $n='';
            foreach($data as $key=>$val) {
                $n.="`$key`, ";
                if(strtolower($val)=='null') 
                    $v.="NULL, ";
                elseif(strtolower($val)=='now()') 
                    $v.="NOW(), ";
                elseif(strcmp(substr($val,0,7),'**ESC**') == 0) 
                    $v .= str_replace('**ESC**','',$val);
                else 
                    $v.= "'".$this->escape($val)."', ";
            }

            if ($v=='' || $n=='') 
                return false;

            $q  = "REPLACE INTO `".$this->prefix.$table."` ";
            $q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";

            if($this->query($q)){
                $id=mysql_insert_id();
                if ($id === 0) {  // The ID generated for an AUTO_INCREMENT column by the previous INSERT query on success, 
                                  // 0 if the previous query does not generate an AUTO_INCREMENT value, or FALSE if no MySQL 
                                  // connection was established.
                    return TRUE;
                } 
                return $id;
            }
            else {
                return false;
            }
        }

        public function update($table,$data,$where='1') {
            $q = "UPDATE `".$this->prefix.$table."` SET ";
            foreach($data as $key=>$val) {
                if(strtolower($val)=='null') $q .= "`$key` = NULL, ";
                elseif(strtolower($val)=='now()') $q .= "`$key` = NOW(), ";
                elseif(strcmp(substr($val,0,7),'**ESC**') == 0) $q .=  "`$key` = ".str_replace('**ESC**','',$val);
                else $q.= "`$key`='".$this->escape($val)."', ";
            }
            $q = rtrim($q, ', ') . ' WHERE '.$where.';';
            $result = $this->query($q); 

            if ($result) {
            }
            return $result;
        }

        public function search($table, $field, $value, $exact=FALSE)
        {
                    $value = escape($value);
            if (!$exact) {      
                $q = "select * from $table where $field like '%$value%';";
            } else {
                $q = "select * from $table where $field = '$value';";
            }
            return $this->query($q);
        }

        public function delete($table,$where='1') {
            $q  = "DELETE FROM `".$this->prefix.$table."` ";
            $q .= " WHERE ".$where.";";
            $result = $this->query($q);             

            if ($result) {
            }
        }

        public function query($sql,$reset=FALSE) {
            //echo "<pre>$sql</pre>";
            $this->connect();
            $command = strtok(trim($sql)," \n\t");
            switch (strtoupper(trim($command))) {
                case "SELECT":
                case "SHOW":
                case "DESCRIBE":
                case "EXPLAIN":
                    if (isset($this->query_id[md5($sql)]) && $reset==FALSE) {
                        $row = mysql_fetch_array($this->query_id[md5($sql)], MYSQL_ASSOC);
                        if ($row == FALSE) {
                            unset($this->query_id[md5($sql)]);
                            return FALSE;
                        } else {
                            return $row;
                        }
                    } else {    
                        $this->query_id[md5($sql)] = @mysql_query($sql, $this->link_id);
                        if (!$this->query_id[md5($sql)]) {
                            throw new DatabaseException(mysql_error($this->link_id),mysql_errno($this->link_id));
                        }
                    }
                    $row = mysql_fetch_array($this->query_id[md5($sql)], MYSQL_ASSOC);
                    if ($row == FALSE) {
                        unset($this->query_id[md5($sql)]);
                        return FALSE;
                    } else {
                        return $row;
                    }
                    break;
                default:
                    return @mysql_query($sql, $this->link_id);
                    break;
            }
        }
    }
?>
如果所有表单元素的名称都与表字段的名称相同,那么将数据从
$\u POST
获取到数据库中是非常简单的。例如:

mysql_query("DELETE FROM stage WHERE listid=".intval($_POST['listid']));
在这种情况下



完整参考资料:

因此,在我将其应用于站点的其余部分之前,上面的代码是100%没有问题的??也就是说,在实际降低系统安全性之后,放置
strip\u标记和
htmlspecialchars
。mysql\u real\u escape\u字符串函数的确切目的是引用分隔符,而不是其他内容。它非常cOmon不相信这个函数是与SQL inj.相关的。我只是一组语法规则的一部分。应该独立于SQL注入的可能性使用。当然。它不能保护任何东西,只能保护带引号的字符串。我发现这个术语更适合于数字转换。+1…好吧,或者,或者至少使
mysql\u real\u escape\u string
最外层的调用…@user:只需删除
strip_标记
htmlspecialchars
$deleteid=mysql_real_escape_string($\u POST['listid'];mysql_send(“DELETE FROM stage where listid='deleteid');
mysql_real_escape_string($\u POST['listid']))
应该足够了。或者如果你想使用
htmlspecialchars
strip\u标记(或任何其他函数),你应该转义它们的返回值:
mysql\u real\u escape\u string(htmlspecialchars(strip\u标记($\u POST['listid'))
没错……mysql_real_escape_string应该可以做到这一点。htmlspecialchars和strip_标记有助于防止XSS,而XSS不适用于您在这里展示的示例。但是编写糟糕的存储过程仍然会被注入,因为您可以通过字符串连接构建查询……所以这不是一个简单的“做到这一点,完成”过程…-1传播存储过程是防止SQL注入的神奇证据这一神话。请看你引用的一个WTF示例loolStored过程不会阻止注入,而且引用的WTF示例在这种情况下完全有意义。编写糟糕的WTF类型的存储过程不会阻止注入,因此如果可能的话,你可以避免编写任何-errrm,嗯。这就是我所说的“我在计算机科学课上是第一名,但什么都不懂”。如果所有表单元素的名称都与表字段的名称相同,那么将数据从$\u POST获取到数据库是非常简单的,并且如果您运行一个通用查询,只需使用escape($value)即可直接进入SQL注入,如果您的服务器运行的是较旧版本的PHP,这也可以保护您。哦,您是否也转义字段名?@Col.Shrapnel,不确定您的意思..update()转义$\u POST中的值在我的示例中,如果类有问题,请告诉我不,我不建议使用转义()在字段名上,这将毫无帮助。唯一可能的方法是显式枚举所有字段名。使用允许的字段名创建一个数组,并对照它检查POST输入。是的,这看起来很无聊,但这是唯一安全的方法
$db = new Database("db.host","db.user","db.pass","db.database");
$data = $_POST;
$ok = $db->update('mytable', $data, 'something = something_else'); //$ok will be false if something went wrong
mysql_query("DELETE FROM stage WHERE listid=".intval($_POST['listid']));