有效地清理用户输入的文本 [英] Efficiently sanitize user entered text

查看:75
本文介绍了有效地清理用户输入的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个html表单,可以接受用户输入的大小约为1000的文本,并将其提交到php页面,并将其存储在mysql数据库中.我将PDO与准备好的语句一起使用,以防止sql注入.但是要清理用户输入的文本,需要做的最大努力是什么?

I have a html form that accepts user entered text of size about 1000, and is submitted to a php page where it will be stored in mysql database. I use PDO with prepared statements to prevent sql injection. But to sanitize the text entered by user, what are the best efforts needed to do ?

我想防止任何脚本注入,xss攻击等.

I want to prevent any script injection, xss attacks, etc.

推荐答案

安全性是一个有趣的概念,吸引了很多人.不幸的是,这是一个复杂的主题,甚至专业人士都将其弄错了.我在Google(CSRF),Facebook(更多CSRF),几家主要的在线零售商(主要是SQL Injection/XSS)以及数千个公司和个人小型站点中发现了安全漏洞.

Security is an interesting concept and attracts a lot of people to it. Unfortunately it's a complex subject and even the professionals get it wrong. I've found security holes in Google (CSRF), Facebook (more CSRF), several major online retailers (mainly SQL injection / XSS), as well as thousands of smaller sites both corporate and personal.

这些是我的建议:

1)使用参数化查询
参数化查询强制将传递给查询的值视为单独的数据,因此DBMS无法将输入值解析为SQL代码.很多人会建议您使用mysql_real_escape_string()来转义字符串,但是与普遍的看法相反,不是不是SQL注入的万能解决方案.以以下查询为例:

1) Use parameterised queries
Parameterised queries force the values passed to the query to be treated as separate data, so that the input values cannot be parsed as SQL code by the DBMS. A lot of people will recommend that you escape your strings using mysql_real_escape_string(), but contrary to popular belief it is not a catch-all solution to SQL injection. Take this query for example:

SELECT * FROM users WHERE userID = $_GET['userid']

如果将$_GET['userid']设置为1 OR 1=1,则没有特殊字符,并且不会对其进行过滤.这将导致返回所有行.或者,更糟糕的是,如果将其设置为1 OR is_admin = 1呢?

If $_GET['userid'] is set to 1 OR 1=1, there are no special characters and it will not be filtered. This results in all rows being returned. Or, even worse, what if it's set to 1 OR is_admin = 1?

参数化查询可防止发生这种注入.

Parameterised queries prevent this kind of injection from occuring.

2)验证您的输入
参数化查询很好,但是有时意外的值可能会导致代码出现问题.确保您正在验证它们是否在范围之内,并且它们不允许当前用户更改他们不应该做的事情.

2) Validate your inputs
Parameterised queries are great, but sometimes unexpected values might cause problems with your code. Make sure that you're validating that they're within range and that they won't allow the current user to alter something they shouldn't be able to.

例如,您可能具有密码更改表单,该表单将POST请求发送到更改其密码的脚本.如果您将其用户ID作为隐藏变量放置在表单中,则他们可以更改它.发送id=123而不是id=321可能意味着他们更改了他人的密码.确保在类型,范围和访问权限方面对所有内容进行了正确的验证.

For example, you might have a password change form that sends a POST request to a script that changes their password. If you place their user ID as a hidden variable in the form, they could change it. Sending id=123 instead of id=321 might mean they change someone else's password. Make sure that EVERYTHING is validated correctly, in terms of type, range and access.

3)使用htmlspecialchars转义显示的用户输入
假设您的用户输入关于我"的信息是这样的:
</div><script>document.alert('hello!');</script><div>
问题是您的输出将包含用户输入的标记.尝试用黑名单自己过滤掉这是一个坏主意.使用htmlspecialchars过滤掉字符串,以便将HTML标签转换为HTML实体.

3) Use htmlspecialchars to escape displayed user-input
Let's say your user enters their "about me" as something like this:
</div><script>document.alert('hello!');</script><div>
The problem with this is that your output will contain markup that the user entered. Trying to filter this yourself with blacklists is just a bad idea. Use htmlspecialchars to filter out the strings so that HTML tags are converted to HTML entities.

4)不要使用$ _REQUEST
跨站点请求伪造(CSRF)攻击的工作原理是,使用户单击链接或访问表示代表在他们登录的网站上执行操作的脚本的URL.$_REQUEST变量是$_GET$_POST$_COOKIE,这意味着您无法区分POST请求中发送的变量(即通过表单中的input标记)或设置为您的网址作为GET的一部分(例如page.php?id=1).

4) Don't use $_REQUEST
Cross-site request forgery (CSRF) attacks work by getting the user to click a link or visit a URL that represents a script that perfoms an action on a site for which they are logged in. The $_REQUEST variable is a combination of $_GET, $_POST and $_COOKIE, which means that you can't tell the difference between a variable that was sent in a POST request (i.e. through an input tag in your form) or a variable that was set in your URL as part of a GET (e.g. page.php?id=1).

比方说,用户希望向某人发送私人消息.他们可能将tosubjectmessage作为参数将POST请求发送到sendmessage.php.现在,让我们想象有人发送了GET请求:

Let's say the user wants to send a private message to someone. They might send a POST request to sendmessage.php, with to, subject and message as parameters. Now let's imagine someone sends a GET request instead:

sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!

如果使用的是$_POST,则不会看到任何这些参数,因为它们是在$_GET中设置的.您的代码看不到$_POST['to']或任何其他变量,因此它不会发送消息.但是,如果使用$_REQUEST,则$_GET$_POST会卡在一起,因此攻击者可以将这些参数设置为URL的一部分.当用户访问该URL时,他们无意间发送了该消息.真正令人担忧的部分是用户无需执行任何操作.如果攻击者创建了一个恶意页面,则该页面可能包含指向该URL的iframe.示例:

If you're using $_POST, you won't see any of those parameters, as they are set in $_GET instead. Your code won't see the $_POST['to'] or any of the other variables, so it won't send the message. However, if you're using $_REQUEST, the $_GET and $_POST get stuck together, so an attacker can set those parameters as part of the URL. When the user visits that URL, they inadvertantly send the message. The really worrysome part is that the user doesn't have to do anything. If the attacker creates a malicious page, it could contain an iframe that points to the URL. Example:

<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!">
</iframe>

这导致用户向人们发送消息而从未意识到他们做了任何事情.因此,应避免使用$_REQUEST,而应使用$_POST$_GET.

This results in the user sending messages to people without ever realising they did anything. For this reason, you should avoid $_REQUEST and use $_POST and $_GET instead.

5)将您得到的一切都视为可疑(甚至恶意)
您不知道用户向您发送了什么.这可能是合法的.可能是攻击.永远不要相信用户发送给您的任何信息.转换为正确的类型,验证输入,必要时使用白名单进行过滤(避免使用黑名单).这包括通过$_GET$_POST$_COOKIE$_FILES发送的任何内容.

5) Treat everything you're given as suspicious (or even malicious)
You have no idea what the user is sending you. It could be legitimate. It could be an attack. Never trust anything a user has sent you. Convert to correct types, validate the inputs, use whitelists to filter where necessary (avoid blacklists). This includes anything sent via $_GET, $_POST, $_COOKIE and $_FILES.



如果遵循这些准则,则在安全性方面您将处于合理的位置.



If you follow these guidelines, you're at a reasonable standing in terms of security.

这篇关于有效地清理用户输入的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆