PoC: onnxruntime Attention PrePack heap out-of-bounds read (malicious .onnx)
Target: microsoft/onnxruntime — CPU contrib op Attention (com.microsoft), used by BERT-family
and many transformer ONNX exports.
Format: ONNX (.onnx).
Class: CWE-125 heap out-of-bounds read at model-load time (during PrePack, before Run()).
Verified: official onnxruntime==1.27.0 pip wheel; source @ HEAD bb9ba7eba452791ac2e70c85044da96cf5555fe0 (2026-07-05).
What it is
Attention<T>::PrePack packs the weights initializer at session-init time. It derives the packing
row stride weight_matrix_col_size = q_hidden_size + k_hidden_size + v_hidden_size entirely from the
qkv_hidden_sizes node attribute, and never compares it against the real column count of the
weights initializer. It then calls MlasGemmPackB(head_size, input_hidden_size, weights_data, weight_matrix_col_size, ...), which reads input_hidden_size rows at that attacker-controlled stride.
Setting qkv_hidden_sizes far larger than the real weights tensor makes the pack walk gigabytes past
the buffer → heap OOB read → crash at load. The only validation tying qkv sizes to the real weights is
in AttentionBase::CheckInputs, which runs in Compute(), after PrePack.
Same class as the already-reported MatMulNBits::PrePack bug (attribute-trusts-over-initializer), in a
different, very widely used contrib op.
Files
attn_evil.onnx — malicious model: weights=[8,12] but qkv_hidden_sizes=[200000,200000,200000].
make_attention.py — regenerates evil + a benign control (python make_attention.py evil|benign out.onnx).
load.py — InferenceSession(model); prints LOADED OK if no crash.
CRASH_PROVEN.md — controlled experiment + lldb.
Run
1python3 -m venv v && ./v/bin/pip install onnx onnxruntime
2./v/bin/python load.py attn_evil.onnx # -> EXC_BAD_ACCESS / SIGBUS during session init (PrePack)
3./v/bin/python make_attention.py benign benign.onnx && ./v/bin/python load.py benign.onnx # -> LOADED OK
Coordinated-disclosure security PoC for the huntr AI/ML bug-bounty program. No payload; it only reads
out-of-bounds memory to demonstrate the parser flaw.