Along with the root cause, which is the `StringConstCompare`
BarrierGuard, that does only allows `in <iterable literal>` and not
`in <variable referencing iterable literal>`
Before, results from `dca` would look something like
## + py/meta/alerts/remote-flow-sources-reach
- django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:16:38:48
reachable with taint-tracking from RemoteFlowSource
- django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:9:38:12
reachable with taint-tracking from RemoteFlowSource
now it should make it easier to spot _what_ it is that actually changed,
since we pretty-print the node.
The meat of this PR is described in the new python/ql/test/experimental/meta/InlineTaintTest.qll file:
> Defines a InlineExpectationsTest for checking whether any arguments in
> `ensure_tainted` and `ensure_not_tainted` calls are tainted.
>
> Also defines query predicates to ensure that:
> - if any arguments to `ensure_not_tainted` are tainted, their annotation is marked with `SPURIOUS`.
> - if any arguments to `ensure_tainted` are not tainted, their annotation is marked with `MISSING`.
>
> The functionality of this module is tested in `ql/test/experimental/meta/inline-taint-test-demo`.
This required a minor change in the type tracker implementation, but
apart from that no other changes appear to be needed. Seems to clean
up the test output quite a bit.
Since predicate name `import` is not allowed, I adopted `importNode` as it sort
of matches what `exprNode` does.
---
Due to only using `importMember` in `os_attr` we previously didn't handle
`import os.path as alias` :|
I did creat a hotfix for this (https://github.com/github/codeql/pull/4446), but
in doing so I realized the core of the problem: We're exposing ourselves to
making these kinds of mistakes by having BOTH importModule and importMember, and
we don't really gain anything from doing this!
We do loose the ability to easily only modeling `from mod import val` and not
`import mod.val`, but I don't think that will ever be relevant.
This change will also make us to recognize some invalid code, for example in
import os.system as runtime_error
we would now model that `runtime_error` is a reference to the `os.system`
function (although the actual import would result in a runtime error).
Overall these are tradeoffs I'm willing to make, as it does makes things simpler
from a QL modeling point of view, and THAT sounds nice 👍
This is not a very good test for showing that we don't handle direct imports,
but it was the best I had available without inventing something new. It's very
fragile, since any of these would propagate taint (due to handling all `join`
calls as if the qualifier was a string):
ospath_alias.join(ts)
ospath_alias.join(ts, "foo", "bar")
But this test DOES serve the purpose of illustrating that my fix works :D