代码之家  ›  专栏  ›  技术社区  ›  Aaron

何时最好清理用户输入?

  •  49
  • Aaron  · 技术社区  · 16 年前

    用户等于不可信。永远不要相信不可信用户的输入。我明白了。然而,我想知道什么时候是净化输入的最佳时间。例如,您是盲目地存储用户输入,然后在访问/使用时对其进行清理,还是立即清理输入,然后存储此“清理”版本?也许除了这些,我还没有想到其他一些方法。我更倾向于第一种方法,因为任何来自用户输入的数据都必须谨慎处理,“清理”后的数据仍然可能在不知不觉中或无意中具有危险性。不管怎样,人们认为什么方法是最好的,原因是什么?

    14 回复  |  直到 6 年前
        1
  •  36
  •   Your Common Sense    3 年前

    不幸的是,几乎没有人能清楚地理解他们在说什么。字面上只有 Kibbee

    这个话题是关于消毒的。但事实是,像这样一个大家都热衷于谈论的被广泛称为“通用消毒”的事情是不可能的 根本不存在。

    它有自己独特的数据格式。 此外,甚至 单个特定介质的各个部分需要不同的格式 . 比如说,HTML格式对于嵌入在HTML页面中的javascript是无用的。或者,字符串格式对于SQL查询中的数字是无用的。

    不可能的

    另一方面,我们努力避免了所有的“用户输入”。。。但是在sql查询中,它周围没有引号,因为它是一个数字或标识符。没有任何“消毒”对我们有帮助。

    在第三方面——好的,我们尽了最大的努力来消除可怕的、不可信的和被蔑视的“用户输入”。。。但在一些内部过程中,我们使用这些数据时没有任何格式(我们已经尽了最大的努力!)——哎哟!在所有的荣耀中都得到了二级注射。

    • 格式化,而不是任何“消毒”
    • 根据一定的媒介规则
    • 甚至遵循媒体不同部分所需的子规则。
        2
  •  16
  •   Daniel Jennings    16 年前

    我喜欢尽可能早地对其进行清理,这意味着当用户试图输入无效数据时,就会进行清理。如果有一个适合他们年龄的文本框,而他们输入的不是数字,我不会让字母的按键通过。

    编辑:总的来说,尽早进行清理,并在您看不见数据的任何时候进行清理(例如,文件保存->文件打开)

        3
  •  15
  •   Script47    6 年前

    我清理我的用户数据非常像Radu。。。

    1. 第一个客户端同时使用正则表达式并控制允许的字符 提交。然而,要意识到,这实际上只会让那些 数据库中的用户知道,数据也将在服务器端进行检查。它是 与其说是实际保护,不如说是警告。

    2. 服务器端完成的任务是检查表单的提交位置。 只允许从指定为有效的页面提交表单 域和IP地址,使脚本觉得它即将到来 从有效的表单位置。

    3. 接下来,我甚至不应该说这些,但总是,我的意思是 总是 第四步。

    4. 表单上任何给定字段的预期数据。不要走捷径 臭名昭著的 独角兽魔角 你的喉咙,说“你真的不会伤害我的,好吗?”。

      在这第四步中,我与其他大多数人的不同之处在于,我只进行了消毒 我将实际使用的用户数据可能会带来安全性 风险,例如任何系统调用、对其他变量的赋值或对 我自己已将数据存储在系统中(因此知道我自己的数据是安全的), 这本身就是一个安全问题。例如,将用户名输入作为 举个例子。我使用用户输入的用户名只是为了对照中的匹配项进行检查 我的数据库,如果为true,之后我使用数据库中的数据执行 我可能在脚本中调用它的所有其他函数,因为我知道它是安全的,而且永远不会 之后再次使用用户数据。

    5. 最后,是过滤掉这些天机器人尝试自动提交的所有内容,使用 “身份验证”系统,如验证码。现在这已经足够重要了 以及“人”输入他们在图片中看到的内容。我这样做是因为 我发现Captcha类型的系统真的让用户很恼火(你可以从他们的 眯起眼睛试图破译扭曲的字母。。。通常反复 再次)。这对于使用SendMail或SMTP的脚本尤其重要 对于电子邮件,因为这些是饥饿的垃圾邮件机器人的最爱。

    总而言之,我会像向我妻子解释一样解释它。。。你的服务器就像一家很受欢迎的夜总会,你的保镖越多,麻烦就越少 在夜总会。我在门外有两个保镖(客户端验证和人工身份验证),门内有一个保镖(检查有效的表单提交位置…“这个ID上真的是你吗”),还有几个保镖在门内 靠近门(运行污染模式并使用良好的正则表达式检查 用户数据)。

    魔弹 谈到安全性,需要所有这些因素相互配合才能确保用户提供的数据的安全。仅仅使用其中一两种方法实际上是毫无价值的,因为它们的力量只有在它们一起工作时才存在。

    总之,就像我妈妈经常说的那样……“安全总比后悔好”。

    更新:

    这些天我正在做的另一件事是Base64编码我的所有数据,然后加密将驻留在SQL数据库中的Base64数据。以这种方式存储它需要大约三分之一的总字节,但在我看来,安全性的好处超过了数据的额外大小。

        4
  •  13
  •   Kibbee    16 年前

    为了防止SQL注入,不要对数据本身做任何事情。只需使用预先准备好的语句,这样,您就不必担心会弄乱用户输入的数据,并使其对您的逻辑产生负面影响。您必须进行一点清理,以确保数字是数字,日期是日期,因为所有内容都是来自请求的字符串,但不要尝试执行任何检查来执行诸如块关键字之类的操作。

        5
  •  5
  •   cpm    16 年前

    对于SQL,只需确保数据库访问库支持自动转义值的绑定变量。任何手动将用户输入连接到SQL字符串的人都应该更清楚。

    对于HTML,我更喜欢在最后一刻逃离。如果您破坏了用户输入,您将永远无法将其取回,如果他们犯了错误,他们可以稍后进行编辑和修复。如果你破坏了他们的原始输入,它将永远消失。

        6
  •  3
  •   Peter Stone    16 年前

    早一点是好的,在你尝试解析它之前。以后要输出的任何内容,特别是传递给其他组件(如shell、SQL等)的内容都必须经过清理。

    但不要过火——例如,在存储密码之前会对密码进行哈希运算(对吗?)。哈希函数可以接受任意二进制数据。你永远不会打印出密码(对吧?)。所以不要解析密码,也不要对它们进行清理。

    另外,请确保您正在从一个受信任的进程进行清理-JavaScript/任何客户端都比无用的安全性/完整性更糟糕。(不过,它可能会提供更好的用户体验,让用户尽早失败——只要在两个地方都做就行了。)

        7
  •  3
  •   Radu Maris    14 年前

    我的意见是在客户端和服务器端都有可能的情况下尽快清理用户输入,我就是这样做的

    1. (客户端),允许用户
    2. (客户端),当用户使用onblur转到下一个字段时,测试他输入的输入 针对regexp,并注意用户是否有不好的地方。
    3. (服务器端),再次测试输入, 如果字段应该是整数,请检查该字段(在PHP中,可以使用is_numeric()), 对照regexp检查一下,好吗 其他(如文字注释),仅

    如果真的有什么看起来像是可能的攻击,脚本会向我发送一封邮件和一条短信,这样我可以检查并尽快阻止它,我只需要检查记录所有用户输入的日志,以及脚本在接受或拒绝输入之前所做的步骤。

        8
  •  2
  •   Jon Ericson Homunculus Reticulli    16 年前

    Perl有一个污点选项,它将所有用户输入视为“污点”,直到用正则表达式检查为止。受污染的数据可以被使用和传播,但在未受污染之前,它会污染它接触到的任何数据。例如,如果将用户输入附加到另一个字符串,则新字符串也会受到污染。基本上,任何包含受污染值的表达式都将输出受污染的结果。

    受污染的数据可以随意抛出(在数据运行时会受到污染),但一旦命令使用了受污染的数据,对外界产生影响,perl脚本就会失败。因此,如果我使用受污染的数据创建文件、构造shell命令、更改工作目录等,Perl将因安全错误而失败。

    我不知道还有哪种语言有类似“污点”的东西,但使用它让我大开眼界。如果你不马上清除污染数据,那么污染数据传播的速度之快令人惊讶。对于程序员来说,自然和正常的事情,比如根据用户数据设置变量或打开文件,如果打开污染,似乎是危险和危险的。因此,完成任务的最佳策略是,一旦从外部获得一些数据,就立即卸载。

    我认为在其他语言中,这也是最好的方法:立即验证用户数据,这样bug和安全漏洞就不会传播得太远。此外,如果潜在的漏洞在一个地方,那么应该更容易审计代码中的安全漏洞。而且,你永远无法预测哪些数据将用于以后的用途。

        9
  •  1
  •   mk.    16 年前

    在存储数据之前,请先清理数据。通常情况下,你不应该表现得很好 任何 SQL操作,而不首先清理输入。您不想让自己受到SQL注入攻击。

    1. 仅执行修改SQL操作,例如,通过POST插入、更新、删除。永远也得不到。
    2. 如果您希望用户输入是某种东西,请确保您检查它是否是某种东西。例如,您正在请求一个号码,然后确保它是一个号码。使用验证。
    3. 使用过滤器。清除不需要的字符。
        10
  •  1
  •   Martin    16 年前

    用户是邪恶的!

    也许不总是这样,但我的方法是总是立即进行sanatize,以确保在我的后端附近没有任何风险。

        11
  •  1
  •   jyoung    16 年前

    假设所有用户都是恶意的。 尽快清理所有输入。 句点

        12
  •  1
  •   Dillie-O    16 年前

    可怕的是,您甚至可能还想开始清理数据库中的数据。最近爆发的ASPRox SQL注入攻击具有双重致命性,因为它会感染给定数据库中的所有数据库表。如果您的数据库托管在同一数据库中有多个帐户的某个位置,则您的数据会因其他人的错误而损坏,但现在您加入了为访问者托管恶意软件的行列,因为您自己没有初始错误。

    当然,这需要大量的前期工作,但如果数据是关键的,那么这是一项值得投资的投资。

        13
  •  0
  •   Sean Chambers    16 年前

    在将用户输入降低到应用程序的较低层之前,应始终将其视为恶意输入。始终尽快处理清理输入,在检查恶意意图之前,不应出于任何原因将其存储在数据库中。

        14
  •  -1
  •   Craig    16 年前

    我发现立即清洗有两个好处。首先,您可以根据它进行验证,并向用户提供反馈。第二,您不必担心在其他地方消耗数据。