您如何解析用户输入?
考虑以下场景: http://www.yourdomain.com/Default.aspx?p=2
现在我们当然要检查查询字符串参数 p 是否不包含错误。 我现在有这样的设置:
1)检查p是否存在
2)从p的值中过滤出html
3)htmlencode p的值
4)检查p是否为整数
5)检查p的整数是否存在于db中
这就是我通常这样做的方式第 5 步当然会影响性能。
亲切的问候, 标记
Consider the following scenario:
http://www.yourdomain.com/Default.aspx?p=2
Now we ofcourse want to check if the querystring parameter p doesnt contain errors.
I now have this setup:
1) Check if p exists
2) Filter out html from p's value
3) htmlencode p's value
4) check if p is integer
5) check if p's integer exists in db
This is how I usual do it, though step 5 is ofcourse a performance hit.
Kind regards,
Mark
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我的观点:通常这种类型的查询字符串参数并不是由用户真正“输入”的,而是作为链接提交的。因此,过于复杂的缓慢验证并不是真正必要的。
因此,我会将其传递到持久性/数据层,并根据我正在使用的系统类型,处理作为常规 404 Not Found 或 500 Internal Server Error 返回的任何错误。
My view: Generally a querystring parameter of this kind isn't really "entered" by users but is submitted as a link. So over-complex slow validation isn't really necessary.
So I would just pass this through to the persistence / data layer and handle any errors that come back as a regular 404 Not Found or 500 Internal Server Error depending on the kind of system I'm working with.
如果您的目的是使用参数从数据库中检索某些内容,为什么要过滤掉 html 或对其进行编码呢?这不像您要将其存储在数据库中,或将其显示在前端。如果存在的话,立即将其扔给 DAL。您的 DAL 应该足够聪明,可以告诉您它是否无法检索具有该 ID 的记录,或者该 ID 是否无法解析,等等。
If your intent is to use the parameter to retrieve something from the database, why filter out html or encode it? It's not like you're going to store it in the database, or display it on the front end. Just immediately throw it to the DAL if it exists. You're DAL should be smart enough to tell you if it failed to retrieve a record with that ID, or if the ID couldn't be parsed, etc..
如果您无论如何都要将输入转换为整数,则不需要步骤 2 和 3 - 只需使用
int.TryParse
来查看您拥有的内容。仅当您期望在动态 sql 语句中使用或将在您的网站上显示的字符串时,我才会对 html 输入进行编码和测试If you are going to convert the input to an integer anyway, then steps 2 and 3 are not needed - just use
int.TryParse
to see what you have. I would encode and test the input for html only if you are expecting a string which you will use in a dynamic sql statement, or will be displaying on your site怎么样:
What about:
很简单。对于大多数数据类型(整数、小数、双精度数、日期和布尔值),都有非常严格的格式。如果该值不能在严格格式下解析,则会出现错误。
字符串有时具有严格的格式,例如电子邮件地址或电话号码。这些可以通过简单的正则表达式进行验证。如果符合就使用,否则报错。
然而,大多数情况下,字符串只需要保存到数据库中,然后再次显示即可。在这种情况下,除了插入数据库时的转义(如果使用参数化查询也不需要)和渲染到显示器时的 HTML 编码之外,不需要任何处理。
这样,所有数据都会得到验证,并且不存在任何注入的风险。
字符串松散格式的罕见例外是……很少见。我现在想不出任何办法。为此,您可以进行一些更广泛的解析和处理。
添加:哦,是的,检查 ID(或其他值)对于数据库是否有效。你做得对,但想想你是否总是需要它。通常,您可以将检查放入您无论如何都必须执行的其他查询中。就像根据 ID 选择数据一样,您不需要显式检查它是否存在 - 只需准备好您的查询不会返回任何数据。
有时您根本不需要使用该值,那么您可以简单地忽略它。
但是,当然,还有其他时候,例如插入/更新数据时,您确实需要显式检查数据是否存在并且在当前上下文中是否有效。
Quite simple. For most data types (integers, decimals, doubles, dates and booleans) there is a very strict format. If the value does not parse under the strict format, it's an error.
Strings sometimes have a strict format, like an email address or a phone number. Those can be validated with a simple regexp. If it conforms, use it, otherwise it's an error.
Most of the time however strings will simply need to be persisted to the DB and later displayed again. In that case no processing is needed, aside from escaping when inserting into DB (unnecessary as well if you used parametrized queries)k, and HTML-encoding when rendering to the display.
This way any and all data is validated, and there is no risk of any injections whatsoever.
The rare exception of a loose format for a string is, well... rare. I can't think of any right now. For that you can afford some more extensive parsing and processing.
Added: Oh, yes, checking whether IDs (or other values) are valid in respect to a DB. You're doing it right, but think if you always need it. Quite often you can put the check into some other query that you have to do anyway. Like when you select data based on the ID, you don't need to explicitly check that it exists - just be ready that your query can return no data.
Sometimes you don't need to use the value at all, then you can simply ignore it.
But, of course, there are other times, like when inserting/updating data, that you indeed need to explicitly check whether the data exists and is valid in the current context.