
When is it best to sanitize user input?用户等于不可信。 永远不要信任不可信用户的输入。 我明白了。 但是,我想知道何时清理输入的最佳时间。 例如,您是盲目存储用户输入,然后在每次访问/使用它时对其进行清理,还是您先对输入进行清理,然后存储此"已清理"版本? 也许除了这些之外,我还没有其他一些方法。 我更倾向于第一种方法,因为必须谨慎处理来自用户输入的任何数据,在这种情况下,"清理"的数据可能仍然在不知不觉中或意外地危险。 无论哪种方式,人们认为哪种方法是最好的,出于什么原因? 不幸的是,几乎没有人清楚地知道他们在说什么。从字面上看。只有@Kibbee设法使它变得笔直。 本主题全都涉??及消毒。但事实是,每个人都渴望谈论的所谓的"通用消毒"之类的东西根本就不存在。 有成千上万种不同的介质,每种介质都需要自己的独特数据格式。而且,即使是单个特定的介质,其部分也需要不同的格式。说,HTML格式对于嵌入HTML页面中的JavaScript毫无用处。或者,字符串格式对于SQL查询中的数字没有用。 事实上,像大多数赞成的答案所建议的那样,"尽早消毒"是不可能的。正如人们无法确定数据将在哪个特定介质中使用。说,我们正在准备抵御" sql注入",从而逃避了所有移动。但是,哎呀! -未填写某些必填字段,我们必须将数据填写回表单而不是数据库中……并添加所有斜杠。 另一方面,我们努力地对所有"用户输入"进行了转义...但是在sql查询中,我们没有引号,因为它是数字或标识符。而且没有"消毒"方法能够帮助我们。 第三方面-好的,我们尽了最大的努力来清理可怕的,不可信任的和鄙夷的"用户输入" ...但是在某些内部过程中,我们使用了这些数据而没有任何格式(因为我们已经尽力了!)-哎呦!具有所有荣耀的二阶注入。 因此,从现实生活中的使用角度来看,唯一正确的方法是
我想尽早清除它,这意味着清除过程是在用户尝试输入无效数据时发生的。如果他们的年龄有一个TextBox,并且他们输入的数字不是数字,那么我不会让该字母的按键通过。 然后,无论正在读取数据(通常是服务器),我在读取数据时都会进行完整性检查,以确保不会因确定的用户(例如手动编辑文件或修改数据包)而漏入!) 编辑:总体而言,尽早进行清理,并在您甚至一秒钟都看不到数据时进行清理(例如,文件保存->文件打开) 我像Radu一样清理用户数据...
客户端同时使用正则表达式并控制允许的字符
第二,这些天我再也看不到这样做了,
接下来,我什至不必这么说,但总是,而且我的意思是总是跑
使用格式正确的正则表达式尽快清理用户数据
这是我在第四步中与大多数其他人不同的地方,因为我只是消毒
最后,方法是过滤掉机器人最近尝试进行的所有自动提交操作,
简而言之,我将向我的妻子解释一下...您的服务器就像一个受欢迎的夜总会,而您拥有的保镖越多,麻烦就越少 我知道这是一篇较旧的文章,但是对于任何在我访问这里后可能会读到它的人来说,我觉得它的重要性已经足够重要,因为他们意识到他们在安全性方面不是"魔术子弹",而且所有这些都需要彼此协同工作确保用户提供的数据安全。仅使用这些方法中的一种或两种方法实际上是毫无价值的,因为它们的力量只有在他们一起协作时才存在。 或总而言之,就像我妈妈经常说的那样:"安全胜于遗憾"。 更新: 这些天,我要做的另一件事是对所有数据进行Base64编码,然后对将驻留在SQL数据库中的Base64数据进行加密。以这种方式存储它需要多出大约三分之一的总字节数,但是我认为安全性优势超过了数据的额外大小。 好。 这取决于您要进行哪种消毒。 为了防止SQL注入,请不要对数据本身做任何事情。只需使用准备好的语句,那样,您就不必担心会弄乱用户输入的数据,并且不会对您的逻辑产生负面影响。您必须进行一点点消毒,以确保数字是数字,日期是日期,因为所有内容都是来自请求的字符串,但是请勿尝试做任何检查来执行诸如block关键字之类的操作。 为了防止XSS攻击,在存储数据之前修复数据可能会更容易。但是,就像其他人提到的那样,有时最好还是获得用户输入内容的原始副本,因为一旦您进行更改,它就会永远丢失。几乎没有一种万无一失的方法来确保您的应用程序仅使用经过预处理的查询才能确保您的应用程序仅输出经过清理的HTML,从而确保您不会被SQL注入所捕获,这几乎是很糟糕的。 最重要的是在逃跑时始终保持一致。偶然的双重消毒是la脚的,不消毒是危险的。 对于SQL,只需确保您的数据库访问库支持绑定变量即可自动转义值。手动将用户输入连接到SQL字符串的任何人都应该了解更多。 对于HTML,我更愿意在最后可能的时候转义。如果销毁用户输入,则永远无法取回它;如果他们输入有误,则可以稍后进行编辑和修复。如果您销毁了他们的原始输入,那么它将永远消失。 我的观点是尽快在客户端和服务器端对用户输入进行处理,我这样做是 在字段中仅输入特定键。 反对正则表达式,并在出现问题时通知用户。 如果field应该是INTEGER检查(在PHP中,您可以使用is_numeric()), 如果字段具有众所周知的格式 对照正则表达式检查所有 其他人(例如文字评论) 逃脱他们。如果有任何可疑的情况,请停止执行脚本,并向用户发送通知,告知他所输入的数据无效。 如果确实有某种可能的攻击,该脚本会向我发送邮件和短信,因此我可以在可能的情况下尽快进行检查并设法阻止它,我只需要检查我登录所有用户输入的日志,并且接受或拒绝输入之前脚本执行的步骤。 尽早进行比较好,绝对是在尝试解析它之前。您稍后要输出的任何东西,或者特别是传递给其他组件(例如,shell,SQL等)的东西都必须经过清理。 但是请不要过度使用-例如,密码在存储之前会被哈希处理(对吗?)。哈希函数可以接受任意二进制数据。而且您永远都不会打印出密码(对吗?)。因此,请勿解析密码-请勿清理密码。 另外,请确保您正在通过受信任的进程进行清理-JavaScript /客户端方面的安全性要比无用的安全性/完整性方面的处理要差。 (不过,这可能会提供更好的用户体验,让您尽早失败-只需在两个地方都做。) Perl有一个taint选项,该选项将所有用户输入都视为"污染",直到使用正则表达式对其进行检查为止。受污染的数据可以使用和传递,但是会污染与其接触的所有数据,直到被污染为止。例如,如果用户输入附加到另一个字符串,则新字符串也会被污染。基本上,任何包含污点值的表达式都将输出污点结果。 污染的数据可以随意抛出(污染数据),但是一旦被对外界有影响的命令使用,perl脚本就会失败。因此,如果我使用受污染的数据来创建文件,构造Shell命令,更改工作目录等,Perl将会失败并出现安全错误。 我不知道另一种语言有"污点"之类的东西,但是使用它却让人大开眼界。如果您不立即取消污染数据的传播速度,那真是令人惊讶。对于程序员而言,自然而正常的事情(例如基于用户数据设置变量或打开文件)在打开污点时似乎是危险且危险的。因此,完成工作的最佳策略是一旦您从外部获得一些数据就取消污染。 而且我怀疑这也是其他语言中最好的方法:立即验证用户数据,以使错误和安全漏洞不会传播得太远。同样,如果潜在漏洞位于一个位置,则应该更容易审核安全漏洞的代码。而且您永远无法预测以后将使用哪些数据来实现什么目的。 我会在对数据进行任何处理之前先对数据进行消毒。我可能需要将"姓氏"和"姓氏"字段连接起来,并将它们连接到要插入数据库的第三个字段中。在进行连接之前,我将清理输入,因此不会出现任何处理或插入错误。越早越好。甚至在前端(在Web设置中)使用Javascript也是理想的,因为这不会发生任何数据进入服务器的开始。 令人恐惧的部分是,您甚至可能还希望开始清理数据库中的数据。最近发生的ASPRox SQL Injection攻击激增,具有双重致命性,因为它将感染给定数据库中的所有数据库表。如果您的数据库托管在同一数据库中托管多个帐户的某个地方,则由于其他人的错误,您的数据将被破坏,但是由于您自己没有最初的过错,现在您已经加入了将恶意软件托管给访问者的行列。 当然,这需要大量的工作,但是如果数据很关键,那么这是值得的投资。
假设所有用户都是恶意的。 用户是邪恶的! 也许并非总是如此,但是我的方法是始终立即进行清理,以确保在我的后端附近没有任何风险。 额外的好处是,如果在输入点进行消毒,则可以向用户提供反馈。 在存储数据之前,请先对其进行清理。通常,如果不先清理输入内容,就不应该执行任何SQL操作。您不想让自己遭受SQL注入攻击。 我有点遵循这些基本规则。 在将用户输入放到应用程序的较低层之前,应始终将其视为恶意输入。在检查恶意意图之前,请始终尽快处理清理输入,并且不应出于任何原因将其存储在数据库中。 我发现立即清洁它有两个优点。第一,您可以针对它进行验证并向用户提供反馈。第二,您不必担心在其他地方使用数据。 |