Implementation:Protectai Modelscan OperatorIssueDetails
| Knowledge Sources | |
|---|---|
| Domains | ML_Security, Static_Analysis |
| Last Updated | 2026-02-14 12:00 GMT |
Overview
Concrete tool for recording and serializing detected unsafe operator details found during model scanning, provided by the modelscan issues module.
Description
OperatorIssueDetails is the concrete implementation of the abstract IssueDetails class. It captures the full context of a detected unsafe operator: the Python module containing the operation, the specific operator name, the severity level, the source file path, and the scanner that produced the finding. It provides both human-readable output (output_lines()) and machine-parseable output (output_json()) for use in console and JSON reports respectively.
Usage
Use this class when:
- Implementing a custom scanner that needs to report detected unsafe operators
- Processing scan results programmatically and accessing operator details
- Understanding the data model behind modelscan findings
Code Reference
Source Location
- Repository: modelscan
- File: modelscan/issues.py
- Lines: L126-159
Signature
class OperatorIssueDetails(IssueDetails):
def __init__(
self,
module: str,
operator: str,
severity: IssueSeverity,
source: Union[Path, str],
scanner: str = "",
) -> None:
"""
Args:
module: Python module containing the unsafe operation (e.g., "os", "subprocess").
operator: Specific function/class name (e.g., "system", "Popen").
severity: Severity level from IssueSeverity enum.
source: File path where the operator was detected.
scanner: Fully-qualified scanner class name that produced this finding.
"""
def output_lines(self) -> List[str]:
"""
Return human-readable description lines.
Format:
"Description: Use of unsafe operator '{operator}' from module '{module}'"
"Source: {source}"
"""
def output_json(self) -> Dict[str, str]:
"""
Return JSON-serializable dict with keys:
description, operator, module, source, scanner, severity
"""
Import
from modelscan.issues import OperatorIssueDetails, IssueSeverity
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| module | str | Yes | Python module name containing the unsafe operator (e.g., "os", "subprocess", "builtins") |
| operator | str | Yes | Specific function or class name (e.g., "system", "exec", "Popen") |
| severity | IssueSeverity | Yes | Severity level (LOW, MEDIUM, HIGH, CRITICAL) |
| source | Union[Path, str] | Yes | File path where the operator was found |
| scanner | str | No | Fully-qualified scanner class name (set by ScanBase.label_results()) |
Outputs
| Name | Type | Description |
|---|---|---|
| output_lines() | List[str] | Two-line human-readable description: description line and source line |
| output_json() | Dict[str, str] | JSON dict with keys: description, operator, module, source, scanner, severity |
Usage Examples
Creating an Issue with OperatorIssueDetails
from modelscan.issues import Issue, IssueCode, IssueSeverity, OperatorIssueDetails
# Create an issue for a detected os.system call
issue = Issue(
code=IssueCode.UNSAFE_OPERATOR,
severity=IssueSeverity.CRITICAL,
details=OperatorIssueDetails(
module="os",
operator="system",
severity=IssueSeverity.CRITICAL,
source="/path/to/malicious_model.pkl",
),
)
# Human-readable output
for line in issue.details.output_lines():
print(line)
# Output:
# Description: Use of unsafe operator 'system' from module 'os'
# Source: /path/to/malicious_model.pkl
Accessing JSON Output
# Get machine-parseable output
json_data = issue.details.output_json()
# {
# "description": "Use of unsafe operator 'system' from module 'os'",
# "operator": "system",
# "module": "os",
# "source": "/path/to/malicious_model.pkl",
# "scanner": "",
# "severity": "CRITICAL"
# }
Using in a Custom Scanner
from modelscan.scanners.scan import ScanBase, ScanResults
from modelscan.issues import Issue, IssueCode, IssueSeverity, OperatorIssueDetails
from modelscan.model import Model
from typing import Optional
class MyScanner(ScanBase):
def scan(self, model: Model) -> Optional[ScanResults]:
issues = []
# Detection logic...
if detected_unsafe_operator:
issues.append(
Issue(
code=IssueCode.UNSAFE_OPERATOR,
severity=IssueSeverity.HIGH,
details=OperatorIssueDetails(
module="dangerous_module",
operator="dangerous_function",
severity=IssueSeverity.HIGH,
source=model.get_source(),
),
)
)
results = ScanResults(issues=issues, errors=[], skipped=[])
return self.label_results(results)