Commit Graph

768 Commits

Author SHA1 Message Date
Rasmus Wriedt Larsen
9151a7e433 Python: Always enable legacy taint tracking configuration
If the legacy configuration is only enabled if there are no other
configurations, defining a configuration in an imported library can lead to
unwanted results. For example, code that uses `any(MyTaintKind t).taints(node)`
would *stop* working, if it did not define its own configuration. (this actually
happened to us)

We performed a dist-compare to ensure there is not a performance deg ration by
doing this. Results at https://git.semmle.com/gist/rasmuswl/a1eca07f3a92f5f65ee78d733e5d260e

Tests that were affected by this:

- RockPaperScissors + Simple: new edges because no configuration was defined for
  SqlInjectionTaint or CommandInjectionTaint
- CleartextLogging + CleartextStorage: new edges because no configuration was
  defined before, AND duplicate deges.
- TestNode: new edges because no configuration was defined before

- PathInjection: Duplicate edges
- TarSlip: Duplicate edges
- CommandInjection: Duplicate edges
- ReflectedXss: Duplicate edges
- SqlInjection: Duplicate edges
- CodeInjection: Duplicate edges
- StackTraceExposure: Duplicate edges
- UnsafeDeserialization: Duplicate edges
- UrlRedirect: Duplicate edges
2019-11-11 11:17:21 +01:00
Felicity Chapman
c4f958d396 Merge pull request #2263 from sauyon/master
Update links to OWASP cheat sheet
2019-11-11 08:51:52 +00:00
Rasmus Wriedt Larsen
358964b1e2 Python: Accept changes in Python 2 specific six tests
We don't use a locked-down version of six, so some internal things probably
changed from the version used last time, and the versoin I have installed.

Long term fix would be to use a specific version of six for tests!
2019-11-08 13:49:52 +01:00
Rasmus Wriedt Larsen
6c259e5608 Python: Temporarily accept changes in Python 2 specific MRO tests
Due to internal PR#35123 we now actually run the tests under
`python/ql/test/2/...`

These seems like a regression, since the tests state that N is ok, but A and J
should not be allowed.

For now we can accept them, so we don't block all other Python PRs
2019-11-08 13:48:21 +01:00
Rasmus Wriedt Larsen
89a13213e2 Python: Accept changes in Python 2 specific tests
Due to internal PR#35123 we now actually run the tests under
`python/ql/test/2/...`

Since we haven't done this in a while, test output has changed a bit. These
changes look perfectly fine.
2019-11-08 13:48:14 +01:00
Rasmus Wriedt Larsen
9ffb67a460 Merge pull request #2266 from tausbn/python-multiple-calls-to-init-join-order-fix
Python: Fix bad join order for `py/multiple-calls-to-init`.
2019-11-07 15:38:43 +01:00
Sauyon Lee
0040c9fb4c Update links to OWASP cheat sheet 2019-11-06 20:21:47 -08:00
semmle-qlci
717490b670 Merge pull request #2265 from tausbn/python-fix-unused-import-global-name-used-join-order
Approved by RasmusWL
2019-11-06 16:38:07 +00:00
Taus Brock-Nannestad
2b24eb2e70 Python: Fix bad join order for py/multiple-calls-to-init.
The `multiple_invocation_paths` predicate had a bad join order where
we (essentially) joined `i1` with `i2` and only then joined `i1` and `i2`
separately to reduce the number of tuples. The join coming from `i1 != i2` had
little impact, but `i1.getFunction() = multi` made a big difference (and
similarly for `i2`). I factored out the code so that these joins would be done
more eagerly. Thus, we went from

```
[2019-11-06 16:53:05] (38s) Starting to evaluate predicate MethodCallOrder::multiple_invocation_paths#ffff/4@2ce75a
[2019-11-06 16:53:35] (68s) Tuple counts for MethodCallOrder::multiple_invocation_paths#ffff:
                      134547    ~9%       {2} r1 = SCAN CallGraph::TInvocation#fff AS I OUTPUT I.<0>, I.<2>
                      235284431 ~3%       {4} r2 = JOIN r1 WITH CallGraph::TInvocation#fff AS R ON FIRST 1 OUTPUT r1.<0>, r1.<1>, R.<1>, R.<2>
                      235149884 ~3%       {4} r3 = SELECT r2 ON r2.<3> != r2.<1>
                      235149884 ~4%       {3} r4 = SCAN r3 OUTPUT r3.<1>, r3.<0>, r3.<3>
                      166753634 ~5%       {4} r5 = JOIN r4 WITH #CallGraph::FunctionInvocation::getACallee_dispred#ffPlus#swapped AS R ON FIRST 1 OUTPUT R.<1>, r4.<2>, r4.<1>, r4.<0>
                      129778    ~0%       {4} r6 = JOIN r5 WITH #CallGraph::FunctionInvocation::getACallee_dispred#ffPlus AS R ON FIRST 2 OUTPUT r5.<0>, r5.<3>, r5.<1>, r5.<2>
                                          return r6
[2019-11-06 16:53:35] (68s) Registering MethodCallOrder::multiple_invocation_paths#ffff + [] with content 1705dcbc08kd9aa40rp2g2e9civhv
[2019-11-06 16:53:35] (68s)  >>> Wrote relation MethodCallOrder::multiple_invocation_paths#ffff with 129778 rows and 4 columns.
```

to

```
[2019-11-06 17:22:22] (25s) Starting to evaluate predicate MethodCallOrder::multiple_invocation_paths_helper#ffff/4@586aec
[2019-11-06 17:22:22] (25s) Tuple counts for MethodCallOrder::multiple_invocation_paths_helper#ffff:
                      134547 ~0%     {2} r1 = SCAN CallGraph::TInvocation#fff AS I OUTPUT I.<2>, I.<0>
                      88111  ~4%     {3} r2 = JOIN r1 WITH #CallGraph::FunctionInvocation::getACallee_dispred#ffPlus#swapped AS R ON FIRST 1 OUTPUT R.<1>, r1.<1>, r1.<0>
                      761305 ~0%     {4} r3 = JOIN r2 WITH #CallGraph::FunctionInvocation::getACallee_dispred#ffPlus AS R ON FIRST 1 OUTPUT r2.<1>, r2.<2>, r2.<0>, R.<1>
                      673194 ~0%     {4} r4 = SELECT r3 ON r3.<3> != r3.<1>
                      673194 ~0%     {4} r5 = SCAN r4 OUTPUT r4.<2>, r4.<1>, r4.<3>, r4.<0>
                                     return r5
[2019-11-06 17:22:22] (25s) Registering MethodCallOrder::multiple_invocation_paths_helper#ffff + [] with content 20edaaecf25nldgp24d9c4et8m3kv
[2019-11-06 17:22:22] (25s)  >>> Wrote relation MethodCallOrder::multiple_invocation_paths_helper#ffff with 673194 rows and 4 columns.
[2019-11-06 17:22:22] (25s) Starting to evaluate predicate MethodCallOrder::multiple_invocation_paths_helper#ffff_2301#join_rhs/4@9e5441
[2019-11-06 17:22:22] (25s) Tuple counts for MethodCallOrder::multiple_invocation_paths_helper#ffff_2301#join_rhs:
                      673194 ~0%     {4} r1 = SCAN MethodCallOrder::multiple_invocation_paths_helper#ffff AS I OUTPUT I.<2>, I.<3>, I.<0>, I.<1>
                                     return r1
[2019-11-06 17:22:22] (25s) Registering MethodCallOrder::multiple_invocation_paths_helper#ffff_2301#join_rhs + [] with content 2069301e655fi9mcovngg9hetfqas
[2019-11-06 17:22:22] (25s)  >>> Wrote relation MethodCallOrder::multiple_invocation_paths_helper#ffff_2301#join_rhs with 673194 rows and 4 columns.
[2019-11-06 17:22:22] (25s) Starting to evaluate predicate MethodCallOrder::multiple_invocation_paths#ffff/4@2f7c34
[2019-11-06 17:22:22] (25s) Tuple counts for MethodCallOrder::multiple_invocation_paths#ffff:
                      134547 ~0%     {2} r1 = SCAN CallGraph::TInvocation#fff AS I OUTPUT I.<2>, I.<0>
                      129778 ~0%     {4} r2 = JOIN r1 WITH MethodCallOrder::multiple_invocation_paths_helper#ffff_2301#join_rhs AS R ON FIRST 2 OUTPUT R.<2>, R.<3>, r1.<0>, r1.<1>
                                     return r2
[2019-11-06 17:22:22] (25s) Registering MethodCallOrder::multiple_invocation_paths#ffff + [] with content 1705dcbc08kd9aa40rp2g2e9civhv
[2019-11-06 17:22:22] (25s)  >>> Wrote relation MethodCallOrder::multiple_invocation_paths#ffff with 129778 rows and 4 columns.
[2019-11-06 17:22:22] (25s) Starting to evaluate predicate MethodCallOrder::multiple_invocation_paths#ffff_0312#join_rhs/4@9f9146
[2019-11-06 17:22:22] (25s) Tuple counts for MethodCallOrder::multiple_invocation_paths#ffff_0312#join_rhs:
                      129778 ~0%     {4} r1 = SCAN MethodCallOrder::multiple_invocation_paths#ffff AS I OUTPUT I.<0>, I.<3>, I.<1>, I.<2>
                                     return r1
[2019-11-06 17:22:22] (25s) Registering MethodCallOrder::multiple_invocation_paths#ffff_0312#join_rhs + [] with content 17c3fe1fcbf6ghhdr7hiukqp41rst
[2019-11-06 17:22:22] (25s)  >>> Wrote relation MethodCallOrder::multiple_invocation_paths#ffff_0312#join_rhs with 129778 rows and 4 columns.
```

Execution time on `salt` went from 29.5s to somewhere below 299ms (the predicate
was not listed in the timing report).
2019-11-06 17:27:03 +01:00
Taus Brock-Nannestad
43148083eb Python: Fix bad join order for global_name_used.
As it turns out, there was a further bad join-order in the `global_name_used`
predicate. In this case, there was a common subexpression in the RA that was
being factored out and evaluated separately, producing a large number of tuples.
2019-11-06 16:37:01 +01:00
Taus Brock-Nannestad
b6f16dee81 Python: Fix bad join order in py/unused-import 2019-11-06 15:14:48 +01:00
Taus
e9336fe30e Merge pull request #2129 from RasmusWL/python-update-django
Python: update django support
2019-11-05 20:51:55 +01:00
Taus
aa7a997c7a Merge pull request #2248 from RasmusWL/python-sensitive-data-fewer-fp
Python: Limit what functions we treat as returning sensitive data
2019-11-04 15:09:52 +01:00
Rasmus Wriedt Larsen
ca22ec6104 Merge pull request #2042 from tausbn/python-fix-unused-import-fps
Python: Fix false positives in `py/unused-import`.
2019-11-04 14:47:30 +01:00
Rasmus Wriedt Larsen
b075103198 Merge pull request #2163 from tausbn/python-undefined-export-fp
Python: Modernise and fix FP in `py/undefined-export`
2019-11-04 13:10:48 +01:00
Rasmus Wriedt Larsen
6593477d0b Python: Limit what functions we treat as returning sensitive data
Before this change, any function that has a parameter that was called
password/credentials would be treated as returning sensitive data of that
kind. `py/clear-text-logging-sensitive-data` would alert if one of these are
logged, which has a LOT of false-positives.
2019-11-04 11:32:21 +01:00
Taus Brock-Nannestad
d2f985038c Python: Fix missing modernisation. 2019-11-04 10:48:42 +01:00
Luke Cartey
d9d4aa30a9 Merge pull request #2214 from hmakholm/pr/upgrade-packs
Make each upgrade directory a QL pack
2019-10-29 16:45:02 +00:00
Taus Brock-Nannestad
5e62da7690 Python: Do not report unreachable "catch-all" cases in elif-chains.
This was brought up on the LGTM.com forums here:
https://discuss.lgtm.com/t/warn-when-always-failing-assert-is-reachable-rather-than-unreachable/2436

Essentially, in a complex chain of `elif` statements, like

```python
if x < 0:
    ...
elif x >= 0:
    ...
else:
    ...
```

the `else` clause is redundant, since the preceding conditions completely
exhaust the possible values for `x` (assuming `x` is an integer). Rather than
promoting the final `elif` clause to an `else` clause, it is common to instead
raise an explicit exception in the `else` clause. During execution, this
exception will never actually be raised, but its presence indicates that the
preceding conditions are intended to cover all possible cases.

I think it's a fair point. This is a clear instance where the alert, even if it
is technically correct, is not useful for the end user.

Also, I decided to make the exclusion fairly restrictive: it only applies if
the unreachable statement is an `assert False, ...` or `raise ...`, and only
if said statement is the first in the `else` block. Any other statements will
still be reported.
2019-10-29 15:30:32 +01:00
Rasmus Wriedt Larsen
fc851b46c3 Python: Fix Django class-based views 2019-10-29 13:58:07 +01:00
Rasmus Wriedt Larsen
fb864b7262 Python: Consolidate tests for django
The tests in 3/ was not Python 3 specific anymore
2019-10-29 13:58:07 +01:00
Rasmus Wriedt Larsen
91f269ed7b Python: Remove unused django sinks
This would find instances of `thing = MyThing.objects.get(field=userinput)`, and
what seems to be a query that wants to match on `thing = MyThing();
thing.field=userinput`. Both are not vulnerable to user-input, due to the
build-in escaping by django.

The DjangoModelFieldWrite actually matches on `MyThing.field=userinput` and not
`thing.field=userinput`. I suspect this to be a mistake.

Matching on `thing.field=userinput`, would require this CodeQL:

attr.getObject(_).pointsTo().getClass() = model
2019-10-29 13:58:07 +01:00
Rasmus Wriedt Larsen
471318369b Python: Don't quote %s in django example
This is vulnerable to SQL injection because of the quotes around %s -- added
some code that highlights this in test.py

Since our examples did this in the safe query, I ended up rewriting them
completely, causing a lot of trouble for myself :D
2019-10-29 13:58:07 +01:00
Rasmus Wriedt Larsen
afe7a0536c Python: Support positional arguments in Django routes 2019-10-29 13:58:07 +01:00
Rasmus Wriedt Larsen
49dd2216a6 Python: Refactor django library
Use General.qll for routing, like in other web libraries
2019-10-29 13:58:07 +01:00
Taus
6e6dab9ab8 Merge pull request #2178 from RasmusWL/python-minor-qldoc-fix
Python: Fix qldoc for TaintTracking Configuration
2019-10-29 10:40:12 +01:00
Henning Makholm
ae554cf1e9 Make each upgrade directory a QL pack 2019-10-28 17:14:31 +01:00
Taus
04e3683035 Merge pull request #2194 from RasmusWL/python-improve-getbasetype-qldoc
Python: Improve qldoc for ClassValue::getABaseType
2019-10-28 17:07:19 +01:00
Rasmus Wriedt Larsen
f1004b10ba Merge pull request #2147 from tausbn/python-cyclic-import-package-fp
Python: Fix cyclic import FP relating to packages.
2019-10-25 11:57:55 +02:00
Rasmus Wriedt Larsen
c50d366527 Python: Improve qldoc for ClassValue::getABaseType
Hopefully it is more clear that you can get multiple results from getABaseType
because of multiple inheritance, and not because we are following the chain of
inheritance
2019-10-24 17:10:42 +02:00
Rasmus Wriedt Larsen
8767d29d21 Python: Use src for naming in TaintTrackign::Configuration
We picked `src` since this is used much more than `source` in our existing code.
2019-10-23 15:56:37 +02:00
Taus
30483db621 Merge pull request #2146 from RasmusWL/python-improve-iter-returns-non-iterator
Python: improve py/iter-returns-non-iterator
2019-10-23 11:53:00 +02:00
Rasmus Wriedt Larsen
5c5eaacc09 Python: Remove cached annotation in py/iter-returns-non-iterator 2019-10-23 10:46:07 +02:00
Rasmus Wriedt Larsen
a98466392d Python: Improve tests and docs for py/iter-returns-non-iterator 2019-10-23 10:46:07 +02:00
Henning Makholm
347d97c14c qlpack.json is now qlpack.yml 2019-10-22 17:36:35 +02:00
Pavel Avgustinov
72de1b25ab Merge pull request #2164 from hmakholm/suites
Add some new-style suite definitions
2019-10-22 16:35:19 +01:00
Taus
a19569ce3e Merge pull request #2161 from RasmusWL/python-fix-cookieset-tostring
Python: Fix toString for CookieSet classes
2019-10-22 16:48:31 +02:00
Henning Makholm
fd768a1af6 Add some new-style suite definitions 2019-10-22 15:51:00 +02:00
Taus Brock-Nannestad
32de65c0c6 Python: Add discussed test case (a false negative). 2019-10-22 15:10:40 +02:00
Taus Brock-Nannestad
83bf54c524 Python: Move false positive (now a true negative) into subfolder. 2019-10-22 15:08:29 +02:00
Rasmus Wriedt Larsen
e487fd3648 Python: Improve alert message for py/iter-returns-non-iterator
Fixes https://github.com/Semmle/ql/issues/1427
2019-10-22 10:27:55 +02:00
Rasmus Wriedt Larsen
6056b457e9 Python: Autoformat py/iter-returns-non-iterator 2019-10-22 10:25:01 +02:00
Taus Brock-Nannestad
ab2c8f312c Python: Apply autoformat. 2019-10-21 17:40:36 +02:00
Taus Brock-Nannestad
4fe1ba0ea4 Python: Refactor py/undefined-export for more clarity. 2019-10-21 17:40:36 +02:00
Taus Brock-Nannestad
8a1d1e7b7a Python: Modernise and false positive in py/undefined-export. 2019-10-21 16:07:48 +02:00
Rasmus Wriedt Larsen
016c95a69c Merge pull request #2078 from taus-semmle/python-unreachable-suppressed
Python: Teach `py/unreachable-statement` about `contextlib.suppress`.
2019-10-21 15:14:39 +02:00
Taus Brock-Nannestad
b2f7b0921b Python: Add false negative test case. 2019-10-21 14:31:05 +02:00
Taus Brock-Nannestad
99b99ef2b6 Python: Teach py/unreachable-statement about contextlib.suppress. 2019-10-21 14:31:05 +02:00
Rasmus Wriedt Larsen
9cf0e244b1 Python: Fix toString for CookieSet classes
The old implementation would result in empty recursion.
2019-10-21 11:26:10 +02:00
Taus
45158a7177 Merge pull request #2053 from RasmusWL/python-modernise-falcon-library
Python modernise falcon library
2019-10-18 14:47:33 +02:00