我想知道从Django中的POST或GET变量中检索数据的最安全方法。有时我使用urls.py中url模式直接传递给view函数的变量。我被告知(不确定)当我开始使用模式时,它们是安全的。'''''但我不知道为什么会这样。
为了检索POST数据我知道两个选项:
使用表单,Django表单有一个cleaned data
函数,可以使数据安全使用.....
使用request.POST.get('someval')
。因为我可以看到这些值没有被转义,它们可能不安全吗?其次,使用u
或r
符号确保安全,如果是这样,为什么?
答案 0 :(得分:3)
r
前缀不会保留在字符串值中。 'a\\b'
和r'a\b'
完全相同,只有一个反斜杠。 u
前缀确定字符串是保存字节还是Unicode字符。一般来说,Django应用程序中的字符串应该是Unicode字符串,但Python会在必要时自动将字节转换为字符(如果使用非ASCII字符,这可能会爆炸)。
这些都不能确定字符串是否“安全”。
在表单上使用cleaned_data
存储意味着数据已针对与其关联的特定字段类型进行了验证。如果您有电子邮件字段,则cleaned_data
值肯定看起来像是有效的电子邮件地址。如果您有纯文本字段,那么cleaned_data
可以是任何字符串。这些都不能保证字符串是“安全的”;输入验证通常是一件好事,也是一种有用的纵深防御,但它不会使应用程序对注入安全。
由于这些值没有被转义,因为我可以看到它们可能不安全吗?
输入值永远不应该被转义,永远不会“安全”。进行转义不是输入处理阶段的工作;当您将值放入具有不同上下文的字符串时,您必须担心转义。
因此,当您创建带有字符串的HTML响应时,您将HTML转义该字符串。 (但更好:使用一种自动逃脱的模板语言,如Django的autoescape
。)
当您创建带有字符串的SQL查询时,您将SQL转义该字符串。 (但更好:使用参数化查询或ORM,这样您就不必使用字符串变量创建查询。)
当您使用字符串创建JavaScript变量赋值时,JS-escape该字符串。 (但更好的是:传递DOM data-
属性中的数据并从JS读取它而不是使用内联代码。)
等等。存在许多不同形式的转义,并且没有全局转义方案可以保护您免受可能的注入攻击范围。因此,保持输入不变,并在输出阶段转义,或者更好地使用现有的框架工具,以避免必须明确地转义。