Skip to content

Python PEP249: track connections stored in class instance attributes#21889

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/investigate-sql-injection-issue
Draft

Python PEP249: track connections stored in class instance attributes#21889
Copilot wants to merge 2 commits into
mainfrom
copilot/investigate-sql-injection-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 21, 2026

SQL injection (and other PEP 249-based) queries miss findings when a connect() result is stored in a class attribute (self._conn) and later accessed via a getter method or direct attribute read — the TypeTracker cannot follow the value through __init__ because ReturnStep is blocked after a CallStep.

Changes

python/ql/lib/semmle/python/frameworks/PEP249.qll

  • classStoresConnectionInInit(cls, attrName) — detects self.<attr> = dbapi.connect(...) in __init__
  • ConnectionGetterAttributeRead (InstanceSource) — marks self._conn reads inside non-__init__ methods as connection sources. The AttrRead node for return self._conn is simultaneously the function's ExtractedReturnNode, so the existing returnStep propagates the type to all call sites for free
  • ConnectionConstructorAttributeRead (InstanceSource) — marks MyClass()._conn direct attribute reads as connection sources, using DataFlowDispatch::resolveClassCall to confirm the constructor targets the right class

python/ql/test/library-tests/frameworks/hdbcli/pep249.py — test cases for the new patterns

python/ql/src/change-notes/2026-05-21-pep249-class-wrapper-connections.md — change note

Patterns now covered

class DatabaseConnection:
    def __init__(self):
        self._conn = dbapi.connect(...)

    def get_conn(self):
        return self._conn  # now an InstanceSource

hdb_con2 = DatabaseConnection().get_conn()  # tracked via returnStep
hdb_con3 = DatabaseConnection()._conn       # tracked as InstanceSource directly

db = DatabaseConnection()
db.get_conn().cursor().execute(query)       # full chain detected

Copilot AI added 2 commits May 21, 2026 23:22
Introduce two new Connection::InstanceSource subclasses in PEP249.qll:

- ConnectionGetterAttributeRead: recognises self._conn reads inside
  getter methods of classes whose __init__ stores a connect() call in
  that attribute. The AttrRead node coincides with the return node, so
  the existing TypeTracker returnStep propagates the connection type to
  all call sites automatically.

- ConnectionConstructorAttributeRead: recognises ClassName()._conn
  direct attribute reads on constructor-call results.

Both classes share the classStoresConnectionInInit helper predicate
that checks for the self.attr = dbapi.connect() store pattern in __init__.

Also adds test cases for the new patterns in the hdbcli test suite
and a change note.
Copilot AI changed the title Fix PEP249 connection tracking through class attribute wrappers Python PEP249: track connections stored in class instance attributes May 21, 2026
Copilot AI requested a review from owen-mc May 21, 2026 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants