如果 Web 应用程序获取用户输入或参数,我们在验证时应该做哪些必要且最重要的事情?

发布于 2024-09-28 13:56:51 字数 292 浏览 1 评论 0原文

我总是在考虑网页上任何类型的验证(PHP 或 ASP,这并不重要),但从未找到好的、准确的答案。

例如,我有一些 GET 参数,它定义了一个 SQL 查询,如 DESC 或 ASC。 (SQL-Injection?)

或者我有一个用户注释功能,其中数据也保存在数据库中。

检查数据中的 HTML 标签是否足够?在将其添加到数据库或将其显示在页面上之前是否应该进行验证?

我正在寻找应该始终使用“外部”给出的任何数据执行的待办事项。

谢谢。

I am always thinking about validation in any kind on the webpage (PHP or ASP, it doesn't matter), but never find a good and accurate answer.

For example, a I have some GET-Parameter, which defines a SQL query like DESC oder ASC. (SQL-Injection?)

Or I have a comment-function for user, where the data is also saved in a database.

Is it enought to check for HTML-tags inside the data? Should the validation done before adding it to the database or showing it on the page?

I am searching for the ToDo's which should be always performed with any data given from "outside".

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

表情可笑 2024-10-05 13:56:51

清楚地了解您想从用户那里得到什么。

您希望他们指定升序/降序吗?这是一个枚举(或布尔值),而不是 SQL 查询的一部分:

$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong

无论您如何转义和清理其字符串,这都是错误的,因为这不是验证枚举的方法。比较:

if ($_GET['sortOrder'] == 'desc') {
    $ascending = false;
} else {
    $ascending = true;
}

if ($ascending) {
    ...
} else {
    ...
}

...这并不值得讨论字符串转义或 SQL 注入,因为您想要从用户那里得到的只是是/否(或升序/降序)答案。

您希望他们发表评论吗?为什么不允许 HTML 标签?如果用户想要输入 HTML 代码怎么办?

同样,您想要从他们那里得到的是“文本...任何最大长度为 1024 个字符的文本*”。这与 SQL 或注入有什么关系? Nothing:

$text = $_POST['commentText'];

if (mb_strlen($text, ENCODING) <= 1024) {
    //valid!
}

数据库中的值应反映用户逐字输入的内容;没有翻译,没有逃脱。假设您要删除所有 HTML从评论中。当您决定以 JSON 格式发送评论时会发生什么?您是否也会删除 JSON 控制字符?那么其他格式呢?如果 HTML 引入一个名为“:)”的标签会发生什么?您是否在数据库中四处走动,从所有评论中删除表情符号?

答案是否定的,因为您不希望用户输入 HTML 安全、JSON 安全、某种奇怪格式和笑脸安全的输入。您需要最多 1024 个字符的文本。检查一下。存储它。

现在,显示部分更加棘手。为了显示:

<b>I like HTML "tags"

在 HTML 中,您需要编写如下内容:

<b>I like HTML "tags"

在 JSON 中,您会这样做:

{ "I like HTML \"tags\" }

这就是为什么您应该在使用数据时使用语言工具来转义数据

当然,对于 SQL 也是如此,这就是为什么在 PHP 中使用简单的查询函数(例如 mysql_query())时应该转义数据。 (另一方面,您应该真正使用的参数化查询不需要转义。)

总结

非常清楚您想要什么作为输入,请记住您几乎永远不需要“HTML 安全”文本。”对此进行验证。需要时转义,这意味着在发送到浏览器时转义 HTML,在发送到数据库时转义 SQL,等等。


*:您还应该在这里定义“字符”的含义。例如,UTF-8 可以使用多个字节来编码一个代码点。 “字符”是指“字节”还是“Unicode 代码点”?

Have a good idea of what you want from the user.

You want them to specify ascending/descending order? That's an enumeration (or a boolean), not part of an SQL query:

$query = "SELECT [...] ORDER BY field " . escape($_GET['sortOrder']); //wrong

This is wrong no matter how much you escape and sanitize their string, because this is not the way to validate an enumeration. Compare:

if ($_GET['sortOrder'] == 'desc') {
    $ascending = false;
} else {
    $ascending = true;
}

if ($ascending) {
    ...
} else {
    ...
}

...which does not warrant a discussion of string escaping or SQL injection because all you want from the user is a yes/no (or ascending/descending) answer.

You want them to enter a comment? Why disallow HTML tags? What if the user wants to enter HTML code?

Again, what you want from them is, say, "a text... any text with a maximum length of 1024 characters*." What does this have to do with SQL or injection? Nothing:

$text = $_POST['commentText'];

if (mb_strlen($text, ENCODING) <= 1024) {
    //valid!
}

The value in the database should reflect what the user entered verbatim; not translated, not escaped. Say you're stripping all HTML <tags> from the comment. What happens when you decide to send comments somewhere in JSON format? Do you strip JSON control characters as well? What about some other format? What happens if HTML introduces a tag called ":)"? Do you go around in your database stripping off smileys from all comments?

The answer is no, as you don't want HTML-safe, JSON-safe, some-weird-format-with-smileys-safe input from the user. You want text that is at maximum 1024 characters. Check for that. Store that.

Now, the displaying part is trickier. In order to display:

<b>I like HTML "tags"

in HTML, you need to write something like:

<b>I like HTML "tags"

In JSON, you would do:

{ "I like HTML \"tags\" }

That is why you should use your language facilities to escape the data when you're using it.

The same of course goes for SQL, which is why you should escape the data when using simple query functions like mysql_query() in PHP. (Parametrized queries, which you should really be using, on the other hand, need no escaping.)

Summary

Have a really good idea of what you want as the input, keeping in mind that you almost never need, say, "HTML-safe text." Validate against that. Escape when required, meaning escape HTML as you send to the browser, SQL as you send to the database, and so on.


*: You should also define what a "character" means here. UTF-8, for example, may use multiple bytes to encode a code point. Does "character" mean "byte" or "Unicode code point"?

阿楠 2024-10-05 13:56:51

如果您使用 PDO,请务必使用准备好的语句 - 这些语句会自动清理传入的数据。

如果使用 mysql_* 函数,请首先通过 mysql_real_escape_string 运行每个变量。

您还可以进行验证,例如确保变量是可接受的范围之一:

$allowed_values = array('name', 'date', 'last_login')
if(in_array($v, $allowed_values)) {
    // now we can use the variable
}

If you're using PDO, be sure to use prepared statements - these clean the incoming data automatically.

If using the mysql_* functions, run each variable through mysql_real_escape_string first.

You can also do validation such as making sure the variable is one of an acceptable range:

$allowed_values = array('name', 'date', 'last_login')
if(in_array($v, $allowed_values)) {
    // now we can use the variable
}
故事未完 2024-10-05 13:56:51

您正在谈论两种数据清理。一种是将用户生成的数据放入数据库中,另一种是将用户生成的数据放入网页中。对于前者,您应该遵循 Adam 的建议。对于后者,您应该查看 htmlspecialchars

不要混合这两者,因为它们做两种完全不同的事情。为此目的,卫生只能在最后一刻进行。在更新数据库之前使用 Adam 的建议。在回显数据之前使用 htmlspecialchars。在将数据添加到数据库之前,请勿对数据使用 htmlspecialchars。

您可能还想看看 Stackoverflow,因为此类问题在过去已经被问过无数次并得到了回答。

You are talking about two kinds of data sanitation. One is about putting user-generated data in your database and the other is about putting user-generated data on your webpage. For the former you should follow adam's suggestions. For the later you should look into htmlspecialchars.

Do not mix these two as they do two completely different things. For that purpose sanitation should only take place at the last moment. Use adam's suggestion just before updating the database. Use htmlspecialchars just before echoing data. Do not use htmlspecialchars on data before adding it to the database.

You might also want to look around Stackoverflow, because this sort of question has been asked and answered countless times in the past.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文