公式サンプルスクリプト examples/recursively_extract_attachments.py には、意図した出力ディレクトリの外部への任意ファイル書き込みを可能にするパストラバーサル脆弱性が存在します。解析されたメールから抽出された添付ファイル名は、サニタイズ処理なしで出力ファイルパスの構築に直接使用されるため、攻撃者が制御したファイル名が対象ディレクトリから脱出できる可能性があります。
ファイル: examples/recursively_extract_attachments.py
行: 61–64
for a in m['attachment']:
out_filepath = out_path / a['filename'] # No sanitization
print(f'\tWriting attachment: {out_filepath}')
with out_filepath.open('wb') as a_out:
a_out.write(base64.b64decode(a['raw']))
a['filename'] の値は、細工されたメールの添付ヘッダーによって攻撃者が制御できます:
Content-Disposition: attachment; filename="../outside/pwned.txt"
書き込み前にパス正規化や境界検証は実行されません。
.eml ファイルを作成します:Content-Disposition: attachment; filename="../outside/pwned.txt"
python recursively_extract_attachments.py -p ./emails -o ./safe
./safe/pwned.txt./outside/pwned.txt ← 意図したディレクトリの外部に書き込まれるKali Linux 上で、仮想環境に pip でインストールした eml-parser を使用して検証済みです。
この脆弱性はサンプルスクリプトのみに限定され、コアの eml-parser ライブラリには影響しません。ただし、このスクリプトは公式リポジトリの一部であり、本番環境での使用に適応される可能性が高いため、細工されたメールを供給する攻撃者は実行コンテキスト内で任意のファイル書き込みを達成できる可能性があります。
潜在的な攻撃シナリオには以下が含まれます:
filename="../../etc/cron.d/backdoor"filename="../../var/www/html/shell.php"filename="../../home/user/.ssh/authorized_keys"import os.path
for a in m['attachment']:
filename = os.path.basename(a['filename'])
out_filepath = out_path / filename
if not out_filepath.resolve().is_relative_to(out_path.resolve()):
print(f'[!] Skipping suspicious filename: {a["filename"]}')
continue
print(f'\tWriting attachment: {out_filepath}')
with out_filepath.open('wb') as a_out:
a_out.write(base64.b64decode(a['raw']))