看了jsf的细颗粒的实践处理,对于每一个页面的输入都可以直接提交到后台,不需要在页面处进行大量的js操作,但是,无法在页面js和服务器端的处理两者之间进行处理。
现在,对于验证,也有了同样的困扰,js的验证为客户端提供了快速的体验,但是在于后台的交互方面有天然的缺陷。
比如,我们要求对于客户输入的一些文本信息在写入数据库之前进行事前处理(有些字符过滤掉,句子末尾加上句号等等), 当然,如果是考虑到正常的逻辑,这些应该在校验之前进行,否则先进行了长度校验,这里处理的时候又在末尾增加了一个句号,就超长了。但是,如果校验是在js上,那么实现这个‘事前处理’也必须在js上了。这样就很受限制。所以,个人更倾向于所有的校验都在后台完成,但这样会对于服务器的负载有所增加,而且客户体验也会造成影响,这些也是要考虑的。
这里在看看别人从安全性方面的分析,如果你有安全性考虑,那么当知道如何取舍。
第1课:切勿绕过服务器端验证
作为一位软件顾问,我曾有机会不但设计并实现了Web应用程序,而且还评估/ 审核了许多Web应用程序。在复杂的、并且用JavaScript客户端封装的应用程序 内,我经常遇到对用户输入信息执行大量检查的Web页面。即使HTML元素具有数据 有效性的属性也如此,例如MAXLENGTH。只有在成功验证所有输入信息后,才能提 交HTML表单。结果,一旦服务器端收到通知表单(请求),便恰当地执行业务逻辑。
在此,您发现问题了么?开发人员已经做了许多重要的假设。例如,他们假设 所有的Web应用程序用户都同样诚实。开发人员还假设所有用户将总是使用他们测 试过的浏览器访问Web应用程序。还有很多其他的假设。这些开发人员忘记了利用 可以免费得到的工具,通过命令行很容易地模拟类似浏览器的行为。事实上,通过 在浏览器窗口中键入适当的URL,您可以发送任何“posted”表单,尽管如此,通过 禁用这些页面的GET请求,您很容易地阻止这样的“表单发送”。但是,您不能阻止 人们模拟甚至创建他们自己的浏览器来入侵您的系统。
根本的问题在于开发人员不能确定客户端验证与服务器端验证的主要差别。两者的 主要差别不在于验证究竟发生在哪里,例如在客户端或者在服务器端。主要的差别 在于验证背后的目的不同。
客户端验证仅仅是方便。执行它可为用户提供快速反馈——使应用程序似乎做出 响应,给人一种运行桌面应用程序的错觉。
另一方面,服务器端验证是构建安全Web应用程序必需的。不管在客户端一侧 输入的是什么,它可以确保客户端送往服务器的所有数据都是有效的。
因而,只有服务器端验证才可以提供真正应用程序级的安全。许多开发人员陷 入了错误感觉的圈套:只有在客户端进行所有数据的验证才能确保安全。下面是说 明此观点的一个常见的示例:
一个典型的登录页面拥有一个用来输入用户名的文本框和一个输入密码的文本 框。在服务器端,某人在接收servlet中可能遇到一些代码,这些代码构成了下面 形式的SQL查询:
"SELECT * FROM SecurityTable WHERE username = '" + form.getParameter("username") + "' AND password = '" + form.getParameter("password") + "';",并执行这些代码。如果查询在结果集的 某一行返回,则用户登录成功,否则用户登录失败。
第一个问题是构造SQL的方式,但现在让我们暂时忽略它。如果用户在用户名 中输入“Alice'--”会怎样呢?假设名为“Alice”的用户已经在 SecurityTable中, 这时此用户(更恰当的说法是黑客)成功地登录。我将把找出为什么会出现这种情 况的原因做为留给您的一道习题。
许多创造性的客户端验证可以阻止一般的用户从浏览器中这样登录。但对于已 经禁用了JavaScript的客户端,或者那些能够使用其他类似浏览器程序直接发送命 令(HTTP POST和GET命令)的高级用户(或者说黑客)来说,我们又有什么办法 呢?服务器端验证是防止这种漏洞类型所必须的。这时,SSL、防火墙等都派不上 用场了。