我这样做了吗?这有助于避免sql注入吗?
$deleteid = htmlspecialchars(strip_tags(mysql_real_escape_string($_POST['listid'])));
mysql_send("DELETE FROM stage where listid='$deleteid'");
答案 0 :(得分:13)
没有
你应该只打电话给mysql_real_escape_string
。
htmlspecialchars
和strip_tags
函数用于对要显示为HTML的字符串进行编码
它们不应该与SQL一起使用
答案 1 :(得分:8)
它可能会阻止SQL注入攻击,但它很难接近它。请改用prepared queries。
由于您的评论表明您正在系统地对整个网站进行更改,因此请采用更好的方法。如果您正在使用它,您可能希望转移到非MySQL特定的数据库API,以防您以后想要切换到另一个后端。
答案 2 :(得分:3)
除了上面提到的建议(仅mysql_real_escape_string
,但更好的预备语句),我想补充一点,确切地分析您要清理的值/总是有用的安全。
如果您的ID应该是一个整数,我只需使用intval($_POST['listid'])
来确保结果为整数并为字符串保留mysql_real_escape_string
(尽管我个人会使用预处理语句/ PDO)
答案 3 :(得分:2)
是的,对MySQL语句中的字符串声明中使用的值使用mysql_real_escape_string
将阻止您进行SQL注入。这就是该功能的确切目的。
但您不需要其他两个函数strip_tags
和htmlspecialchars
。因为这些函数用于删除(HTML)标记并分别用字符引用替换HTML特殊字符。它们不旨在保护您免受SQL注入。
事实上,在strip_tags
之后使用htmlspecialchars
和/或mysql_real_escape_string
可以在某些特定情况下打破转义(例如,当使用基于非US-ASCII的字符集时,请参阅{ {3}})。因此,请确保在将其返回值插入SQL语句之前使用该函数。
除了使用mysql_real_escape_string
对输出进行编码外,您还可以使用addslashes()
Versus mysql_real_escape_string()
验证输入:
if (ctype_digit($_POST['listid'])) {
mysql_send("DELETE FROM stage where listid='".$_POST['listid']."'");
} else {
// invalid value
}
此验证确保在查询中仅使用(正)整数值,不需要转义。
答案 4 :(得分:0)
我总是在我的所有项目中使用数据库助手类。这样我就不必使用mysql_real_escape_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;
}
}
}
?>
创建和使用数据库类:
$db = new Database("db.host","db.user","db.pass","db.database");
如果所有表单元素的名称与表字段相同,则将$_POST
中的数据导入数据库非常简单。例如:
$data = $_POST;
$ok = $db->update('mytable', $data, 'something = something_else'); //$ok will be false if something went wrong
答案 5 :(得分:0)
在这种情况下
mysql_query("DELETE FROM stage WHERE listid=".intval($_POST['listid']));
答案 6 :(得分:-1)
使用存储过程并仅向您的app db用户授予执行权限(以及sprocs带来的无数其他好处)