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.

Unhandled TypeError (float(None)) in PMMLLinearRegression when a RegressionModel NumericPredictor omits the coefficient attribute (load-time DoS)

Target

  • Package: sklearn-pmml-model (PyPI: sklearn-pmml-model)
  • Version tested: 1.0.8 (latest release at time of report)
  • Affected file: sklearn_pmml_model/linear_model/implementations.py
  • Affected APIs: PMMLLinearRegression(...) (and PMMLLogisticRegression via the same non-segment _get_coefficients path)
  • Vector: attacker-supplied PMML file parsed at model-construction time.
  • Impact: Denial of service. Loading an untrusted PMML file raises an unhandled TypeError, crashing the caller. There is no try/except around model construction.

Root cause

_get_coefficients() builds the coefficient vector by mapping each field to coefficients_for_field(name, field). For a continuous (non-categorical) field the code parses the predictor's coefficient with a raw float(...) on the result of ElementTree's .get('coefficient'):

def coefficients_for_field(name, field):
    predictors = table.findall(f"*[@name='{name}']")

    if field.get('optype') != 'categorical':
      if len(predictors) > 1:
        raise Exception('PMML model is not linear.')

      return [float(predictors[0].get('coefficient'))]   # <-- line 177
    ...

  return list(chain.from_iterable([
    coefficients_for_field(name, field)
    for name, field in est.fields.items()
    if table.find(f"*[@name='{name}']") is not None       # <-- guard, line 187
  ]))

ElementTree's Element.get('coefficient') returns None when the attribute is absent. The guard on line 187 (table.find(f"*[@name='{name}']") is not None) only checks that a predictor element with the matching name exists β€” it does not validate that the predictor carries a coefficient attribute. A <NumericPredictor name="x1"/> therefore passes the guard, reaches line 177, and evaluates float(None), which raises:

TypeError: float() argument must be a string or a real number, not 'NoneType'

The value is entirely attacker-controlled from the PMML document, and model construction has no exception handling, so the exception propagates out of the PMMLLinearRegression(...) constructor and crashes any application that loads an untrusted PMML model.

Proof of concept

Two minimal PMML files are included.

linreg-baseline.pmml β€” a well-formed RegressionModel (functionName="regression") with DataDictionary fields y (target) and x1, and one RegressionTable containing <NumericPredictor name="x1" coefficient="1.5"/>.

linreg-nocoef.pmml β€” identical, except the coefficient attribute is stripped from the NumericPredictor (<NumericPredictor name="x1"/>). This is the only difference between the two files.

from sklearn_pmml_model.linear_model import PMMLLinearRegression

# Negative control: loads fine
m = PMMLLinearRegression("linreg-baseline.pmml")
print("loaded OK; coef_=", m.coef_, "intercept_=", m.intercept_)

# Malicious: single missing attribute -> crash
PMMLLinearRegression("linreg-nocoef.pmml")

The negative control proves the crash is caused solely by the single missing coefficient attribute, not by any other malformation in the file.

Captured evidence (verbatim, sklearn-pmml-model 1.0.8, CPython 3.13)

=== NEGATIVE CONTROL: baseline ===
loaded OK; coef_= [1.5] intercept_= 0.0

=== MALICIOUS: NumericPredictor missing coefficient ===
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
  File ".../sklearn_pmml_model/linear_model/implementations.py", line 44, in __init__
    _get_coefficients(self, table)
  File ".../sklearn_pmml_model/linear_model/implementations.py", line 185, in _get_coefficients
    coefficients_for_field(name, field)
  File ".../sklearn_pmml_model/linear_model/implementations.py", line 177, in coefficients_for_field
    return [float(predictors[0].get('coefficient'))]
            ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: float() argument must be a string or a real number, not 'NoneType'

Suggested fix

Validate the coefficient attribute before conversion and raise a clear, caught PMML-parsing error (or default per the PMML spec, where a missing coefficient is not permitted for a NumericPredictor). For example, read the attribute, and if it is None raise a descriptive ValueError/parsing exception rather than letting float(None) throw a bare TypeError. The same hardening should be applied to coefficient_for_category (float(predictor[0].get('coefficient'))) on the categorical branch.

Dedup note

  • No CVE is known for this specific defect. This is a distinct code path from the other sklearn-pmml-model findings previously reported by this researcher:
    • SparseArray index/DoS issues (_parse_array / SVM) β€” different parser.
    • PMMLLogisticRegression segment OOB β€” segment-branch indexing, not the non-segment _get_coefficients float(None) path.
    • GLM beta TypeError (GeneralRegressionModel) β€” a different estimator and a different attribute in a different implementation file.
    • Tree/forest/NaiveBayes/kNN/NeuralNetwork findings β€” unrelated model types. This report is specifically the RegressionModel NumericPredictor missing coefficient -> float(None) TypeError in linear_model/implementations.py line 177, reachable via PMMLLinearRegression and PMMLLogisticRegression's non-segment branch.
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