2013-05-20 35 views
1

我一直用我的网站上这段代码很长一段时间,而只是想确保我正确sanatizing我的PHP $_POST输入...

foreach($_POST as $key=>$val) //this code will sanitize your inputs. 
    $_POST[$key] = mysqli_real_escape_string($connection, $val); 

说,例如我有岗位价值$_POST['comment']那我想添加到数据库中,这是否是在数据库输入之前将其进行sanatize的好方法?

foreach($_POST as $key=>$val) //this code will sanitize your inputs. 
    $_POST[$key] = mysqli_real_escape_string($connection, $val); 

    //is this safe? or is there another step? 
    $comment = $_POST['comment']; 

    if($comment != ""){ 
    //add $comment to database 
    } 

有什么事,我还需要添加$comment到MySQL数据库之前做?或者那些最上面的两行自己做魔术?请让我知道这是否是一种安全的方法,或者如果有更好的方法!谢谢!

+0

用户编写查询,用户输入更安全的处理 – samayo

+2

一定要使用的方法制得的语句(http://stackoverflow.com/a/60496) – HamZa

回答

2

的可能重复:https://stackoverflow.com/questions/15664021/php-escaping-vars-posted-through-var-and-got-by-postvari-with-a-meth

我已经尝试过你的方式。看起来没有魔术功能。然而,从传统的MySQL注入,你可以是安全的,当添加mysqli_real_escape_string到每个张贴的值,然后用它作为一个字符串(引号)在分贝,但它被认为是不好的做法,也不是最安全的方式

由于MySQLi提供了参数化查询,因此您应该熟悉它们,并将与数据库驱动程序相对应的实际内容留给库。

+0

有帮助,谢谢!我会做一些研究!对于参数化查询,我将在1分钟内接受答案 – pattyd

+0

+1。手动调用转义函数是一个表明你做错了什么的标志。 – tadman

0

_real_escape_string不会完全清理用户输入。您必须使用准备好的语句。

面向对象的风格

$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); 
$stmt->bind_param('sssd', $code, $language, $official, $percent); 

$code = 'DEU'; 
$language = 'Bavarian'; 
$official = "F"; 
$percent = 11.2; 

程序风格

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); 
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent); 

$code = 'DEU'; 
$language = 'Bavarian'; 
$official = "F"; 
$percent = 11.2; 

参数类型

Character  Description 
i corresponding variable has type integer 
d corresponding variable has type double 
s corresponding variable has type string 
b corresponding variable is a blob and will be sent in packets

Documentation

+1

'mysql_real_escape_string',而丑陋,过时,技术上是否正确地消毒他们。 – tadman

+0

好的谢谢!!!! – pattyd

+0

@tadman [不依据此](http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html) – Kermit

0

不好的一面在于,你会滥用后变量,所以你不能将它们用于查询之外的其他目的。例如,如果你仍然想回应一些后变量呢?

更好的是逃避到一个新的数组

,甚至更好的是没能逃脱,但使用参数化查询。

1

不是。人们可以使用multibyte攻击,这将绕过所有这些消毒杀菌剂。

此外,

根据this answer应避免书写张贴这样一个可以保持消毒代码未消毒远。即使你“消毒”了一切,也会导致不良的习惯。

1

这不是清理输入的好方法。查询应该参数化,输入应该作为参数提供,不管它来自哪里。不应该做额外的卫生设施(否则可能会重复)。

如果您有具体的规则(如$comment != "")这是验证,它是由你来决定验证规则,以及如何处理无效的输入(比unsanitized输入不同)。

使用适当的参数准备语句mysqli的示例:

$stmt = mysqli_prepare($connection, "INSERT INTO comments VALUES (?)"); 
mysqli_stmt_bind_param($stmt "s", $comment); 
mysqli_execute($stmt); 
+3

这里需要注意的是,只有在查询执行时才进行消毒处理。做得过早会导致各种问题。 – tadman

+0

@tadman我没有这样做,但重要的是要强调它 –

+0

@tadman Noob的问题,但你说使用像filter_var这样的函数不是一个安全的PHP的“良好做法”?如果你可以看看我的答案,并评论它会很好。 –

0

你缺少一些对安全的PHP代码中最重要的事情。

让我们从头开始。

开始与这些链接请:请阅读代码评论

This first // and this second!

1)验证,然后如果通过验证筛选您的数据!

所以我们有一个注册表格,一个需要电子邮件......所以现在我们要做的就是验证电子邮件。

$email = $_POST['email']; // Declare the variable 
if (filter_var($email, FILTER_VALIDATE_EMAIL)) { // If validation passes ... 
    $safe_email = filter_var($email, FILTER_SANITIZE_EMAIL) // Sanitize the email 
} else { // Validation fails no need to sanitize 
    echo "WRONG EMAIL PUNK!!!!"; 
} 

2)现在无论是使用的mysqli或PDO(我宁愿PDO),我们这样做:

$dbh = new PDO("mysql:host=xxxxxx;dbname=xxxxxx;charset=utf8", USERNAME(XXXXXXXXX), PASSWORD(XXXXXXXX); // Set up the PDO instance PLEASE DO NOT FORGET TO EXPLICETELY STATE A CHARSET!!!! 
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set up error mode 
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); // I prefer emulate prepares to be false 

$sql = INSERT INTO ..... (........., email) VALUES (............, :email); // Set up our named parameter 
$query -> $dbh -> prepare($sql); // Prepare the query 
$query -> bindParam (':email', $email); 
$query -> execute() // Yay! 

其所有罚款和花花公子使用PDO与mysqli的,但有一个叫做表达式:

Its not the wand, its the wizard. 

PDO/MysqlI无法解决所有问题!确保

Refer to my other question on how to set up PDO

1)验证 2)消毒 3)使用参数查询的安全性! 4)逃脱任何外部(不可信数据)

遵循这些安全的PHP实践更安全的PHP编码。

享受

+0

这里有很多内容是不使用正确的ORM的反模式。数据验证应以一致的方式进行,并封装在适当的结构中以便可重复使用。像'filter_var($ email,...)'这样的代码行并不是一个可移植的方式。至少你已经正确设置了PDO,并且正在使用指定的占位符功能来清楚地表明在执行时正确地转义了所有内容。 – tadman

+0

那么正确的方法是创建这样的函数,不是吗?我只是问,因为你似乎更了解filter_var函数。 –

+0

正确的方法是使用ORM并具有一致的可测试方法来清理,验证和持久化用户输入。编写任意函数来清理事物只会适用于微不足道的程序。比这更大的任何东西都需要更多的结构,而ORM提供了这种结构。有很多可供选择的。选择一个适合您的需求。 – tadman

相关问题