Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset python/PYTHON-LANG-SEC-006 --project .About This Rule
Understanding the vulnerability and how it is detected
Python's typing.get_type_hints() resolves type annotations by evaluating string annotations (also known as PEP 563 postponed annotations) using eval() in the context of the annotated object's module namespace. When from __future__ import annotations is used or annotations are stored as string literals, get_type_hints() calls eval() on those strings to resolve them.
If annotations are dynamically constructed or sourced from untrusted data, an attacker can inject arbitrary Python expressions into the annotation string that will be evaluated when get_type_hints() is called. This is particularly relevant in frameworks that use annotations for serialization, validation, or ORM field definitions and call get_type_hints() at runtime.
In most applications, get_type_hints() is called on developer-controlled class definitions and poses no direct risk. The risk arises when annotation strings are generated dynamically from external input or when get_type_hints() is called on classes loaded from untrusted sources.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Annotation String Evaluation
With from __future__ import annotations enabled, all annotations are stored as strings and evaluated lazily. get_type_hints() calls eval() on these strings. If annotation strings can be influenced by an attacker, this becomes an eval injection vulnerability.
Framework-Level Risk in Pydantic and Dataclasses
Frameworks such as pydantic, dataclasses, and attrs call get_type_hints() to resolve field types. If these frameworks process class definitions constructed from external data, the annotation evaluation can be exploited. This is a known risk in dynamic schema generation.
Serialization and ORM Reflection Attacks
ORMs and serialization libraries that use annotations to determine field types and call get_type_hints() for schema reflection can be attacked via malicious annotation strings in serialized object metadata.
Plugin and Extension Loading
Systems that dynamically load classes from user-specified modules and then call get_type_hints() on those classes for introspection may execute malicious annotation expressions defined in attacker-controlled plugin code.
How to Fix
Recommended remediation steps
- 1Only call get_type_hints() on classes and functions defined in trusted, version-controlled source code.
- 2Never construct annotation strings dynamically from external input or store annotation strings in untrusted data sources.
- 3When building dynamic schemas from external configuration, use typing constructs as Python objects (str, int, List[str]) rather than string representations.
- 4Audit frameworks that call get_type_hints() on plugin or user-defined classes to ensure annotation content cannot be influenced by attackers.
- 5Consider using inspect.get_annotations() in Python 3.10+ for lower-level annotation access that avoids the eval() behavior in specific contexts.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule detects calls to typing.get_type_hints() and the unqualified form get_type_hints() in Python source code. The rule flags all call sites for review since the safety depends on the trust level of the object passed as the argument, which requires human review to determine.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Python
Dangerous eval() Usage Detected
eval() executes arbitrary Python expressions from strings, enabling remote code execution when called with untrusted input.
Dangerous exec() Usage Detected
exec() executes arbitrary Python statements from strings or code objects, enabling remote code execution when called with untrusted input.
Non-literal Dynamic Import Detected
__import__() or importlib.import_module() with a non-literal argument can import arbitrary modules when called with untrusted input.
Frequently Asked Questions
Common questions about Dangerous typing.get_type_hints() Usage
New feature
Get these findings posted directly on your GitHub pull requests
The Dangerous typing.get_type_hints() Usage rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.