Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何停止HTTP(和rfc822、电子邮件)头注入?_Python_Http Headers_Code Injection_Email Headers_Rfc822 - Fatal编程技术网

Python 如何停止HTTP(和rfc822、电子邮件)头注入?

Python 如何停止HTTP(和rfc822、电子邮件)头注入?,python,http-headers,code-injection,email-headers,rfc822,Python,Http Headers,Code Injection,Email Headers,Rfc822,(我问(并回答)这个问题是为了提供一些(希望有用的)信息,因为我无法使用搜索引擎轻松找到这些信息。不过,请随意回答并添加有用的信息:-) 如何在Python中转义/引用HTTP头 和/或如何验证它们以确保它们不包含任何上下文转义值 换句话说,我们如何处理HTTP头,cgi.escape和urllib.quote方法(和清理)对HTML和URL做了什么?这可用于防范和防止类似的漏洞攻击 例如 我们让用户提供一个应该重定向到的URL。我们希望防止注入攻击(其中一种是众所周知的攻击)。撇开(在本讨论中

(我问(并回答)这个问题是为了提供一些(希望有用的)信息,因为我无法使用搜索引擎轻松找到这些信息。不过,请随意回答并添加有用的信息:-)

如何在Python中转义/引用HTTP头

和/或如何验证它们以确保它们不包含任何上下文转义值

换句话说,我们如何处理HTTP头,
cgi.escape
urllib.quote
方法(和清理)对HTML和URL做了什么?这可用于防范和防止类似的漏洞攻击

例如 我们让用户提供一个应该重定向到的URL。我们希望防止注入攻击(其中一种是众所周知的攻击)。撇开(在本讨论中)安全问题不谈(关于用户可以选择的域中的URL的秘密自动转发),如果我们决定重定向,我们如何转义用户提供的URL以防止HTTP头注入(或检测它是否包含对HTTP有害的值)


现在,在我们实现
redirect\u to
命令的python代码中,我们希望像上面这样的输入要么被转义(使其无害),要么成为一个错误。我们如何做到这一点?

如果输入数据包含在标题字段参数(例如)中,则可以使用对其进行编码(受约束,它定义了标题字段的变体)

如果未包含头字段参数,则似乎无法使用此方法。在这种情况下,最安全的赌注可能只是不包括输入,如:;但是,如果您坚持包含输入,则可能需要尝试以下方法之一:

(这可能是不安全的,因为,除非(甚至可能使用它?)这些方法对HTTP可能无法正常工作

单程。。。 要做到这一点,尽管它可能不是完全万无一失的(edit):它不是万无一失的(当它自己使用时);它接受
\r\n\r\n
,终止标题并启动正文!因此
\r
\n
需要处理,除非前面有非
\r
/
\n
空格(如制表符或空格。)),使用该模块。该模块专为(编辑::但是(似乎,因为电子邮件包以前是几个单独的模块())而设计),因此似乎是作业的工具。此
标题
类用于编码标题值,而不是完整的
标题名称:值
,因此也是此作业的候选对象(我们只希望对值进行vaidate或转义)

(提示:
email
模块中的许多工具在处理其他MIME格式(edit:也可能是类似MIME的)东西时也很方便;在
cgi
模块中,
cgi.FieldStorage
中的东西也很方便,尤其是用于HTTP表单解析。)

但是,只有当输入看起来是恶意的(似乎包含另一个(嵌入的)头)时,才会引发错误;但是,它似乎不会通过转义来处理无效输入(如果不是,请在注释中更正)。(
charset
参数应该转义标题片段,返回有效的输入,但是,它可能与用户代理(电子邮件、HTTP等)的兼容性不太好;请参阅(edit:许多HTTP用户代理都支持(不一定是
email.header.header
类编码的
charset
参数(除了rfc2231编码之外,它似乎还使用了一些MIME特定的编码),而是编码)

例如:

import email.header
import re

def check_string_for_rfc822_header(s):
    wip_header_component = str(email.header.Header(s))
    if re.search(r'(\r?\n[\S\n\r]|\r[\S\r])', wip_header_component):
        raise Exception
    else:
        return wip_header_component

# testing...
>>> check_string_for_rfc822_header("aaa")
"aaa"
>>> check_string_for_rfc822_header("a\r\nb")
"a\r\nb"
>>> check_string_for_rfc822_header("a\r\nb: c")
<error>
def remove_linebreakers(s):
    return s.replace("\n", "").replace("\r", "")

# or...
import re

def remove_linebreakers(s):
    re.sub(r'[\n\r]', '', s)


# testing...
>>> remove_linebreakers("aaa")
"aaa"
>>> remove_linebreakers("a\r\nb")
"ab"
>>> remove_linebreakers("a\r\nb: c")
"ab: c"
# if we are not working with a header param value, the following...
# ...raises email.errors.HeaderParseError if input is poisonous when in a header
wip_header_component = str(email.header.Header('<input>'))
header_component = (raise_error() if re.search(r'(\r?\n[\S\n\r]|\r[\S\r])', wip_header_component) else wip_header_component)
# ...or if we *are* working with a header param value...
email.utils.encode_rfc2231('<input>', 'UTF-8')
总之。。。 第一种方法似乎更好,但仅用于验证(而不是转义),除非它是参数值,在这种情况下,使用转义

例如:

import email.header
import re

def check_string_for_rfc822_header(s):
    wip_header_component = str(email.header.Header(s))
    if re.search(r'(\r?\n[\S\n\r]|\r[\S\r])', wip_header_component):
        raise Exception
    else:
        return wip_header_component

# testing...
>>> check_string_for_rfc822_header("aaa")
"aaa"
>>> check_string_for_rfc822_header("a\r\nb")
"a\r\nb"
>>> check_string_for_rfc822_header("a\r\nb: c")
<error>
def remove_linebreakers(s):
    return s.replace("\n", "").replace("\r", "")

# or...
import re

def remove_linebreakers(s):
    re.sub(r'[\n\r]', '', s)


# testing...
>>> remove_linebreakers("aaa")
"aaa"
>>> remove_linebreakers("a\r\nb")
"ab"
>>> remove_linebreakers("a\r\nb: c")
"ab: c"
# if we are not working with a header param value, the following...
# ...raises email.errors.HeaderParseError if input is poisonous when in a header
wip_header_component = str(email.header.Header('<input>'))
header_component = (raise_error() if re.search(r'(\r?\n[\S\n\r]|\r[\S\r])', wip_header_component) else wip_header_component)
# ...or if we *are* working with a header param value...
email.utils.encode_rfc2231('<input>', 'UTF-8')
#如果我们没有使用头参数值,则以下。。。
#如果输入在标题中有毒,则会引发email.errors.HeaderParseError
wip_header_component=str(email.header.header(“”))
标头\u组件=(如果重新搜索(r'(\r?\n[\S\n\r]\r[\S\r]),在制品标头\u组件),则引发\u错误(),否则在制品标头\u组件)
#…或者如果我们*正在*处理标头参数值。。。
email.utils.encode_rfc2231(“”,“UTF-8”)

不要逃避。只需停止处理(删除标题或整个请求)。

我认为我没有在问题中正确解释自己;我修改了它(及其标题),试图解释更多。我还是不生成重定向。只返回400。是的,我想这更有意义。我更新了我的答案,使用了关于使用文件名,这是我当前的用例,我后来意识到,关于这些主题的标准,由您:-)