You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

ONNX Scaler scale β€” Numeric Transform Authority PoC

Affected Product: ONNX (.onnx) β€” Microsoft & Meta
Route: huntr MFV up to $4,000
Operator: ai.onnx.ml.Scaler
Attribute: scale
Verdict: REAL_ONNX_SCALER_T0_PASS β€” 9/9 assertions, 5/5 reproducibility


Summary

An ONNX model file contains a runtime-consumed ML preprocessing operator attribute (ai.onnx.ml.Scaler.scale) that controls the numeric scale factor applied to continuous input features before downstream scoring. A crafted ONNX model can mutate Scaler.scale while keeping all downstream LinearClassifier coefficients and intercepts byte-identical, causing the same numeric input to produce a different post-scaler tensor, different class scores, and a flipped prediction.

The ai.onnx.ml.Scaler applies unconditionally to every numeric input via the formula:

y[i] = (x[i] - offset[i]) * scale[i]

No sentinel trigger value is required. This distinguishes it from ai.onnx.ml.Imputer, which only acts when the input matches replaced_value_float. The Scaler authority gap affects all ordinary continuous numeric inputs.


Affected Product

  • Format: ONNX (.onnx)
  • Operator: ai.onnx.ml.Scaler (domain ai.onnx.ml, version 1)
  • Attribute: scale (FLOATS)
  • Runtime: onnxruntime (CPUExecutionProvider)
  • Maintainers: Microsoft & Meta

Vulnerability Details

The ai.onnx.ml.Scaler operator transforms continuous numeric inputs before passing them to downstream scoring operators. Its scale attribute (a float array) directly controls the magnitude and sign of each transformed feature value. Because ONNX model inspection tools and users typically examine downstream classifier weights (coefficients, intercepts, class labels) to assess model behavior, a mutation confined to Scaler.scale produces a prediction change that the downstream weights do not reveal.

Mutation applied:

Field clean.onnx mutant.onnx
Scaler.scale [-5.0] [+5.0] ← only change
Scaler.offset [0.0] [0.0] (identical)
LinearClassifier.coefficients [-1.0, 1.0] [-1.0, 1.0] (identical)
LinearClassifier.intercepts [0.0, 0.0] [0.0, 0.0] (identical)

Effect on inference:

Step clean.onnx mutant.onnx
Input [[1.0]] [[1.0]]
Post-scaler tensor [[-5.0]] [[+5.0]]
Scores [5.0, -5.0] [-5.0, 5.0]
Predicted label 0 1

The prediction flips from class 0 to class 1 with zero change to any downstream classifier weight.


Impact

A crafted ONNX model with a mutated Scaler.scale attribute will produce different inference output from an otherwise structurally identical model. A user or tool that audits model behavior by examining classifier coefficients, intercepts, and output labels will observe no difference between clean and mutant β€” the divergence occurs entirely in the preprocessing operator attribute before scoring.

This creates a pre-score numeric transform authority gap: the effective decision boundary of the model is determined not only by downstream classifier weights but also by the preprocessing operator attributes, which are not equivalently scrutinized.

This is not a claim of RCE, ACE, memory corruption, or scanner bypass as primary impact.


Proof of Concept

Requirements:

pip install onnx>=1.14.0 onnxruntime>=1.16.0 numpy>=1.24.0

Run reproduce script:

python reproduce_onnx_scaler_numeric_transform_flip.py

Expected output:

clean  label: 0, scores: [5.0, -5.0]
mutant label: 1, scores: [-5.0, 5.0]
reproducibility: clean 5/5=True, mutant 5/5=True
clean  SHA256: 490a7d7e2ac39079c0f9dec100e5aace96f3b98fd376a3b6c47487ed50a2b07c
mutant SHA256: e1134b7822b011ed76648dbe8c3a1870cf9503c379863769a1685c28b3c77598
A1: same input [[1.0]] used β†’ PASS
...
A9: prediction flip 0β†’1 (zero coefficient change) β†’ PASS
ONNX_SCALER_NUMERIC_TRANSFORM_FLIP_CONFIRMED

Run hash matrix inspector:

python inspect_onnx_scaler_hash_matrix.py

Expected output:

H1: clean scale != mutant scale β†’ PASS
H2: offset identical (clean == mutant) β†’ PASS
H3: coefficients identical β†’ PASS
H4: intercepts identical β†’ PASS
H5: post-scaler tensor differs β†’ PASS
...
H11: clean coef = [-1.0, 1.0] β†’ PASS
Total: 11/11
ONNX_SCALER_HASH_MATRIX_PASS

Runtime Evidence

Item Value
Operator ai.onnx.ml.Scaler
Mutated attribute scale (clean: [-5.0], mutant: [+5.0])
Unchanged attribute offset = [0.0] (byte-identical)
Input [[1.0]] (ordinary continuous numeric)
Post-scaler clean [[-5.0]]
Post-scaler mutant [[+5.0]]
LinearClassifier coefficients [-1.0, 1.0] (byte-identical)
LinearClassifier intercepts [0.0, 0.0] (byte-identical)
clean label 0, scores [5.0, -5.0]
mutant label 1, scores [-5.0, 5.0]
Prediction flip 0 β†’ 1
Reproducibility 5/5
clean SHA256 490a7d7e2ac39079c0f9dec100e5aace96f3b98fd376a3b6c47487ed50a2b07c
mutant SHA256 e1134b7822b011ed76648dbe8c3a1870cf9503c379863769a1685c28b3c77598
Assertions 9/9 PASS
Hash matrix 11/11 PASS

Distinctness from Prior Findings

This finding is distinct from all previously submitted ONNX and ML format findings:

Prior Finding Root Distinct from Scaler
ai.onnx.ml.Imputer.imputed_value_floats Sentinel replacement (triggers only when input == replaced_value_float) Scaler acts unconditionally on all inputs; different operator and trigger condition
ai.onnx.ml.OneHotEncoder.cats_strings Categorical column binding mutation Different operator; different input type (categorical string vs continuous numeric)
ai.onnx.ml.SVMClassifier.classlabels_strings Post-inference label rendering Acts after scoring; Scaler acts before scoring
TFLite NormalizationOptions FlatBuffer metadata normalization Different format (.tflite), different runtime (Task Library), different spec layer
SafeTensors preprocessor_config.json image_mean HF sidecar JSON image normalization Different format (sidecar JSON), different runtime, different modality (CV image)
Joblib CountVectorizer.vocabulary_ NLP token-to-column binding Different format (.joblib), different runtime, different operator class
SafeTensors tokenizer.json model.vocab NLP token-to-ID binding Different format (sidecar JSON), different runtime, different modality (NLP)

Non-Claims

This PoC does not claim:

  • Remote code execution (RCE)
  • Arbitrary code execution (ACE)
  • Memory corruption
  • Scanner bypass as primary impact
  • Class label string substitution (classlabels_strings)
  • Categorical feature binding (OneHotEncoder.cats_strings)
  • Sentinel-triggered replacement (Imputer.imputed_value_floats)
  • TFLite FlatBuffer normalization metadata manipulation
  • SafeTensors sidecar JSON preprocessing manipulation

The root claim is specifically: ONNX ai.onnx.ml.Scaler.scale pre-score numeric transform authority.


Recommendation

ONNX model auditing tools and consumers should validate preprocessing operator attributes (Scaler.scale, Scaler.offset) alongside downstream classifier weights when assessing model integrity. The Scaler.scale attribute directly controls the numeric values fed into downstream scoring and can flip predictions without any change to classifier coefficients or intercepts.


References

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support