FA-76811 / Email MIME structure / Open access
Strip blocked attachments under a content policy: body exemption · case 01
A named executable marked inline slips through the policy.
ROOT CAUSE
The body exemption decision evaluates `if (n.get('disp') or '').lower() != 'attachment':` where the contract requires `if (n.get('disp') or '').lower() != 'attachment' and not name:`.
VERIFIED REPAIR
Use `if (n.get('disp') or '').lower() != 'attachment' and not name:` for the body exemption decision and keep every other rule of the model unchanged.
Unsuccessful approach: Exempting every unnamed part also exempts oversized unnamed attachments. The attempted `if not name:` still disagrees with a fixture.
Case contract
Leaves {type, filename, disp, size}. A leaf is blocked when its last filename extension (trimmed, lower-cased) is in blocked_ext, its type is application/x-msdownload, or its size exceeds max_size. A non-attachment leaf without a filename (a body) is never blocked. Blocked leaves become "strip", others "keep"; a blocked leaf anywhere under multipart/signed cannot be stripped, and then the whole message is "reject". Result: the per-leaf action list or "reject".
Why this case matters
Mail gateways strip dangerous attachments but must not silently break signed messages.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree, blocked_ext, max_size):
actions = []
def walk(n, signed):
t = n['type'].lower()
if t.startswith('multipart/'):
for c in n['parts']:
walk(c, signed or t == 'multipart/signed')
return
name = (n.get('filename') or '').strip().lower()
ext = name.rsplit('.', 1)[-1] if '.' in name else ''
bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size
if (n.get('disp') or '').lower() != 'attachment':
bad = False
if bad and signed:
actions.append('reject')
else:
actions.append('strip' if bad else 'keep')
walk(tree, False)
return 'reject' if 'reject' in actions else actions
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| double extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| upper-case padded extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| blocked part inside signed mixed | reject | reject | Passed |
| large body and named inline part | ['keep', 'keep', 'strip'] | ['keep', 'strip', 'strip'] | Failed |
| size boundaries | ['keep', 'keep', 'strip'] | ['keep', 'keep', 'strip'] | Passed |
| executable type in signed | reject | reject | Passed |
| clean message | ['keep', 'keep'] | ['keep', 'keep'] | Passed |
SHA-256 / 40e62562566f2aecb6b48273918555f1dbc6d58e89f35cbe66d5591c2d2167f0
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree, blocked_ext, max_size):
actions = []
def walk(n, signed):
t = n['type'].lower()
if t.startswith('multipart/'):
for c in n['parts']:
walk(c, signed or t == 'multipart/signed')
return
name = (n.get('filename') or '').strip().lower()
ext = name.rsplit('.', 1)[-1] if '.' in name else ''
bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size
if not name:
bad = False
if bad and signed:
actions.append('reject')
else:
actions.append('strip' if bad else 'keep')
walk(tree, False)
return 'reject' if 'reject' in actions else actions
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| double extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| upper-case padded extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| blocked part inside signed mixed | reject | reject | Passed |
| large body and named inline part | ['keep', 'strip', 'keep'] | ['keep', 'strip', 'strip'] | Failed |
| size boundaries | ['keep', 'keep', 'strip'] | ['keep', 'keep', 'strip'] | Passed |
| executable type in signed | reject | reject | Passed |
| clean message | ['keep', 'keep'] | ['keep', 'keep'] | Passed |
SHA-256 / f8fb787a65e363493c73c33a3c351943940cadcd14b58a373bb8f356bf0b1c3d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree, blocked_ext, max_size):
actions = []
def walk(n, signed):
t = n['type'].lower()
if t.startswith('multipart/'):
for c in n['parts']:
walk(c, signed or t == 'multipart/signed')
return
name = (n.get('filename') or '').strip().lower()
ext = name.rsplit('.', 1)[-1] if '.' in name else ''
bad = ext in blocked_ext or t == 'application/x-msdownload' or n.get('size', 0) > max_size
if (n.get('disp') or '').lower() != 'attachment' and not name:
bad = False
if bad and signed:
actions.append('reject')
else:
actions.append('strip' if bad else 'keep')
walk(tree, False)
return 'reject' if 'reject' in actions else actions
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice1.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP1.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 1}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5001}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 1000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 1001}]}, [], 1000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r1.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 2: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice2.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP2.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 2}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5002}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 2000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 2001}]}, [], 2000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r2.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 3: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice3.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP3.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 3}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5003}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 3000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 3001}]}, [], 3000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r3.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 4: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice4.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP4.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 4}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5004}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 4000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 4001}]}, [], 4000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r4.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])], 5: [('double extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 10}, {'type': 'application/pdf', 'filename': 'invoice5.pdf.exe', 'disp': 'attachment', 'size': 10}]}, ['exe'], 1000), ['keep', 'strip']), ('upper-case padded extension', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/octet-stream', 'filename': 'SETUP5.EXE ', 'disp': 'attachment', 'size': 5}]}, ['exe'], 1000), ['keep', 'strip']), ('blocked part inside signed mixed', ({'type': 'multipart/signed', 'parts': [{'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/zip', 'filename': 'x.js', 'disp': 'attachment', 'size': 5}]}, {'type': 'application/pgp-signature'}]}, ['js'], 1000), 'reject'), ('large body and named inline part', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'size': 5005}, {'type': 'application/octet-stream', 'filename': 'tool.exe', 'disp': 'inline', 'size': 3}, {'type': 'application/zip', 'disp': 'attachment', 'size': 5000}]}, ['exe'], 1000), ['keep', 'strip', 'strip']), ('size boundaries', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'image/png', 'filename': 'a.png', 'disp': 'attachment', 'size': 5000}, {'type': 'image/png', 'filename': 'b.png', 'disp': 'attachment', 'size': 5001}]}, [], 5000), ['keep', 'keep', 'strip']), ('executable type in signed', ({'type': 'multipart/signed', 'parts': [{'type': 'text/plain'}, {'type': 'application/x-msdownload', 'filename': 'a.bin', 'disp': 'attachment', 'size': 1}]}, [], 50), 'reject'), ('clean message', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain'}, {'type': 'application/pdf', 'filename': 'r5.pdf', 'disp': 'attachment', 'size': 10}]}, ['exe'], 100), ['keep', 'keep'])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| double extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| upper-case padded extension | ['keep', 'strip'] | ['keep', 'strip'] | Passed |
| blocked part inside signed mixed | reject | reject | Passed |
| large body and named inline part | ['keep', 'strip', 'strip'] | ['keep', 'strip', 'strip'] | Passed |
| size boundaries | ['keep', 'keep', 'strip'] | ['keep', 'keep', 'strip'] | Passed |
| executable type in signed | reject | reject | Passed |
| clean message | ['keep', 'keep'] | ['keep', 'keep'] | Passed |
SHA-256 / c75af58699560d6615527b9c35088db3b69d568b971b5a0fb01e61f37640e16a
Verification & scope
Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:19.743738+00:00.
Case digest / c0459812a8982a6a6752da662333c25a05a166d0d8ecf14e8b0c366afce4b179