如何防止在PHP中的代码注入攻击?

我很混乱,PHP中有这么多函数,有些使用这个,有些使用这个函数。 有些人使用: htmlspecialchars()htmlentities()strip_tags()

哪一个是正确的,你们通常使用什么?

这是正确的(build议我一个更好的,如果有的话):

 $var = mysql_real_escape_string(htmlentities($_POST['username'])); 

这一行可以防止MySQL注入和XSS的攻击

顺便说一下,除了XSS攻击和MySQL注入之外,还有什么其他的事情需要注意吗?

编辑

总结:

如果我想插入string到数据库,我不需要使用htmlentities ,只需使用mysql_real_escape_string 。 当显示数据时,使用htmlentities() ,这是你所有的意思?

总结:

  • 插入数据库时​​使用的mysql_real_escape_string
  • htmlentities()数据输出到网页时使用的htmlentities()
  • htmlspecialchars()用什么时候?
  • strip_tags()用于什么时候?
  • addslashes()使用什么时候?

有人可以填写问号吗?

 mysql_real_escape_string used when insert into database htmlentities() used when outputting data into webpage htmlspecialchars() used when?? strip_tags() used when ?? addslashes() used when ?? 

htmlspecialchars()用什么时候?

htmlspecialchars与htmlentities大致相同。 区别:字符编码。

都编码控制字符,如<> ,等等用于打开标签等htmlentities也编码其他语言,如变音符号,欧元符号等字符。 如果你的网站是utf,请使用htmlspecialchars(),否则使用htmlentities()。

strip_tags()用于什么时候?

htmlspecialchars /实体编码特殊字符,所以他们显示,但不解释 。 strip_tags删除它们。

在实践中,这取决于你需要做什么。

一个例子…你已经编写了一个论坛,并给用户一个文本字段,所以他们可以发布的东西。 恶意的只是尝试

 pictures of <a href="javascript:void(window.setInterval(function () {window.open('http://evil.com');}, 1000));">kittens</a> here 

如果你什么都不做,链接将被显示,点击链接的受害者会得到很多popup窗口。

如果你的输出是htmlentitiy / htmlspecialchar,文本将会按原样存在。 如果你strip_tag它,它只是删除标签,并显示它:

 pictures of kittens here 

有时你可能想要一个混合,在那里留下一些标签,如<b> (strip_tags可以在那里留下一定的标签)。 这也是不安全的,所以最好使用一些对xss的完整库

和addslashes

引用php手册:

这些字符是单引号('),双引号(“),反斜杠()和NUL(NULL字节),在需要在数据库查询中引用的字符之前返回带有反斜杠的string。

addslashes()的一个使用示例是将数据input到数据库中。 例如,要将O'reilly的名字插入到数据库中,您需要将其转义。 强烈build议使用DBMS特定的转义函数(例如MySQL的mysqli_real_escape_string()或PostgreSQL的pg_escape_string()),但是如果您使用的DBMS没有转义函数,并且DBMS使用\转义特殊字符,可以使用这个function。

只有在进入系统时才对数据进行编码,需要进行编码 – 否则会遇到您想操纵实际数据的情况。

对于SQL注入 – 使用绑定variables, 如何在PHP中防止SQL注入? (它谈论准备好的陈述,但它是给你保护的约束,而不是准备)。

对于XSS – 如果您在指定HTML或文本的位置写入HTML。 在生成文档的地方使用htmlentities。 我会避免将数据以这种forms存储在数据库中(除非在CPU性能/磁盘访问时间变得越来越长的情况下经常使用的写 – 罕见读系统中),那么我将拥有该列的raw_和html_版本…或者只是使用memcached或类似的)。

如果您让用户inputurl,那么您需要更加小心,因为javascript:do_evil()是一个有效的URI,它将被执行(例如,作为点击链接的href或者在某些浏览器中的图像的src刚刚加载)。

插入到数据库中时只需要使用mysql_escape_string(),而在显示HTML时只需使用htmlentites。 如果要防止简单的注入攻击,这就足够了,但毫无疑问,在开发Web应用程序时,您应该了解许多其他安全问题,而另一个主要问题是跨站请求伪造。

htmlspecialchars()将&,',“,<和>转换为HTML实体格式(&,”等)

htmlentities()将所有适用的字符转换成它们的HTML实体格式。

strip_tags()删除所有的HTML和PHP标签。

htmlspecialchars()和htmlentities()都带有一个可选参数,指出应该如何处理引号。 有关详细信息,请参阅PHP手册。

strip_tags()函数带有一个可选的参数,指出哪些标签不应该被剥离。

  $var = strip_tags ($var, '<p><br />'); 

strip_tags()函数将删除无效的HTML标记,这可能会导致问题。 例如,strip_tags()会将所有认为是HTML标签的代码抽出,即使它不正确的形成

 <b I forgot to close the tag. 

我想到了这个快速清单:

  • 总是使用HTTPS,没有HTTPS您的站点是完全未encryption的 。 不,客户端encryption和发送它们将不起作用,请仔细考虑。 无效的HTTPS证书也使您易受MITM攻击 。 如果你买不起证书,只需使用Let's Encrypt即可。
  • 总是在PHP代码的任何输出上使用htmlescapechars(),也就是包含用户input 。 大多数模板引擎可以帮助您轻松完成。
  • 在您的php.ini使用仅限HTTP的标志来防止脚本访问您的Cookie
  • 防止与会话相关的问题
    • 切勿在cookie外面暴露用户的PHPSESSID (会话ID) ,如果有人知道别人的会话ID,他们可以简单地使用它login到他们的帐户
    • Remember mefunction要小心,可能会显示一些警告。
    • 当用户login时(或者其他适当的话)刷新会话ID
    • 超时非活动会话
  • 永远不要相信一个cookie,它可以随时被脚本/用户改变,删除,修改和创build
  • 防止与SQL相关的问题
    • 始终使用准备好的语句 准备语句导致用户input分开传递,并防止SQL注入
    • 当你的代码失败时抛出一个exception。 有时你的SQL服务器可能由于某种原因而closures,像PDO这样的库默认情况下忽略这个错误,并在日志中logging一个警告。 这会导致从DB获得的variables为空,这取决于您的代码,这可能会导致安全问题。
    • 一些类似PDO图书馆模拟了准备好的陈述。 把它关掉。
    • 在您的数据库中使用UTF-8编码,它允许您存储几乎任何字符,并避免编码相关的攻击
    • 不要连接任何东西到您的查询 。 像$myquery = "INSERT INTO mydb.mytable (title) VALUES(" . $user_input . ")"几乎意味着你有一个SQL注入的巨大安全风险。
  • 以随机,扩展名文件名的forms存储上传的文件。 如果用户使用.php文件扩展名上传一个文件,那么无论何时您的代码加载该文件,它都会执行该文件,并且允许用户执行一些后端代码
  • 确保你不容易受到CSRF攻击。
  • 始终更新您的PHP副本,以确保最新的安全补丁和性能改进

看看这个网站PHP安全联盟 。 我发现它是一个很好的网站,全面了解PHP安全(包括SQL注入和XSS)。

在将数据插入数据库或查询数据库时,我不会使用htmlentities()。 如果你数据库中的数据是作为实体存储的,那么这些数据只能用于理解html实体的东西。

对于不同types的输出,你必须使用不同的转义机制,例如SQL – mysql_real_escape_string() ,HTML – htmlentities()或htmlspecialchars() ,shell – escapeshellarg() 。 这是因为“危险的”字符对于每一个字符都是不同的 – 没有一种方法可以使任何输出媒体的数据安全。