用户等于不值得信任.永远不要相信不值得信任的用户输入.我明白了.但是,我想知道什么时候消毒输入的最佳时间是.例如,您是否盲目存储用户输入,然后在访问/使用它时对其进行清理,或者您是否立即清理输入然后存储此"已清理"的版本?也许除了这些之外我还有其他一些方法.我更倾向于第一种方法,因为仍然必须谨慎地处理来自用户输入的任何数据,其中"清理的"数据可能仍然在不知不觉中或意外地变得危险.无论哪种方式,人们认为哪种方法最好,原因是什么?
不幸的是,几乎没有一个参与者清楚地了解他们在谈论什么.从字面上看.只有@Kibbee设法直截了当.
这个主题都是关于消毒.但事实是,诸如广泛的"通用消毒"这样的事情,每个人都如此渴望谈论,只是不存在.
有许多不同的媒介,每个都需要它自己的,不同的数据格式.而且 - 即使是单一的某些介质也需要不同的格式.比方说,HTML格式对于HTML页面中嵌入的javascript是无用的.或者,字符串格式对SQL查询中的数字没用.
事实上,正如大多数赞成的答案所建议的那样,这种"尽早消毒"是不可能的.由于人们无法确定哪些媒介或中等部分将使用数据.比如说,我们正在准备防范"sql-injection",逃避一切动作.但是哎呀! - 一些必填字段未填写,我们必须将数据填回表单而不是数据库...添加所有斜杠.
另一方面,我们努力逃脱所有"用户输入"...但在sql查询中我们没有引号,因为它是一个数字或标识符.并没有"消毒"对我们有所帮助.
第三方面 - 好吧,我们尽最大努力消除可怕的,不值得信赖的和鄙视的"用户输入"......但是在一些内部过程中我们使用了这些数据而没有任何格式化(因为我们已经做到了最好!) - 和哎呦!所有的荣耀都得到了二阶注入.
因此,从现实生活中的使用角度来看,唯一正确的方法是
格式化,而不是"消毒"
在使用之前
根据某些媒介规则
甚至遵循该媒体不同部分所需的子规则.
我想尽早清理它,这意味着当用户试图在无效的数据进入消毒情况.如果有他们的年龄一个文本框,并输入他们在其他任何一个号码,我不让的字母的按键经过.
于是,无论是读取数据(通常是一个服务器),我做了仔细的检查,当我读入数据,只是为了确保没有在滑落由于更确定的用户(如手工编辑文件,甚至修改数据包!)
编辑:总体来说,早消毒和消毒你已经失去了视线数据的哪怕一秒钟的任何时间(例如保存文件 - >打开文件)
我像Radu一样清理用户数据...
第一个客户端使用正则表达式并使用与事件相关联的javascript或jQuery控制允许的字符输入到给定的表单字段,例如onChange或OnBlur,它甚至可以在提交之前删除任何不允许的输入.但要意识到,这实际上只会让那些用户知道,数据也将在服务器端进行检查.这比任何实际保护都要警告.
其次,我现在很少看到这样做,服务器端的第一次检查是检查表单提交的位置.通过仅允许从您指定为有效位置的页面提交表单,您可以在读取任何数据之前终止脚本.当然,这本身就是不够的,因为一个拥有自己服务器的好黑客可以"欺骗"域名和IP地址,使你的脚本看来它来自一个有效的表单位置.
接下来,我甚至不应该这样说,但总是,我的意思是,总是在污点模式下运行脚本.这迫使你不要懒惰,并且要努力做好第4步.
使用适合于表单上任何给定字段所需数据的格式正确的regex,尽快清理用户数据.不要像臭名昭着的" 独角兽的魔角 "这样的捷径来吹过你的污点检查......或者你也可以先把污点检查放在首位,以确保它能为你的安全所做的一切.这就像是给一个精神病患者一把锋利的刀子,带着你的喉咙,然后说'你真的不会伤害我,那将是你'.
这是我在第四步中与大多数其他人不同的地方,因为我只是以可能带来安全风险的方式清理我实际使用的用户数据,例如任何系统调用,对其他变量的分配,或者任何写入存储数据.如果我只使用用户输入的数据来比较我自己存储在系统上的数据(因此知道我自己的数据是安全的),那么我就不用费心去处理用户数据了.我永远不会把它当成一种安全问题.例如,以用户名输入为例.我只使用用户输入的用户名来检查我的数据库中的匹配项,如果为true,那么之后我使用数据库中的数据执行我可能在脚本中调用的所有其他函数,因为它知道它是安全的,
最后,现在是使用"人工身份验证"系统(如Captcha)过滤掉机器人现在所有尝试的自动提交.这一点非常重要,我花了很多时间编写自己的"人工认证"模式,该模式使用照片和"人"输入来输入他们在图片中看到的内容.我之所以这样做是因为我发现Captcha类型的系统真的让用户烦恼(你可以通过他们眯起眼睛的眼睛试图解读扭曲的字母......通常一遍又一遍).这对于使用SendMail或SMTP进行电子邮件的脚本尤其重要,因为这些是您饥饿的垃圾邮件机器人的最爱.
简而言之,我会像对待我的妻子一样解释它...你的服务器就像一个受欢迎的夜总会,你拥有的保镖越多,你在夜总会中可能遇到的麻烦就越少.门外有两个保镖(客户端验证和人工认证),门内有一个保镖(检查有效的表单提交位置......'这真的是你在这个ID'),还有几个保镖在关闭靠近门(运行污点模式并使用良好的正则表达式来检查用户数据).
我知道这是一篇较老的帖子,但我认为对于那些在我访问之后可以阅读它的人来说,重要的是在安全方面意识到他们不是" 魔术弹 ",并且所有这些都需要彼此联合起来使您的用户提供的数据安全.仅仅使用这些方法中的一种或两种实际上是毫无价值的,因为它们的力量只有在它们全部团结在一起时才存在.
或者总之,正如我妈妈经常说的那样......"比安慰更安全".
这取决于你正在做什么样的消毒.
为了防止SQL注入,请不要对数据本身做任何事情.只需使用准备好的语句,这样,您就不必担心弄乱用户输入的数据,并使其对您的逻辑产生负面影响.你必须消毒一点,以确保数字是数字,日期是日期,因为一切都是来自请求的字符串,但不要尝试做任何检查来做阻止关键字或任何东西.
为了防止XSS攻击,在存储数据之前修复数据可能会更容易.然而,正如其他人所提到的,有时候拥有一个确切的用户输入的原始副本是很好的,因为一旦你改变它,它就会永远丢失.这几乎是太糟糕了,没有一种简单的方法可以确保您的应用程序只发出已清理的HTML,以确保您不会因使用准备好的查询而被SQL注入捕获.
最重要的是在逃跑时始终保持一致。偶然的双重消毒是la脚的,不消毒是危险的。
对于SQL,只需确保您的数据库访问库支持绑定变量即可自动转义值。手动将用户输入连接到SQL字符串的任何人都应该了解更多。
对于HTML,我更愿意在最后可能的时候转义。如果销毁用户输入,则永远无法取回它;如果他们输入有误,则可以稍后进行编辑和修复。如果您销毁了他们的原始输入,那么它将永远消失。