如何防止在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 me
function要小心,可能会显示一些警告。 - 当用户login时(或者其他适当的话)刷新会话ID
- 超时非活动会话
- 切勿在cookie外面暴露用户的
- 永远不要相信一个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() 。 这是因为“危险的”字符对于每一个字符都是不同的 – 没有一种方法可以使任何输出媒体的数据安全。