为什么客户端验证还不够?

Why is client-side validation not enough?

提问人:Misha Moroshko 提问时间:8/14/2010 最后编辑:Misha Moroshko 更新时间:8/10/2013 访问量:13206

问:

我在这里看到:

您可能已经知道,依靠 仅在客户端验证上就是一个 非常糟糕的主意。始终执行 适当的服务器端验证 井。

您能解释一下为什么服务器端验证是必须的吗?

服务器 端客户端 验证

评论

18赞 Noon Silk 8/14/2010
将客户端验证视为为用户提供的便利。服务器端验证是您实际执行验证的地方。
2赞 David Thomas 8/14/2010
可能值得您阅读有关此 SO 主题的一些答案:stackoverflow.com/questions/1726617/......
14赞 Pascal Thivent 8/14/2010
一句话:不要相信客户。为什么?因为你不能。
0赞 Vitalii Fedorenko 4/28/2015
服务器端安全性的客户端强制执行是常见的软件弱点之一 cwe.mitre.org/data/definitions/602.html
0赞 Wildcard 12/15/2017
security.stackexchange.com/a/175472/96753

答:

66赞 Pekka 8/14/2010 #1

客户端验证 - 我假设您在这里谈论的是网页 - 依赖于 JavaScript

JavaScript 支持的验证可以在用户的浏览器中关闭,由于脚本错误而失败,或者不费吹灰之力就被恶意规避。

此外,提交表单的整个过程都可以伪造。

因此,永远无法保证到达服务器端的是干净和安全的数据。

评论

1赞 grilix 8/15/2010
它适用于所有有客户端的东西,例如在线游戏,因此,正如@Pascal所说,您不能信任客户端。而且,就网页而言,它们最容易伪造=/
13赞 Paul Creasey 8/14/2010 #2

任何了解基本 JavaScript 的人都可以绕过客户端。

客户端只是用来提升用户体验(无需重新加载页面进行验证)

6赞 Brian Agnew 8/14/2010 #3

在不特定于 Javascript 和 Web 客户端的情况下,为了更广泛地解决这个问题,服务器应该负责维护自己的数据(与底层数据库一起)。

在客户端-服务器环境中,服务器应该准备好接受许多不同的客户端实现可能与之通信的事实。考虑一个贸易准入系统。客户端可以是 GUI(例如交易输入系统)和(例如)数据上传客户端(从.csv文件加载多个交易)。

客户端验证可能以多种不同的方式执行,但并非所有方式都正确。因此,服务器不必信任客户端数据并自行执行完整性检查和验证。

3赞 Jungle Hunter 8/14/2010 #4

您可以关闭/编辑 JavaScript。

5赞 user240515 8/14/2010 #5

以防攻击者发布自己的表格。

7赞 Dave Sherohman 8/14/2010 #6

与您交谈的客户可能不是您认为您正在与之交谈的客户,因此它可能会忽略您要求它执行的任何验证。

在 Web 上下文中,不仅用户可能在其浏览器中禁用了 javascript,而且还可能您根本没有与浏览器交谈 - 您可能正在从机器人那里获得表单提交,该机器人正在 POST 到您的提交 URL,而根本没有看到表单。

在更广泛的背景下,您可能正在处理一个被黑客入侵的客户端,该客户端正在发送真实客户端永远不会发送的数据(例如,FPS 游戏的瞄准机器人),甚至可能是一个完全自定义的客户端,该客户端由逆向工程您的有线协议的人创建,该客户端对您期望它执行的任何验证一无所知。

19赞 DarkDust 8/14/2010 #7

在编写服务器应用程序时有一个简单的规则:永远不要信任用户数据。

您需要始终假设恶意用户以您不希望的方式访问您的服务器(例如,在这种情况下,通过手动查询而不是预期的网页)。例如,如果您的网页试图过滤掉 SQL 命令,则攻击者已经有一个很好的提示,即使用 SQL 命令传递输入可能是一个很好的攻击媒介。curl

3赞 Richard 8/14/2010 #8

因为用户代理(例如浏览器)可能是假的。创建自定义应用程序以创建具有任意标头和内容的 HTTP 请求非常容易。它甚至可以说它是一个真正的浏览器——你无法分辨出其中的区别。

你所能做的就是查看请求的内容,如果你不检查它,你就不知道它是有效的。

评论

0赞 Wildcard 12/15/2017
您还可以检查会话变量,而不仅仅是内容。
0赞 supercat 8/14/2010 #9

您应该对任何数据执行服务器端验证,如果这些数据无效,则可能对发布数据的实体以外的任何人有害。如果无效数据不会对发布数据的实体以外的任何人产生不良影响,则客户端验证可能适用。除非您可以确定不良数据的不良影响不会扩散到发布数据的实体之外,否则您应该使用服务器端验证来保护自己免受破坏者或其他恶意客户端的侵害。

评论

3赞 Dave Sherohman 8/14/2010
即使它只会伤害提交者,您也需要对其进行验证,因为可能会受到跨站点请求伪造攻击。en.wikipedia.org/wiki/Cross-site_request_forgery
0赞 supercat 8/15/2010
@Dave Sherohman:感谢您的更正,尽管我不确定我是否理解它。如果流氓用户代理提交的虚假信息除了将虚假数据返回给流氓用户代理之外没有任何作用,这将如何使攻击成为可能?假设谁信任谁,以及流氓用户代理自己无法做到的恶作剧将被允许发生?
3赞 Douglas 8/15/2010
想象一下,一个 rouge 代理构造了一个无效的查询,并诱使目标执行该查询,可能是通过隐藏的 iframe 虚假响应将来自您的域,例如,可以访问您的应用程序 cookie。如果虚假响应允许注入客户端代码,攻击者可以窃取 cookie,然后利用这些新信息发起进一步的攻击。
2赞 Douglas 8/16/2010
对不起,这个例子不是特别清楚(它提出了应该通过适当的输出转义而不是输入验证来处理的问题)。我想说的是,构建恶意查询的人可能不是执行恶意查询的人,所以你仍然必须谨慎行事。最近有人沿着这些思路搞砸的一个例子:giorgiosironi.blogspot.com/2010/08/......攻击者试图通过分发恶意查询供其他人执行来对 Google 进行负面报道。
1赞 supercat 12/15/2017
@Wildcard:我想我明白道格拉斯的意思了,但他的后续例子很差。一个更好的问题可能是基于提交的数据构建客户端 Javascript 的网站。如果提交故意格式不正确的数据可能导致服务器向客户端发送有害代码,则服务器应执行足够的验证以防止这种情况发生,即使代码的影响只会对客户端有害。
1赞 J. Bruni 8/14/2010 #10

服务器端验证是必须的,因为客户端验证不能确保未经验证的数据将到达服务器。

客户端验证是不够的,因为它的作用范围非常有限。验证仅在浏览器用户界面中执行。

Web 服务器“侦听”并接收来自浏览器的包含数据的 HTTP 请求,然后对其进行处理。

恶意用户可以通过多种方式发送恶意 HTTP 请求。甚至不需要浏览器。

在浏览器中使用 JavaScript 执行的客户端验证是一项重要的可用性用户界面增强功能。但是,它并不能阻止知道如何规避浏览器默认行为(构建将发送到服务器的 HTTP 请求)的用户发送恶意数据。这可以通过一些浏览器插件、使用 cURL 等轻松完成。

0赞 Chinmoy 8/15/2010 #11

客户端验证用于防止客户端输入错误数据。服务器端验证用于防止服务器处理错误数据。在此过程中,它还为提交过程引入了一些安全性。

1赞 Jeffrey Blake 8/15/2010 #12

一般来说,最好让应用程序的每个部分都进行自己的检查/验证。

客户端检查有利于最大限度地提高用户体验,加快向客户端反馈他们需要修复某些问题的速度,并减少服务器端检查中遇到的问题数量。

然后,在服务器端代码的每个主要转换点,您也应该在那里进行检查。验证应用程序代码中的输入,最好通过白名单输入验证,然后使用参数化查询与数据库进行任何交互,以进一步确保不会发生问题。

0赞 Charlie 8/15/2010 #13

客户端验证以安全的浏览器、客户端语言或 HTML 5 为前提。所有这些元素都可能被禁用、部分不可用或根本无法实现。您的网站必须由每个人、每个浏览器使用。 服务器端语言更安全,如果它们不是错误,验证肯定会更安全、更正确。

0赞 Jijo John 6/25/2013 #14

伙计,假设如果一个人关闭了浏览器中的javascript,验证就死了。然后,如果他通过该表单将一些恶意内容发布到服务器端。这将导致严重的漏洞,如sql注入或xss或任何其他类型的问题。因此,如果您要实现客户端 javascript 验证,请当心。

谢谢