First fix handles the case where there's interference from a class-based
decorator on a function. In this case, _technically_ we have an instance
of the decorator class, but in practice this decorator will (hopefully)
forward all accesses to the thing it wraps.
The second fix has to do with methods that are added dynamically using
`setattr`. In this case, we cannot be sure that the relevant methods are
actually missing.
Uses the new `DuckTyping` module to handle recognising whether a class
is a container or not. Only trivial test changes (one version uses
"class", the other "Class").
Note that the ported query has no understanding of built-in classes. At
some point we'll likely want to replace `hasUnresolvedBase` (which will
hold for any class that extends a built-in) with something that's aware
of the built-in classes.
Looking at the results of the the previous DCA run, there was a bunch of
false positives where `bind` was being used with a `AF_UNIX` socket (a
filesystem path encoded as a string), not a `(host, port)` tuple. These
results should be excluded from the query, as they are not vulnerable.
Ideally, we would just add `.TupleElement[0]` to the MaD sink, except we
don't actually support this in Python MaD...
So, instead I opted for a more low-tech solution: check that the
argument in question flows from a tuple in the local scope.
This eliminates a bunch of false positives on `python/cpython` leaving
behind four true positive results.
This takes care of most of the false negatives from the preceding
commit.
Additionally, we add models for some known wrappers of `socket.socket`
from the `gevent` and `eventlet` packages.
Adds test cases from github/codeql#21582 demonstrating false negatives:
- Address stored in class attribute (`self.bind_addr`)
- `os.environ.get` with insecure default value
- `gevent.socket` (alternative socket module)
By limiting the results to the class that actually defines the `__del__`
method, we eliminate a bunch of FPs where a _subclass_ of such a class
would also get flagged.
For module-level metaclass declarations, we now also check that the
right hand side in a `__metaclass__ = type` assignment is in fact the
built-in `type`.
These could arguably be moved to `Class` itself, but for now I'm
choosing to limit the changes to the `DuckTyping` module (until we
decide on a proper API).
This module (which for convenience currently resides inside
`DataFlowDispatch`, but this may change later) contains convenience
predicates for bridging the gap between the data-flow layer and the old
points-to analysis.