如果被包括在報頭字段參數(例如filename
parameter of the Content-Disposition
header),它可以被用email.utils.encode_rfc2231
編碼(由these specifications,它定義了rfc2231 encoding的變化作爲約束的)的輸入數據。
如果它是而不是包含一個頭字段參數,那麼看起來這個方法不能使用。在這種情況下,最安全的賭注可能只是不包括輸入,如Julian Reschke wrote;然而,如果你堅持包括輸入,你可能想嘗試以下方法之一:
(這可能是不安全的,因爲HTTP is not a MIME-compliant protocol,所以除非the MIME-Version
header is used(並且可能即使它被使用?),這些方法可能不支持HTTP正確工作)
一種方式...
要做到這一點,雖然它可能不是完全萬無一失(編輯:它是不萬無一失(按使用時本身);它接受\r\n\r\n
,終止標題並啓動正文!因此,需要處理\r
和\n
,除非前面有非\r
/\n
空格(如製表符或空格),否則將使用email.header
模塊。這是專爲rfc822 headers(編輯:但(看起來,因爲電子郵件包過去是幾個單獨的模塊(example))not for HTTP headers!),所以似乎是工作的工具。這Header
類是用於編碼標頭值,而不是完整的Header-Name: value
,因此是這個工作的候選人(我們想要voda或逃生值只有)。
(提示:與其他MIME格式(編輯工作時,許多email
模塊中的工具也很方便:可能還有MIME-等)的東西,尤其是這麼過的東西cgi
模塊中,cgi.FieldStorage
用於HTTP的形式解析)
然而,僅email.header
會如果輸入似乎惡意引發錯誤(似乎包含另一個(嵌入式)報頭);但是,它似乎不會處理無效的輸入通過轉義(如果不是這樣的話,請在註釋中更正)。 (該charset
參數應逃脫報頭片段,返回有效輸入,但是,它可能沒有與用戶代理(電子郵件,HTTP等這樣良好的相容性);見here(編輯:許多HTTP用戶代理支持(不一定是charset
參數編碼爲email.header.Header
類(這似乎使用除了RFC2231編碼一些特定的MIME-編碼),但)的rfc5987編碼)
例:
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>
的另一種方式...
要做到這一點,它似乎只是remove \r
and \n
characters(每個單獨但是;不要僅僅刪除整個字符串\r\n
,因爲這會在單獨發生時仍然會使這些未轉義,並且許多(大多數?)HTTP utils將分別接受它們中的每一個!)。同樣,我們可以通過替換\r\n
,\r
和\n
來替換它們,它們自己用空格(這是擺脫標題的方式;參見the standard)作爲前綴。
但是,此方法沒有考慮標準的細節(例如rfc822標頭must be ACSII),這些標準可能會被單獨利用。
例子:
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"
總之...
第一種方式似乎更好,但僅用於驗證(不轉義),除非它是一個參數值,在這種情況下逃脫它使用email.utils.encode_rfc2231
。
例子:
# 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')
我覺得我沒有在問題中正確解釋自己;我修改了它(和它的標題),試圖解釋更多。 – Abbafei
我仍然不會生成重定向。只需返回400. –
是的,我想這樣做更有意義。我使用關於處理文件名的[info I gleaned](http://stackoverflow.com/q/1361604)更新了我的答案,這是我當前的用例,後來我意識到[some of](http:// tools.ietf。org/html/rfc6266)有關這些主題的標準,[由作者撰寫](http://tools.ietf.org/html/rfc5987)由你們:-) – Abbafei