入力データがヘッダー フィールドパラメーター(たとえば、ヘッダーのfilename
パラメーター) に含まれている場合、( Content-Disposition
rfc2231 エンコーディングのバリエーションを定義するこれらの仕様email.utils.encode_rfc2231
によって制約されるように) でエンコードできます。
ヘッダー フィールド パラメータに含まれていない場合、このメソッドは使用できないようです。このような状況では、 Julian Reschke が書いたように、入力を含めないことが最も安全な方法でしょう。ただし、どうしても入力を含める場合は、次のいずれかの方法を試してください。
( HTTP は MIME 準拠のプロトコルではないため、これは安全ではない可能性があります。したがって、MIME-Version
ヘッダーが使用されない限り(そしておそらく使用されていても?)、これらの方法はHTTP では正しく機能しない可能性があります。)
一方通行...
これを行うには、完全に確実ではないかもしれませんが (**編集**: (単独で使用した場合) 絶対確実ではありません; ヘッダーを終了し、ヘッダーを開始する `\r\n\r\n` を受け入れます本文! したがって、`\r` および `\n` は、`\r`/`\n` 以外の空白 (タブやスペースなど) が前にない限り、処理する必要があります)、
`email.header`を使用することです。モジュール。
これは特にrfc822 ヘッダー用に設計されています (**編集**: しかし (どうやら、email パッケージは以前はいくつかの別個のモジュール (
example ))であっ
たため、HTTP ヘッダー用ではありません! )、そのためのツールのようです。この `Header` クラスは、完全な `Header-Name: value` ではなく、ヘッダーの *values* をエンコードすることを目的としているため、このジョブの候補です (値 *のみ* を検証またはエスケープする場合)。
(ヒント: モジュール内のツールの多くは、他の MIME 形式 ( editemail
: およびおそらく MIME に似たもの)を操作するときにも便利です。モジュール内のもの、特に HTTP フォームの解析にはあまりにも便利です。)cgi
cgi.FieldStorage
ただし、入力に悪意があると思われる (別の (埋め込まれた) ヘッダーが含まれているように見える)email.header
場合にのみエラーが発生します。ただし、無効な入力をエスケープして処理しないようです (そうでない場合は、コメントでこれを修正してください)。(パラメーターはヘッダー フラグメントをエスケープし、有効な入力を返す必要がありますが、ユーザー エージェント (電子メール、HTTP など) との互換性があまり高くない場合があります。ここを参照してください( edit : <a href="https://stackoverflow .com/a/1361646/541412>多くの HTTP ユーザー エージェントがサポートしています (必ずしもクラスのエンコーディングのパラメーターではありません(rfc2231 エンコーディング以外に MIME 固有のエンコーディングを使用しているようです)、しかし) rfc5987charset
charset
email.header.Header
エンコーディング)。
例:
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>
別の方法...
これを行うには、単に
`\r` と `\n` 文字を削除するだけのようです (ただし、それぞれ個別に; 完全な文字列 `\r\n` の出現を削除しないでください。別々に発生し、多くの (ほとんどの?) HTTP ユーティリティはそれぞれを別々に受け入れます!)。同様に、`\r\n`、`\r`、および `\n` を先頭に空白を追加して置き換えることにより、ヘッダーをエスケープできます (これはヘッダーをエスケープする方法です。
標準を参照してください)。
ただし、この方法では標準の詳細が考慮されていないため (たとえば、rfc822 ヘッダーは 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"
要約すれば...
最初の方法の方が良いように見えますが、それがパラメーター値でない限り (エスケープではなく) 検証のためだけ
です。
例:
# 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')