Compare commits

...

947 Commits

Author SHA1 Message Date
Andrew Eisenberg
0e53ad33f6 Actions: Add permissions block to code scanning workflow 2021-04-26 10:53:29 -07:00
Andrew Eisenberg
3670c729c0 Actions: Use the main branch of the codeql action
This commit switches to the bleeding edge, main branch of the
codeql action. This helps us test the action before merging all
of the new changes into main, which occurs roughly once a week.

If there are commits that introduce bugs in codeql-action, then
we will be more likely to catch it before releasing to the world
if we are using it in this extension.
2021-04-26 08:43:28 -07:00
Shati Patel
a09c12acfe Merge pull request #5537 from alexet/ambig-super
Docs: Update the language specification for changes to super.
2021-04-26 13:34:50 +01:00
Tamás Vajk
a7030c7fed Merge pull request #5308 from tamasvajk/feature/flow-sources-sinks
C#: Add Console.Read* to local flow sources
2021-04-23 16:36:16 +02:00
Tamás Vajk
c3058f4744 Merge pull request #5749 from tamasvajk/feature/fix-fromsource
C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file
2021-04-23 16:35:40 +02:00
Shati Patel
6f2103f312 Merge pull request #5722 from github/tamasvajk-patch-1
C#: Add Dapper to supported frameworks
2021-04-23 14:32:22 +01:00
Jonas Jensen
9b5bb95766 Merge pull request #5696 from jbj/reapply-inconsistency-workaround
Revert "Revert "C++: Work around extractor issue CPP-383""
2021-04-23 14:49:32 +02:00
Anders Schack-Mulligen
bc8c55836a Merge pull request #5743 from aschackmull/java/flow-summary-tweaks
Java/C#: Move a couple of flow summary tweaks to the shared implementation.
2021-04-23 13:46:04 +02:00
Tamas Vajk
1b4c3c7415 Fix code review findings 2021-04-23 13:44:34 +02:00
Tamás Vajk
819be43ce7 Fix alphabetical order of supported frameworks 2021-04-23 13:41:59 +02:00
Tamás Vajk
43dc9bbc94 Merge pull request #5744 from tamasvajk/feature/java-loc
Java: Introduce LoC summary metric query
2021-04-23 11:39:42 +02:00
Jonas Jensen
6de5b3021e C++: Replace Jira ticket reference with GH issue 2021-04-23 09:58:39 +02:00
Jonas Jensen
6e059ea002 C++: Remove reference to obsolete issue CPP-383 2021-04-23 09:58:15 +02:00
Shati Patel
96a4d91a6c Merge pull request #5731 from shati-patel/docs/unbind-pragmas
Docs: New "directional binding" pragmas
2021-04-23 08:37:02 +01:00
CodeQL CI
635fb4c25a Merge pull request #5685 from erik-krogh/markdownIt
Approved by asgerf
2021-04-22 14:55:31 -07:00
Taus
3e4ff9e472 Merge pull request #5742 from RasmusWL/django-3.2
Python: Add support for new features in Django 3.2
2021-04-22 17:39:02 +02:00
CodeQL CI
bdb41423e2 Merge pull request #5748 from asgerf/js/rate-limiting-fixes
Approved by erik-krogh
2021-04-22 05:56:50 -07:00
Tamas Vajk
ed42c878b0 Adjust 'fromSource' to hold only on '.cs' files 2021-04-22 14:17:16 +02:00
Tamas Vajk
b36d35bf1e Revert "C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file"
This reverts commit 1dab1590ea.
2021-04-22 14:16:10 +02:00
Mathias Vorreiter Pedersen
2b8afe55e8 Merge pull request #5747 from rdmarsh2/rdmarsh2/cpp/deprecate-return-stack-allocated-object
C++: deprecate cpp/return-stack-allocated-object
2021-04-22 11:37:07 +02:00
Owen Mansel-Chan
fea9f5f431 Merge pull request #5746 from owen-mc/java/refactor-exec-tainted
Make ExecTainted easier to extend
2021-04-22 10:14:28 +01:00
Tamas Vajk
a8a920c8f0 Add change note 2021-04-22 11:01:12 +02:00
Owen Mansel-Chan
8a01799fb8 Make imports private
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-04-22 09:46:49 +01:00
Owen Mansel-Chan
4b8d4f5bbd Update docs 2021-04-22 09:30:50 +01:00
Owen Mansel-Chan
e448dcb725 Avoid bad join order
We want to avoid joining on `i` first.
2021-04-22 09:30:49 +01:00
Owen Mansel-Chan
9f1704560b Include constructors in abstract class 2021-04-22 09:30:48 +01:00
Tamas Vajk
1dab1590ea C#: Adjust 'fromSource' to hold only on files passed to the compiler as a source file 2021-04-22 10:21:28 +02:00
Tamás Vajk
9c936867fa Exclude code from XML files
Co-authored-by: yo-h <55373593+yo-h@users.noreply.github.com>
2021-04-22 09:00:31 +02:00
Tamás Vajk
a7cc9f98ef Merge pull request #5745 from tamasvajk/feature/fix-arg-default
C#: Fix special case of default argument value extraction
2021-04-22 08:58:13 +02:00
Robert Marsh
cac1bef6ea C++: deprecate cpp/return-stack-allocated-object 2021-04-21 15:17:31 -07:00
Asger Feldthaus
fe8deeaf6b JS: Autoformat 2021-04-21 23:13:57 +01:00
Asger Feldthaus
e98bfe921e JS: QLDoc 2021-04-21 22:14:50 +01:00
Asger Feldthaus
bb7934b381 JS: Change note 2021-04-21 21:20:12 +01:00
Asger Feldthaus
c113cfd8b7 JS: Autoformat 2021-04-21 21:13:07 +01:00
Rasmus Wriedt Larsen
5a9e27c6fc Merge branch 'main' into django-3.2 2021-04-21 17:15:47 +02:00
Chris Smowton
94f0a1532d Merge pull request #5682 from smowton/smowton/docs/fix-has-modifier-comment
Fix documentation of Modifier.qll
2021-04-21 15:41:29 +01:00
Tamas Vajk
a0f5e45ae9 C#: Fix special case of default argument value extraction 2021-04-21 16:34:29 +02:00
Geoffrey White
ba335089c4 Merge pull request #5601 from ihsinme/ihsinme-patch-259
CPP: Add query for CWE-691 Insufficient Control Flow Management After Refactoring The Code
2021-04-21 15:13:38 +01:00
Owen Mansel-Chan
9c72e73a82 Make ExecTainted easier to extend
To add a method that executes a command, you can now define a class
extending ExecMethod.
2021-04-21 14:55:37 +01:00
CodeQL CI
30d7f0dc98 Merge pull request #5687 from RasmusWL/inline-taint-tests
Approved by yoff
2021-04-21 06:24:12 -07:00
Asger Feldthaus
2c9a6e7bef JS: Cache function-wrapping steps in type-tracking stage 2021-04-21 13:45:58 +01:00
Tamas Vajk
e25305e3cc Java: Introduce LoC summary metric query 2021-04-21 14:27:00 +02:00
Anders Schack-Mulligen
f9599da32d Java/C#: Move a couple of flow summary tweaks to the shared implementation. 2021-04-21 14:24:15 +02:00
Rasmus Wriedt Larsen
be9cbd79d6 Python: Add change-note for Django 3.2 support 2021-04-21 13:58:34 +02:00
Rasmus Wriedt Larsen
59c6f76457 Python: Add test for new response.headers in Django
See https://docs.djangoproject.com/en/3.2/ref/request-response/#setting-header-fields
2021-04-21 13:55:22 +02:00
Rasmus Wriedt Larsen
2302c8d5fa Python: Model new alias method on django QuerySets 2021-04-21 13:52:38 +02:00
yoff
a19373ab54 Merge pull request #5727 from tausbn/python-use-localsource-in-stepsummary
Python: Use `LocalSourceNode` in `StepSummary::step`
2021-04-21 13:50:31 +02:00
Tamás Vajk
205469316c Merge pull request #5738 from tamasvajk/feature/loc
C# Add line of code metric query
2021-04-21 13:49:32 +02:00
Tamas Vajk
2a6f979ce6 C# Add line of code metric query 2021-04-21 10:42:06 +02:00
Anders Schack-Mulligen
9362ae0687 Merge pull request #5422 from tamasvajk/feature/sink-migration-ldap
Java: Migrate LDAP injection sinks to CSV format
2021-04-21 10:05:28 +02:00
Rasmus Wriedt Larsen
63a2657aef Merge branch 'main' into inline-taint-tests 2021-04-21 10:02:55 +02:00
Tom Hvitved
7080b256fb Merge pull request #5715 from hvitved/csharp/ssa/perf-tweaks
C#: A few minor SSA performance tweaks
2021-04-21 09:59:12 +02:00
Tom Hvitved
def62e8c22 Merge pull request #5718 from hvitved/csharp/hardcoded-cred-remove-cp
C#: Remove CP from `HardcodedCredentials::getCredentialSink`
2021-04-21 09:58:56 +02:00
Tom Hvitved
1ed11b297b Merge pull request #5725 from hvitved/csharp/dataflow/performance
C#: Various data-flow performance tweaks
2021-04-21 09:46:15 +02:00
yoff
ef0ea247c4 Merge pull request #5679 from tausbn/python-fix-bad-points-to-joins
Python: Fix bad points-to joins
2021-04-20 21:19:32 +02:00
Tom Hvitved
3eba5b0aac Merge pull request #5676 from hvitved/csharp/dispatch/get-a-viable-overrider-perf
C#: Speedup `DispatchMethodOrAccessorCall::getAViableOverrider()`
2021-04-20 19:57:59 +02:00
Erik Krogh Kristensen
357e1c0802 Update javascript/ql/src/semmle/javascript/frameworks/Markdown.qll
Co-authored-by: Asger F <asgerf@github.com>
2021-04-20 19:57:47 +02:00
yo-h
00137f2905 Merge pull request #5721 from github/yo-h/java-diagnostic-queries
Java: add extractor `diagnostic` queries
2021-04-20 13:36:49 -04:00
Shati Patel
98a0959784 Docs: New "directional binding" pragmas 2021-04-20 18:12:35 +01:00
Taus
890f96d9b5 Python: Prevent bad joins in TypeBackTracker
Perhaps unsurprisingly, the join orderer was eager and willing to find
the wrong join order in this predicate as well. Applying a similar
fix to the one used in `TypeTracker::step` fixes the problem.
2021-04-20 15:01:04 +00:00
Taus
c0569da65c Python: Move track/backtrack to LocalSourceNode
This is merely making explicit what was implicitly enforced. The move
to change the return type of `step` already meant that `this` and
`result` had to be `LocalSourceNode`. By moving these methods to their
rightful place, we should hopefully avoid a bit of suprising behaviour.
2021-04-20 14:39:56 +00:00
Taus
2a07441c19 Python: ModuleVariableNodes are not API uses
This caused some suprising test changes, where suddenly we had flow from
a `ModuleVariableNode` (as a `RemoteFlowSource`) to a sink. This of
course makes little sense, so instead we simply exclude these nodes as
uses in the first place.
2021-04-20 14:33:42 +00:00
Taus
7581cbade6 Python: Fix forgotten type tracker
This was the last remaining type tracker that did not use
`LocalSourceNode`.
2021-04-20 14:32:56 +00:00
Tamas Vajk
583513bafd Fix review findings 2021-04-20 16:28:47 +02:00
Asger Feldthaus
43ca8ea5f7 JS: Fix perf issue in forwardsParameter 2021-04-20 15:15:12 +01:00
Chris Smowton
a5cfdd2cfe Merge pull request #5467 from p0wn4j/groovy-execute
[Java] CWE-094: Query to detect Groovy Code Injections
2021-04-20 14:49:56 +01:00
Erik Krogh Kristensen
62dfd1fa7d improve the markdown-it model 2021-04-20 15:23:03 +02:00
Taus
38548c9acd Python: Simplify charpred for LocalSourceNode
The somewhat convoluted `comes_from_cfgnode` was originally introduced
in order to have local sources for instances of global variables. This
was needed because global variables have an implicit "scope entry" SSA
definition that flows to the first actual use of the variable (and so
would not fit the strict "has no incoming flow" definition of a local
source node).

However, a subsequent change means that we include all global variable
reads anyway, and so the old definition is no longer needed.

(See commit 3fafb47b16 for further
context.)
2021-04-20 13:19:36 +00:00
Taus
038bf612be Python: Add change note 2021-04-20 13:06:30 +00:00
Jonas Jensen
f02c86cb22 Merge pull request #5726 from MathiasVP/fix-false-positive-in-return-stack-allocated-memory-2
C++: Fix false positive in return stack allocated memory (second attempt)
2021-04-20 15:05:11 +02:00
Taus
a55b43b67e Python: Use LocalSourceNode throughout step
This commit does a lot of stuff all at once, so here are the main
highlights:

In `TypeTracker.qll`, we change `StepSummary::step` to step only between
source nodes. Because reads and writes of global variables happen in two
different (jump) steps, this requires the intermediate
`ModuleVariableNode` to _also_ be a `LocalSourceNode`, and we therefore
modify the charpred for that class accordingly. (This also means
changing a few of the tests to account for these new source nodes.)

In addition, we change `TypeTracker::step` to likewise step between
local source nodes.

Next, to enable the use of the `track` convenience method on nodes, we
add some pragmas to `TypeTracker::step` that prevent bad joins from
occurring. With this, we can eliminate all of the manual type tracker
join predicates.

Next, we observe that because `StepSummary::step` now uses `flowsTo`, it
automatically encapsulates all local-flow steps. In particular this
means we do not have to use `typePreservingStep` in `smallstep`, but can
use `jumpStep` directly. A similar observation applies to
`TypeTracker::smallstep`.

Having done this, we no longer need `typePreservingStep`, so we get rid
of it.
2021-04-20 12:59:33 +00:00
Taus
31bd701bd5 Python: Final LocalSourceNode fixes 2021-04-20 12:59:33 +00:00
Chris Smowton
9bfb0d93ca Autoformat QL 2021-04-20 13:59:09 +01:00
Rasmus Wriedt Larsen
897105de02 Merge pull request #5717 from tausbn/python-use-api-graphs-in-django
Python: Use API graphs in Django model
2021-04-20 14:57:55 +02:00
Erik Krogh Kristensen
19c5889775 use mayHaveBooleanValue 2021-04-20 14:39:54 +02:00
Erik Krogh Kristensen
13d915927b add change note 2021-04-20 14:39:54 +02:00
Erik Krogh Kristensen
7046f1a902 add taint-step for markdown-it when the HTML flag is set 2021-04-20 14:39:54 +02:00
Taus
76700d17d6 Merge pull request #5684 from RasmusWL/flask-more-taint-tests
Python: Add taint tests for .get() in flask
2021-04-20 14:08:08 +02:00
Asger Feldthaus
f8d428cb2d JS: Use function-forwarding steps when tracking rate limiters 2021-04-20 13:00:42 +01:00
Mathias Vorreiter Pedersen
93e55e2631 C++: Fix FP in cpp/return-stack-allocated-memory. 2021-04-20 13:58:12 +02:00
Mathias Vorreiter Pedersen
1797b6c7f9 C++: Add FP test from the work on smart pointers in dataflow. 2021-04-20 13:54:57 +02:00
Asger Feldthaus
581f4ed757 JS: Generalize handling of route handler wrapper functions 2021-04-20 12:46:40 +01:00
Chris Smowton
0ec3ee29e4 Style last use of SecureASTCustomizer 2021-04-20 12:44:49 +01:00
Hayk Andriasyan
bb58a50503 Update GroovyInjection.qhelp 2021-04-20 15:41:58 +04:00
p0wn4j
f2de440886 [Java] CWE-094: Query to detect Groovy Code Injections 2021-04-20 19:18:24 +04:00
Jonas Jensen
d4fdd50e2c Merge pull request #5723 from MathiasVP/cleanup-smart-ptr-model
C++: Simplify smart pointer model
2021-04-20 13:25:02 +02:00
Tom Hvitved
dd1bb18938 C#: Various data-flow performance tweaks
- Cache `DataFlowCall::getEnclosingCallable()`.
- Cache `ParameterNode`.
- Cache `ArgumentNode`.
- Force proper join-orders for uses of `getNodeType()`.
- Inline `localFlow` to prevent calculating full TC.
2021-04-20 11:56:25 +02:00
Tom Hvitved
1f9239089f Merge pull request #5695 from hvitved/csharp/dispose-not-called-on-exc-perf
C#: Improve performance of `DisposeNotCalledOnException.ql`
2021-04-20 11:52:18 +02:00
Tom Hvitved
b2a7a3ed30 Merge pull request #5674 from hvitved/csharp/ssa/call-graph-perf
C#: Improve performance of `SsaImpl::CallGraph::SimpleDelegateAnalysis`
2021-04-20 11:51:52 +02:00
Geoffrey White
2b7e599dc4 Merge pull request #5703 from MathiasVP/improve-access-of-memory-location-after-end-of-buffer-using-strncat
C++: Improve cpp/access-memory-location-after-end-buffer-strncat
2021-04-20 10:44:24 +01:00
Mathias Vorreiter Pedersen
61d4d17225 C++: Simplify smart pointer model and accept test changes. 2021-04-20 09:57:58 +02:00
Tamás Vajk
408954e4d8 C#: Add Dapper to supported frameworks 2021-04-20 09:30:47 +02:00
yo-h
87cd72496c Java: add extractor diagnostic queries 2021-04-19 15:34:16 -04:00
yo-h
cb524b6c19 Merge pull request #5611 from github/yo-h/java16
Java: adjust test `options` for JDK 16 upgrade
2021-04-19 15:12:23 -04:00
Taus
bc6685aa3f Python: Fix typo
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-19 19:57:35 +02:00
Anders Schack-Mulligen
5458c02cc2 Merge pull request #5456 from aschackmull/java/adopt-flow-summary
Java: Use shared flow summary library for CSV models.
2021-04-19 16:21:10 +02:00
Anders Schack-Mulligen
33db0c13cd Merge pull request #5689 from github/aeisenberg/rework-staleness
Actions: Change staleness calculation
2021-04-19 15:57:41 +02:00
Tom Hvitved
9128ec72ad C#: A few minor SSA performance tweaks 2021-04-19 15:51:14 +02:00
Anders Schack-Mulligen
80eb0a2df6 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-19 15:45:58 +02:00
CodeQL CI
437bba1e3c Merge pull request #5716 from erik-krogh/vscodeRegress
Approved by esbena
2021-04-19 06:30:02 -07:00
Tom Hvitved
15e4b7f95d C#: Remove CP from HardcodedCredentials::getCredentialSink 2021-04-19 15:03:11 +02:00
Rasmus Wriedt Larsen
d607c13ab6 Python: Taint tests: include elment for forgotten MISSING 2021-04-19 15:01:42 +02:00
Rasmus Wriedt Larsen
9585390941 Python: Taint tests, report error location first
To better match the standard output from inline expectation tests
2021-04-19 14:59:47 +02:00
Rasmus Wriedt Larsen
b2cb284ff2 Python: Add more examples of what is ok with new taint tests 2021-04-19 14:56:20 +02:00
Anders Schack-Mulligen
7d84cfacef Java: Add MapKeyContent and MapValueContent. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
39862740e0 Java: Convert support for fluent interfaces. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
579c955892 Java: Adjust some tests. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
175c71221a Java: Adjust some test output with more edges/nodes. 2021-04-19 14:06:27 +02:00
Anders Schack-Mulligen
60965b0d8c Java: Adjust some csv models. 2021-04-19 14:02:19 +02:00
Anders Schack-Mulligen
a27dac029f Java: Use shared flow summary library for csv models. 2021-04-19 14:02:19 +02:00
Chris Smowton
36abf8733e Merge pull request #5714 from aschackmull/java/add-misc-qltests
Java: Add a few qltests
2021-04-19 13:00:10 +01:00
Taus
9acc71a7cb Python: Get rid of all _attr methods in Django.qll 2021-04-19 11:54:10 +00:00
Erik Krogh Kristensen
9e6f28e335 fix bad join order in Xss.qll 2021-04-19 13:17:49 +02:00
Anders Schack-Mulligen
29aec0d770 Java: Adjust expected output. 2021-04-19 13:16:46 +02:00
Anders Schack-Mulligen
c5193cf03f Apply suggestions from code review 2021-04-19 13:14:56 +02:00
Anders Schack-Mulligen
06514159be Java: Add XXE tests. 2021-04-19 10:58:21 +02:00
Anders Schack-Mulligen
daad62c4e0 Java: Add TaintedPath test. 2021-04-19 10:07:03 +02:00
Jonas Jensen
1ab75eb6f4 Merge pull request #5708 from github/fix-id-in-JsonpInjection-1
Java: Fix id in experimental JsonpInjection.ql query
2021-04-19 08:23:34 +02:00
yoff
118840dad4 Merge pull request #5690 from tausbn/python-disallow-post-update-nodes-as-local-source-nodes
Python: Disallow `PostUpdateNode` as `LocalSourceNode`
2021-04-19 06:56:11 +02:00
ihsinme
c2d97b98e2 Merge branch 'main' into ihsinme-patch-259 2021-04-18 21:01:56 +03:00
Mathias Vorreiter Pedersen
e36b42a03f Java: Fix invalid id in experimental query
The invalid id broke CI here: https://github.com/github/codeql/pull/5703 (see https://github.slack.com/archives/CPSEA0G22/p1618602834224600)
2021-04-17 09:47:15 +02:00
Taus
f3661c34ee Python: Clean up Django models using API graphs
First sweep. Takes care of most of the models.
2021-04-16 19:53:36 +00:00
Mathias Vorreiter Pedersen
95742aec69 C++: Accept test changes for the other experimental query in the directory. This is only a change in line numbers. 2021-04-16 21:29:17 +02:00
Mathias Vorreiter Pedersen
64f8316a6d C++: Tidy up the ql file and accept test changes. 2021-04-16 21:22:13 +02:00
Mathias Vorreiter Pedersen
1e327289b2 C++: Add false negative test. 2021-04-16 18:38:51 +02:00
Mathias Vorreiter Pedersen
50abb6e3a1 C++: Cleanup test.c 2021-04-16 17:32:44 +02:00
Shati Patel
5c2bf68a05 Merge pull request #5692 from tamasvajk/feature/doc-cs9
Update supported C#/.NET versions
2021-04-16 16:22:06 +01:00
Jonas Jensen
f8d45f04ed Revert "Revert "C++: Work around extractor issue CPP-383""
**Revert the revert** of the workaround for CFG issues when a
`FunctionCall` has a `getTarget` that does not exist. While we've fixed
the main cause of the problem, it can apparently still happen in rare
cases as a result of extractor crashes.

This reverts commit ee5eaef5e4.
2021-04-16 16:44:58 +02:00
Tom Hvitved
40b74167e0 C#: Improve performance of DisposeNotCalledOnException.ql 2021-04-16 14:34:16 +02:00
Rasmus Wriedt Larsen
3c8ea167c4 Merge pull request #5668 from tausbn/python-use-api-graphs-in-fabric
Python: Use API graphs in Fabric model
2021-04-16 14:27:55 +02:00
Rasmus Wriedt Larsen
6ed1016bb8 Merge pull request #5669 from tausbn/python-use-api-graphs-for-invoke
Python: Use API graphs for Invoke
2021-04-16 14:27:19 +02:00
Taus
92b4eb7f02 Python: Cleanup and more explanation
Goes into some detail about the intended semantics of local source nodes
and `flowsTo`.
2021-04-16 11:54:20 +00:00
Geoffrey White
e1028a2765 Merge pull request #5667 from MathiasVP/use-range-analysis-in-overflow
C++: Use range analysis in Overflow.qll
2021-04-16 12:00:28 +01:00
Taus
5c79ad2412 Python: Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-16 11:38:29 +02:00
Taus
af0c32c01d Python: Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-04-16 11:35:12 +02:00
Anders Schack-Mulligen
605f28f741 Merge pull request #5686 from smowton/haby0/JsonHijacking
Java: JSONP Injection w/cleanups
2021-04-16 11:09:17 +02:00
Tom Hvitved
946fcf1c82 C#: Speedup DispatchMethodOrAccessorCall::getAViableOverrider()
In addition to improved performance, the analysis no longer applies a closed-world
assumption to type parameters. That is, if the type of a receiver is a type parameter,
then the call may target any method of a compatible receiver type, not just the
types that actually instantiate the type parameter.
2021-04-16 10:43:17 +02:00
Tamas Vajk
b0975bb3ea Update supported C#/.NET versions 2021-04-16 09:15:43 +02:00
Taus
451d36dc97 Python: Allow _some_ PostUpdateNodes
Specifically, allow the ones arising from calls, but not reads or
writes. This should fix the tests.
2021-04-15 21:26:12 +00:00
Taus
c9c8259ed0 Python: Disallow PostUpdateNode as LocalSourceNode
Previously, in cases like

```python
def foo(x):
    x.bar()
    x.baz()
    x.quux()
```

we would have flow from the first `x` to each use _and_ flow from the
post-update node for each method call to each subsequent use, and all
of these would be `LocalSourceNode`s. For large functions with the above
pattern, this would lead to a quadratic blowup in `hasLocalSource`.

With this commit, only the first of these will count as a
`LocalSourceNode`, and the blowup disappears.
2021-04-15 17:56:14 +00:00
Andrew Eisenberg
5d827b6fc8 Actions: Change staleness calculation
Calculate staleness on issues that have the
`Stale` label. Leave all other issues untouched.
2021-04-15 10:14:13 -07:00
Rasmus Wriedt Larsen
3e7dc12246 Python: Port taint tests to use inline expectations
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`.
2021-04-15 18:00:33 +02:00
Chris Smowton
c37994089c Revert changes to unrelated query 2021-04-15 16:24:29 +01:00
Chris Smowton
254de76078 Remove unnecessary stubs 2021-04-15 16:20:27 +01:00
haby0
dedf765542 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-15 22:59:22 +08:00
Rasmus Wriedt Larsen
b359205d17 Python: Add taint tests for .get() in flask 2021-04-15 14:53:44 +02:00
CodeQL CI
578ce1e512 Merge pull request #5683 from asgerf/js/typescript-template-literal-type-crash
Approved by erik-krogh
2021-04-15 05:11:11 -07:00
Mathias Vorreiter Pedersen
7fbc62358e C++: Accept test changes after making the exprMightOverFlow predicates more sound. 2021-04-15 13:57:44 +02:00
haby0
0e183ab4a4 Finish comment 2021-04-15 19:49:06 +08:00
Chris Smowton
fa36ba901a Merge pull request #5471 from artem-smotrakov/el-injection
Java: Query for detecting Jakarta Expression Language injections
2021-04-15 12:39:34 +01:00
haby0
d269a7e717 CWE-598 reduction 2021-04-15 19:33:15 +08:00
haby0
216f204438 delete FilterClass 2021-04-15 19:28:25 +08:00
haby0
583d0889e2 delete tomcat-embed-core stub, update the ServletGetMethod class 2021-04-15 17:40:51 +08:00
haby0
5d05e4d224 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-15 17:28:53 +08:00
Tom Hvitved
0f24db8759 C#: Improve performance of SsaImpl::CallGraph::SimpleDelegateAnalysis 2021-04-15 11:25:27 +02:00
Asger Feldthaus
f8570bb293 JS: Update TRAP 2021-04-15 10:16:46 +01:00
Asger Feldthaus
cb736c8c82 JS: Change note 2021-04-15 09:37:57 +01:00
Tom Hvitved
972cc47f67 Merge pull request #5673 from hvitved/csharp/customizations
C#: Add `Customizations.qll`
2021-04-15 10:24:29 +02:00
Asger Feldthaus
b4a2a9db25 JS: Fix extraction of non-substitution template literal types 2021-04-15 09:23:45 +01:00
Chris Smowton
bd3b3178ba Fix documentation of Modifier.qll 2021-04-15 09:16:51 +01:00
haby0
b3bdf89fc2 rm VerificationMethodFlowConfig, use springframework-5.2.3 stub 2021-04-15 10:25:40 +08:00
CodeQL CI
4be183c7f6 Merge pull request #5675 from erik-krogh/libXss
Approved by esbena
2021-04-14 14:34:23 -07:00
ihsinme
b30ae3980c Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-14 20:48:20 +03:00
Robert Marsh
fe57876fd8 Merge pull request #5643 from dbartol/smart-pointers/side-effect-refactor
C++: Refactor some side effect generation code
2021-04-14 09:59:41 -07:00
Taus
897d12420b Python: Prevent bad join in isinstanceEvaluatesTo
In some cases, we were joining the result of `val.getClass()` against
the first argument of `Types::improperSubclass` before filtering out the
vast majority of tuples by the call to `isinstance_call`.

To fix this, we let `isinstance_call` take care of figuring out the
class of the value being tested. As a bonus, this cleans up the only
other place where `isinstance_call` is used, where we _also_ want to
know the class of the value being tested in the `isinstance` call.
2021-04-14 16:49:12 +00:00
Artem Smotrakov
97186b3d30 Added comments for tests 2021-04-14 19:30:58 +03:00
Andrew Eisenberg
56ba0f080a Merge pull request #5659 from github/aeisenberg/mark-as-stale
Actions: Add workflow for marking stale questions
2021-04-14 08:37:55 -07:00
Taus
a7fcf52267 Python: Fix bad join in total_cost
The recent change to `appliesTo` lead to a perturbation in the join
order of this predicate, which resulted in a cartesian product between
`call` and `ctx` being created (before being filtered by `appliesTo`).

By splitting the intermediate result into its own helper predicate,
suitably marked to prevent inlining/magic, we prevent this from
happening again.
2021-04-14 15:36:01 +00:00
Andrew Eisenberg
392adf2a25 Workflows: Remove dry-run flag for labeller 2021-04-14 08:25:34 -07:00
Dave Bartolomeo
b29f35f564 Fix formatting 2021-04-14 11:15:16 -04:00
Geoffrey White
64fed4cb10 Merge pull request #5677 from MathiasVP/fix-duplicate-ids-in-experimental
C++: Fix duplicate names in experimental queries
2021-04-14 15:58:49 +01:00
Jonas Jensen
b4f01c9afa Merge pull request #5578 from MathiasVP/ast-flow-smart-pointers
C++: AST dataflow through smart pointers
2021-04-14 16:39:05 +02:00
Mathias Vorreiter Pedersen
53a320a810 C++: Fix duplicate names. 2021-04-14 16:33:18 +02:00
Mathias Vorreiter Pedersen
bb447d7174 C++: Make sure missingGuardAgainstOverflow (and underflow) holds when range analysis fails to deduce a bound. 2021-04-14 16:30:43 +02:00
yoff
447f339857 Merge pull request #5641 from tausbn/python-use-localsourcenode-in-typetrackers
Python: Use API graphs in PEP249 support
2021-04-14 15:39:49 +02:00
Mathias Vorreiter Pedersen
92508beb82 Merge pull request #5600 from ihsinme/ihsinme-patch-258
CPP: Add query for CWE-691 Insufficient Control Flow Management When Using Bit Operations
2021-04-14 14:55:30 +02:00
Anders Schack-Mulligen
f43d427875 Merge pull request #5645 from Marcono1234/marcono1234/primary-ql-class
Java: Override getAPrimaryQlClass() for more classes
2021-04-14 14:51:29 +02:00
Mathias Vorreiter Pedersen
bc7cc2f7ce C++: Remove rule that wasn't needed. 2021-04-14 14:50:27 +02:00
Mathias Vorreiter Pedersen
da36508714 Revert "C++: As response to the review comments this commit adds a reference-to-pointer state to AddressFlow. A call to an unwrapper function now adds a pointer -> reference-to-pointer transition, and a ReferenceDereference adds a reference-to-pointer -> pointer transition."
This reverts commit 5aeaab7c6d.
2021-04-14 14:41:22 +02:00
Chris Smowton
591ac38c31 Merge pull request #5591 from Marcono1234/marcono1234/member-nested-type
Java: Add MemberType
2021-04-14 12:29:54 +01:00
Taus
54c79bff74 Merge pull request #5666 from RasmusWL/django-refactor
Python: Refactoring and exposing of Django views/fields/forms
2021-04-14 13:07:20 +02:00
Mathias Vorreiter Pedersen
2e40d01397 Update cpp/ql/src/semmle/code/cpp/security/Overflow.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-04-14 13:01:31 +02:00
Rasmus Wriedt Larsen
44d2bf42d7 Merge pull request #5671 from tausbn/python-use-api-graphs-in-werkzeug
Python: Use API graphs in Werkzeug
2021-04-14 12:57:58 +02:00
Erik Krogh Kristensen
fd23e0bdda use more API nodes in XmlParsers, and recognize more results from parsing XML 2021-04-14 11:48:31 +02:00
Anders Schack-Mulligen
3b6cd0f681 Merge pull request #5661 from smowton/smowton/cleanup/call-is-exprparent
Make Call a subclass of ExprParent.
2021-04-14 10:49:33 +02:00
Rasmus Wriedt Larsen
9de8085571 Merge pull request #5665 from tausbn/python-use-api-graphs-in-tornado
Python: Tornado cleanup using API graphs
2021-04-14 10:22:21 +02:00
Rasmus Wriedt Larsen
2d0c9b6bf2 Merge pull request #5670 from tausbn/python-use-api-graphs-in-dill
Python: Use API graphs in Dill model
2021-04-14 10:08:02 +02:00
Rasmus Wriedt Larsen
55723618a9 Python: Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-04-14 10:05:50 +02:00
Chris Smowton
2965a1f204 Use Thread$State as an inner-class example
Map<>$Entry currently has odd generic notation that may be about to change.
2021-04-14 08:43:05 +01:00
Chris Smowton
5158e7964e Add change note 2021-04-14 08:25:12 +01:00
Tom Hvitved
36fe72246b C#: Add change note 2021-04-14 09:22:16 +02:00
Tom Hvitved
4810308b16 C#: Add Customizations.qll 2021-04-14 09:16:31 +02:00
haby0
77208bcc91 Fix the error that there is no VerificationMethodToIfFlowConfig 2021-04-14 13:14:43 +08:00
haby0
e2ed0d02b0 Delete existsFilterVerificationMethod and existsServletVerificationMethod, add from get handler to filter 2021-04-14 12:34:52 +08:00
haby0
37dae67a0d Fix RequestResponseFlowConfig.isSink error 2021-04-14 09:55:24 +08:00
Robert Marsh
419d25cbcf Merge pull request #5325 from ihsinme/ihsinme-patch-245
CPP: Add query for CWE-783 Operator Precedence Logic Error When Use Bool Type
2021-04-13 13:24:39 -07:00
Taus
981c5deb57 Merge pull request #5639 from tausbn/python-api-graphs-missing-builtins
Python: Add missing builtins to `API::builtin`
2021-04-13 21:27:52 +02:00
Marcono1234
d853f0c400 Java: Add MemberType 2021-04-13 18:55:20 +02:00
Taus
a6bb9ebb9f Python: Re-introduce abstract toString
This seems like the easier solution in the short run.
2021-04-13 16:08:41 +00:00
Taus
079c7e089d Python: Autoformat 2021-04-13 16:05:45 +00:00
Taus
273e8ce4ef Python: Add change note 2021-04-13 16:04:07 +00:00
haby0
00235ed3b3 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:58:52 +08:00
haby0
25b012db48 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:58:28 +08:00
Taus
5f7d3d0d36 Python: Use API graphs in Werkzeug 2021-04-13 15:57:21 +00:00
haby0
7be45e7c5e Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:56:17 +08:00
haby0
6e73d13670 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-13 23:48:45 +08:00
Taus
2890fe6d61 Python: Use API graphs in Dill model
If only all rewrites were this smooth...
2021-04-13 15:26:54 +00:00
Taus
7ed09904b4 Python: Use API graphs for Invoke
A few stragglers remain, as they are modelling the use of decorators.

They will be dealt with at a later date.
2021-04-13 15:21:19 +00:00
Mathias Vorreiter Pedersen
aa52585120 C++: Add change-note. 2021-04-13 17:17:05 +02:00
Marcono1234
89a5acf6e8 Java: Revert overriding XMLFile.getAPrimaryQlClass()
Library file has to be kept in sync with the other languages, however except
cpp none of them have the getAPrimaryQlClass() predicate declared in a
superclass. Therefore for simplicity revert the change for Java.
2021-04-13 17:09:15 +02:00
Taus
7f131c1f35 Python: Get rid of _attr predicates 2021-04-13 14:55:44 +00:00
Taus
1008411594 Python: Use API graphs in Fabric model 2021-04-13 14:49:44 +00:00
Mathias Vorreiter Pedersen
d1457995dd C++: Use range analysis in Overflow.qll 2021-04-13 16:39:28 +02:00
Taus
a404faa302 Python: Use American English in change note
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-04-13 15:05:44 +02:00
Taus
7825a2cdfc Python: Add change note 2021-04-13 12:48:45 +00:00
Taus
1a4845f417 Python: Restrict types a bit
The `CallCfgNode` restrictions are familiar and useful.

Restricting `InstanceSource` to extend `LocalSourceNode` is novel, but I
think it makes sense. It will act as a good reminder to anyone extending
`InstanceSource` that the node in question is a `LocalSourceNode`, which
will be enforced by the return type of the internal type tracker anyway.
2021-04-13 12:28:38 +00:00
Taus
f93b68d4dc Python: Get rid of _attr methods 2021-04-13 12:25:38 +00:00
Taus
98d936d8b3 Python: Tornado cleanup using API graphs
I wasn't able to roll out API graphs as widely in Tornado as I had
hoped, since we're lacking the "def" part. This means most of the
`InstanceSource` machinery will have to stay.
2021-04-13 12:25:38 +00:00
CodeQL CI
f341d5010d Merge pull request #5662 from asgerf/js/simpler-json-api
Approved by erik-krogh
2021-04-13 04:37:56 -07:00
Tom Hvitved
9b0ef2fe21 Merge pull request #5654 from hvitved/csharp/autobuilder/pwsh
C#: First try `pwsh` and then `powershell` when calling `dotnet-install.ps1`
2021-04-13 13:15:01 +02:00
Chris Smowton
58d198261e Merge pull request #5663 from smowton/luchua/java/sensitive-cookie-not-httponly
Java: CWE-1004 Query to check sensitive cookies without the HttpOnly flag set w/minor corrections
2021-04-13 12:08:53 +01:00
CodeQL CI
646639bc73 Merge pull request #5460 from erik-krogh/forgery-2
Approved by asgerf
2021-04-13 03:57:04 -07:00
Chris Smowton
f22b11881e Minimise stubs
By removing all business logic from the stubs, we better test that our analysis treats them as opaque and does not rely on their internal structure
2021-04-13 10:36:28 +01:00
Chris Smowton
45e1a61d7b Mark test as bad-but-missed
This test ought ideally to be caught, but isn't by the current version of the query.
2021-04-13 10:36:27 +01:00
Asger Feldthaus
e77117f902 JS: Autoformat 2021-04-13 10:29:14 +01:00
Asger Feldthaus
929d9da4b4 JS: Migrate to new JSON API 2021-04-13 10:29:13 +01:00
Asger Feldthaus
7c13163413 JS: Lift JSON accessors to JSONValue 2021-04-13 10:29:13 +01:00
Tom Hvitved
15c103e42d C#: Remove code duplication in BuildScripts.cs 2021-04-13 10:57:15 +02:00
Chris Smowton
dee974ff2d Make Call a subclass of ExprParent. All of its subclasses are in any case (via Expr or Stmt) 2021-04-13 09:13:47 +01:00
Marcono1234
c37dbb2e68 Java: Override getAPrimaryQlClass() for more classes 2021-04-13 08:46:01 +01:00
Mathias Vorreiter Pedersen
3cfd30ef6f Merge pull request #5629 from hvitved/cpp/remove-unique
C++: Remove `unique` wrapper from `DataFlow::Node::getEnclosingCallable`
2021-04-13 09:42:34 +02:00
haby0
be39883166 Change the class name and comment,Use .(CompileTimeConstantExpr).getStringValue() 2021-04-13 14:10:10 +08:00
Dave Bartolomeo
afd2f58f9f C++: Fix PR feedback 2021-04-12 18:21:05 -04:00
Dave Bartolomeo
697b2dcde8 C++: Add missing store step for single-field struct use
We have special code to handle field flow for single-field structs, but that special case was too specific. Some `Store`s to single-field structs have no `Chi` instruction, which is the case that we handled already. However, it is possible for the `Store` to have a `Chi` instruction (e.g. for `{AllAliased}`), but still have a use of the result of the `Store` directly. We now add a `PostUpdateNode` for the result of the `Store` itself in those cases, just like we already did if the `Store` had no `Chi`.
2021-04-12 18:11:41 -04:00
Robert Marsh
0102d68f38 Merge pull request #5658 from MathiasVP/fix-partial-def-diff-test
C++: Fix performance in test
2021-04-12 13:08:30 -07:00
Andrew Eisenberg
e0fcb15739 Actions: Add workflow for marking stale questions
This PR adds a workflow for marking and closing issues as stale. Issues must be labeled as _question_. PRs are never marked as stale.
2021-04-12 13:05:53 -07:00
Artem Smotrakov
b96b665262 Renaming in java/ql/src/experimental/Security/CWE/CWE-094 2021-04-12 21:40:49 +03:00
Mathias Vorreiter Pedersen
037e6369ce C++: Ensure all values are bound in both disjunctions. 2021-04-12 18:27:21 +02:00
luchua-bc
d7f26dfc18 Update stub classes and qldoc 2021-04-12 16:19:23 +00:00
Taus
fda750ef26 Merge pull request #5642 from tausbn/python-use-api-graphs-in-stdlib
Python: Use API graphs in `Stdlib.qll`
2021-04-12 18:05:38 +02:00
Chris Smowton
423ff32d04 Merge pull request #5384 from luchua-bc/java/insecure-spring-actuator-config
Java: CWE-016 Query to detect insecure configuration of Spring Boot Actuator
2021-04-12 17:04:47 +01:00
Taus
6d4ddc0329 Merge pull request #5614 from tausbn/python-allow-absolute-imports-from-source-directory
Python: Allow absolute imports from source directory
2021-04-12 18:02:00 +02:00
CodeQL CI
bc56d16c18 Merge pull request #5485 from RasmusWL/django-queryset-chains
Approved by tausbn
2021-04-12 08:49:31 -07:00
Tom Hvitved
dfc91b8331 C#: Simplify dotnet-install.ps1 invocation
Using the pattern from https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script.
2021-04-12 17:33:33 +02:00
Chris Smowton
bb23866cec Add missing doc comments 2021-04-12 16:33:01 +01:00
Tom Hvitved
d35a501121 Merge pull request #5583 from lcartey/cs/restrict-jump-to-def
C#: Exclude jump-to-def information for elements with too many locations
2021-04-12 16:52:20 +02:00
ihsinme
a43698802f Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-12 17:36:50 +03:00
CodeQL CI
310a2c8bb3 Merge pull request #5655 from erik-krogh/cert
Approved by esbena
2021-04-12 07:31:04 -07:00
Chris Smowton
2656a52880 Merge pull request #5538 from luchua-bc/java/credentials-in-properties
Java: CWE-555 Query to detect plaintext credentials in Java properties files
2021-04-12 15:22:21 +01:00
Chris Smowton
abeefcaced Merge pull request #4947 from porcupineyhairs/DexLoading
Java : add query to detect insecure loading of Dex File
2021-04-12 15:22:12 +01:00
Mathias Vorreiter Pedersen
5aeaab7c6d C++: As response to the review comments this commit adds a reference-to-pointer state to AddressFlow. A call to an unwrapper function now adds a pointer -> reference-to-pointer transition, and a ReferenceDereference adds a reference-to-pointer -> pointer transition. 2021-04-12 16:01:01 +02:00
ihsinme
58d5ad48d5 Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-12 17:00:34 +03:00
ihsinme
d7c14775bf Update InsufficientControlFlowManagementAfterRefactoringTheCode.qhelp 2021-04-12 16:56:48 +03:00
Chris Smowton
11bf982728 Remove superfluous linebreaks in qhelp file 2021-04-12 14:36:42 +01:00
Erik Krogh Kristensen
32737a17fb add change note 2021-04-12 15:09:13 +02:00
Erik Krogh Kristensen
172d6139e2 support all ClientRequests in js/disabling-certificate-validation 2021-04-12 15:06:10 +02:00
luchua-bc
c281e54d22 Remove unused files and update qldoc 2021-04-12 13:05:01 +00:00
Tom Hvitved
57016ddbde C++: Remove unique wrapper from DataFlow::Node::getEnclosingCallable() 2021-04-12 14:41:52 +02:00
Tom Hvitved
7d2a60e910 Merge pull request #5640 from hvitved/dataflow/path-step-perf
Data flow: Prevent bad join-order in `pathStep`
2021-04-12 14:40:46 +02:00
Tamas Vajk
b4d35b52c3 C#: Add Console.Read* to local flow sources 2021-04-12 14:19:17 +02:00
Tom Hvitved
5446532e1d C#: Update auto-builder tests 2021-04-12 14:01:55 +02:00
Anders Schack-Mulligen
acd4cf2878 Merge pull request #5636 from aschackmull/java/shared-flow-summaries
Java: Adopt shared flow summaries
2021-04-12 13:35:31 +02:00
CodeQL CI
e8d835b422 Merge pull request #5638 from erik-krogh/smartInliner
Approved by esbena
2021-04-12 04:17:25 -07:00
Tom Hvitved
c7686b1838 C#: First try pwsh and then powershell when calling dotnet-install.ps1 2021-04-12 13:01:14 +02:00
Tom Hvitved
cf5f838b13 Data flow: Remove recommendation to use unique in Node::getEnclosingCallable() 2021-04-12 12:04:23 +02:00
Anders Schack-Mulligen
e003b04061 Merge pull request #5637 from Marcono1234/marcono1234/toString-method
Java: Add ToStringMethod
2021-04-12 11:43:55 +02:00
Max Schaefer
cd57e61f65 Rename MkHasUnderlyingType to MkTypeUse. 2021-04-12 11:30:15 +02:00
Erik Krogh Kristensen
91d28fb8b0 cleanup in API-graphs 2021-04-12 11:30:15 +02:00
CodeQL CI
63f087a8e9 Merge pull request #5653 from erik-krogh/givenCommand
Approved by asgerf
2021-04-12 02:01:32 -07:00
Rasmus Wriedt Larsen
364d48948f Merge pull request #3810 from dilanbhalla/syntaxpython
Python: Function/Class Naming Convention (Syntax)
2021-04-12 10:42:17 +02:00
Erik Krogh Kristensen
17c4bbbc4e allow parameters that end with "Command" in js/shell-command-constructed-from-input 2021-04-12 09:57:40 +02:00
haby0
1b948ac2e2 Combine two Configurations into one 2021-04-12 15:44:39 +08:00
ihsinme
feb3a8deb1 Update InsufficientControlFlowManagementAfterRefactoringTheCode.expected 2021-04-12 08:23:41 +03:00
ihsinme
6924c6c51c Update test.c 2021-04-12 08:23:06 +03:00
ihsinme
3da88f2103 Update InsufficientControlFlowManagementAfterRefactoringTheCode.c 2021-04-12 08:15:36 +03:00
ihsinme
17d1c77a14 Update InsufficientControlFlowManagementAfterRefactoringTheCode.ql 2021-04-12 08:14:17 +03:00
yo-h
4f2060f96b Merge commit '2d618d6b928d8b76ac8033b3b63d9bde71caa325' into yo-h/java16 2021-04-11 23:55:33 -04:00
Taus
10be2735ec Python: Get rid of _attr predicates
Also changes all `CfgNode`s representing calls to `CallCfgNode`s.
2021-04-10 12:12:18 +00:00
haby0
d90527bead JsonpInjectionExpr updated to JsonpBuilderExpr 2021-04-10 10:33:21 +08:00
Marcono1234
9349e6922d Java: Add ToStringMethod 2021-04-10 04:00:44 +02:00
haby0
eeae91e620 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:48:55 +08:00
haby0
046aeaa38c Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:37:29 +08:00
haby0
8b756d7f1b Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:27:03 +08:00
haby0
650446f761 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:26:32 +08:00
haby0
a5ebe8c600 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 09:26:08 +08:00
porcupineyhairs
8687c5c145 Apply suggestions from code review
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:18:35 +05:30
haby0
8a7d28a2ed Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:49 +08:00
haby0
4c21980d4f Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:30 +08:00
haby0
9635a36044 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:29:06 +08:00
haby0
760231c004 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:28:17 +08:00
haby0
c77c7b0a98 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:27:16 +08:00
haby0
837f20108d Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:25:43 +08:00
haby0
157e4670fd Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:25:11 +08:00
haby0
79c1374925 Update java/ql/src/semmle/code/java/frameworks/Servlets.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:24:49 +08:00
haby0
1510048f7a Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:23:13 +08:00
haby0
d8165145c7 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:22:44 +08:00
haby0
ebd38eaf3b Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:22:08 +08:00
haby0
b8c11503f0 Update java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-04-10 04:21:49 +08:00
Dave Bartolomeo
0a86642056 C++: Refactor some side effect generation code
This change was necessary for my upcoming changes to introduce side effect instructions for indirections of smart pointers. The code to decide which parameters have which side effects appeared in both the IPA constructor for `TTranslatedSideEffect` and in `TranslatedCall`. These two versions didn't quite agree, especially once the `SideEffectFunction` model provides its own side effects instead of the defaults.
The relevant code has now been factored out into `SideEffects.qll`. This queries the model if one exists, and provides default side effects if no model exists. This fixes at least one existing issue, where we were emitting a buffer read side effect for `*this` instead of an indirect read side effect. This accounts for all of the IR diffs in the tests.
2021-04-09 16:14:03 -04:00
luchua-bc
4e3791dc0d Remove LoadCredentialsConfiguration and update qldoc 2021-04-09 19:36:35 +00:00
Taus
720fbaf301 Python: Fix test error.
Somehow, having to type "Node" all day long made me turn "json" into
"node"...

Also removes some bits that weren't needed after all.
2021-04-09 19:04:49 +00:00
Mathias Vorreiter Pedersen
1510fe370d C++: Add cases for const pointer wrapper references to AddressFlow and FlowVar. 2021-04-09 20:58:05 +02:00
Mathias Vorreiter Pedersen
2329b31601 C++: Replace the new SmartPointerPartialDefinition with additional steps in AddressFlow.qll 2021-04-09 20:49:45 +02:00
Mathias Vorreiter Pedersen
a460e3ad3d Merge branch 'main' into ast-flow-smart-pointers 2021-04-09 19:41:10 +02:00
Taus
cc4827600b Python: Use API graphs in Stdlib.qll
Eliminates _almost_ all of the bespoke type trackers found here. The
ones that remain do not fit easily inside the framework of API graphs
(at least, not yet), and I did not see any easy ways to clean them up.
They have, however, been rewritten to use `LocalSourceNode` internally,
which was the primary goal of this exercise.

I'm sure we could also clean up many of the inner modules given the more
lean presentation we have now, but this can wait for a different PR.
2021-04-09 17:11:47 +00:00
luchua-bc
04b0682bbf Use isAdditionalTaintStep and make the query more readable 2021-04-09 16:14:51 +00:00
Tom Hvitved
fd8f745468 Java: Adopt shared flow summary library and refactor data-flow nodes. 2021-04-09 16:57:03 +02:00
Shati Patel
2d618d6b92 Merge pull request #5625 from shati-patel/docs/cli-manual
Docs: Link to CodeQL CLI manual from the sidebar
2021-04-09 15:30:24 +01:00
Tom Hvitved
f130616369 Data flow: Make getLocalCc private again 2021-04-09 16:22:58 +02:00
Taus
d2b874f217 Python: Use API graphs in PEP249 support
Because the replacement extension point now extends `API::Node`, I
modified the `toString` method of the latter to have an empty body.
The alternative would be to require everyone to provide a `toString`
predicate for their extensions, but seeing as these will usually be
pointing to already existing API graph nodes, this seems silly.

(This may be the reason why the equivalent method in the JS libs has
such an implementation.)
2021-04-09 14:19:00 +00:00
Jonas Jensen
e1d0bbb021 Merge pull request #5607 from MathiasVP/smart-pointer-ast-read-store-steps
C++: read and store steps for smart pointers in AST dataflow
2021-04-09 16:11:48 +02:00
CodeQL CI
6fd4a8afff Merge pull request #5567 from asgerf/js/sql-models
Approved by esbena
2021-04-09 07:11:10 -07:00
CodeQL CI
be2fe6e171 Merge pull request #5630 from erik-krogh/urlStep
Approved by esbena
2021-04-09 07:05:43 -07:00
CodeQL CI
8d2768b2ce Merge pull request #5634 from erik-krogh/fileSource
Approved by asgerf
2021-04-09 07:04:42 -07:00
Anders Schack-Mulligen
701e815368 Merge pull request #5628 from hvitved/java/remove-unique
Java: Remove `unique` wrapper from `DataFlow::Node::getEnclosingCallable()`
2021-04-09 15:21:26 +02:00
Mathias Vorreiter Pedersen
cd310eb9d5 C++: Remove unused import. 2021-04-09 15:08:48 +02:00
Tamás Vajk
992a4df12f Merge pull request #5619 from tamasvajk/feature/fix-default-argument-value-extraction
C# Improve default argument value extraction
2021-04-09 14:58:35 +02:00
Mathias Vorreiter Pedersen
996cda9b97 C++: Fix incorrect test annotation. 2021-04-09 14:46:46 +02:00
Tom Hvitved
6874b8d4b3 Data flow: Prevent bad join-order in pathStep 2021-04-09 14:24:47 +02:00
Mathias Vorreiter Pedersen
80d5b17900 C++: Remove the dataflow rule for smart_ptr -> *smart_ptr. 2021-04-09 14:20:51 +02:00
Mathias Vorreiter Pedersen
cae0060a89 C++: Replace the new rules in DataFlowUtil with a dataflow model for pointer wrapper classes. 2021-04-09 14:06:58 +02:00
Taus
affdedd840 Python: Add missing builtins to API::builtin
We were missing out on `None`, `True`, and `False` as these do not
appear as actual attributes of the `builtins` module in Python 3
(because they are elevated to the status of keywords there)

The simple solution, then, is to just always include them directly.
2021-04-09 12:02:07 +00:00
Tamas Vajk
46197e6e69 Address review comments 2021-04-09 13:39:37 +02:00
Erik Krogh Kristensen
595bdedb22 rename predicate to getStem, and update regexp 2021-04-09 13:07:54 +02:00
Mathias Vorreiter Pedersen
0a6aef71a2 C++: Respond to review comments. 2021-04-09 12:29:13 +02:00
CodeQL CI
652e8b4872 Merge pull request #5586 from asgerf/js/tsconfig-file-inclusion-handling
Approved by esbena
2021-04-09 02:50:51 -07:00
Tom Hvitved
c9c4c067b6 Merge pull request #5633 from hvitved/csharp/get-a-source-type-perf
C#: Improve performance of `Dispatch::SimpleTypeDataFlow::getASourceType()`
2021-04-09 11:42:34 +02:00
Tamás Vajk
a335bb0115 Merge pull request #5609 from tamasvajk/feature/dapper
C#: Dapper support
2021-04-09 10:52:17 +02:00
CodeQL CI
ad267404c9 Merge pull request #5137 from asgerf/js/redux-less
Approved by erik-krogh
2021-04-09 01:24:19 -07:00
Tamas Vajk
d7f0b9a7fa Add change note 2021-04-09 09:58:37 +02:00
Tamas Vajk
749db379ca Address code review findings 2021-04-09 09:55:37 +02:00
Tamas Vajk
dbb3d3dc17 Add change note 2021-04-09 09:50:55 +02:00
Tamas Vajk
53daa7c436 Java: Migrate LDAP injection sinks to CSV format 2021-04-09 09:15:47 +02:00
luchua-bc
11304b2ae1 Update qldoc and change the wrapper method implementation 2021-04-09 02:21:59 +00:00
Erik Krogh Kristensen
7f01586bf1 fix bad join order in getDocumentedParameter 2021-04-09 01:15:46 +02:00
Erik Krogh Kristensen
e5bce548de add nomagic on mayHaveStringValue 2021-04-09 00:08:51 +02:00
Erik Krogh Kristensen
956311457d fixed bad SourceNode X SourceNode join in HTTP model 2021-04-08 21:15:50 +02:00
ihsinme
9b3ccade43 Update test.c 2021-04-08 22:06:35 +03:00
ihsinme
3d117243e4 Update test.c 2021-04-08 22:05:31 +03:00
ihsinme
02eb447a35 Update InsufficientControlFlowManagementWhenUsingBitOperations.expected 2021-04-08 22:04:08 +03:00
ihsinme
a6b486a448 Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-08 22:01:43 +03:00
Dilan
d73ba13b28 autoformat fix 2021-04-08 11:41:58 -07:00
Artem Smotrakov
b39a3ab12c Added setVariable() sink 2021-04-08 20:41:43 +03:00
Tamás Vajk
8adaee05b6 Merge pull request #5453 from tamasvajk/feature/use_codeql_stubs
C#: Adjust make_stubs.py to use codeql instead of odasa
2021-04-08 16:16:05 +02:00
Anders Schack-Mulligen
6109ef5e88 Merge pull request #5475 from Marcono1234/marcono1234/minus-literal
Java: Improve documentation regarding minus in front of numeric literals
2021-04-08 16:11:14 +02:00
Asger Feldthaus
7d300b53d7 JS: Autoformat 2021-04-08 15:06:48 +01:00
Anders Schack-Mulligen
d42a01cb3a qldoc fixup 2021-04-08 15:45:21 +02:00
Tamas Vajk
e5160929eb Remove ODASA reference from make_stubs.py 2021-04-08 15:04:02 +02:00
Erik Krogh Kristensen
30ba69d991 treat "files" in a package.json as main modules, if "main" is not present 2021-04-08 14:42:12 +02:00
Tom Hvitved
036e181bc1 C#: Improve performance of Dispatch::SimpleTypeDataFlow::getASourceType() 2021-04-08 14:27:28 +02:00
Tom Hvitved
716568ebd1 Merge pull request #5623 from hvitved/csharp/enclosing
C#: Compute enclosing callable as a transitive closure
2021-04-08 14:20:09 +02:00
Tom Hvitved
9820116734 Merge pull request #5603 from hvitved/csharp/dataflow/no-unique
C#: Remove `unique` wrappers from `DataFlow::Node::get(EnclosingCallable|ControlFlowNode)`
2021-04-08 14:19:34 +02:00
Asger Feldthaus
52a2260dc7 JS: Rename change note file 2021-04-08 12:52:23 +01:00
Rasmus Wriedt Larsen
c738f387b1 Merge pull request #5624 from tausbn/python-make-callcfgnode-a-localsourcenode
Python: Improve `CallCfgNode` interface
2021-04-08 13:38:24 +02:00
Taus
cf5f760ecd Merge pull request #5582 from RasmusWL/all-tuple
Python: Add support for `__all__` assigned to tuple
2021-04-08 13:03:27 +02:00
Rasmus Wriedt Larsen
83477439a1 Python: Make django views/fields/forms class modeling extensible
This also requires that we make this part of the modeling public, which I guess
is step we want to take eventually anyway!

I'm not quite sure whether the modules `Django::Views` and `Django::Forms` are
actually helpful, or whether we should just have their modules available as
`Django::View`, `Django::Form`, and `Django::Field`...
2021-04-08 12:45:37 +02:00
Rasmus Wriedt Larsen
b7483a5394 Python: Add modeledSubclassRef for Django views/fields/forms 2021-04-08 12:45:36 +02:00
Rasmus Wriedt Larsen
322bdcb703 Python: Port Django view modeling to API graphs 2021-04-08 12:45:35 +02:00
Rasmus Wriedt Larsen
8ce5c46e05 Python: Minor refactor
modName/clsName _is_ shorter, but also looks way worse :D
2021-04-08 12:45:34 +02:00
Tamas Vajk
a790eb8110 Fix for unconstrained generic types 2021-04-08 12:20:01 +02:00
Tamas Vajk
a8cbdc92b9 Add more test cases 2021-04-08 12:17:19 +02:00
Tamas Vajk
551a7ce9e5 Fix expression value of struct default argument values 2021-04-08 12:14:53 +02:00
Tamas Vajk
c069c3384e Fix tests 2021-04-08 12:07:36 +02:00
Tamas Vajk
cb9a9db356 C# Improve default argument value extraction 2021-04-08 12:07:22 +02:00
Tamas Vajk
2ac1e60406 C#: Add parameter default value tests 2021-04-08 12:04:18 +02:00
Jonas Jensen
51bab81f56 Merge pull request #5622 from MathiasVP/inline-is-before
C++: Inline Location::isBefore
2021-04-08 11:24:33 +02:00
Erik Krogh Kristensen
99dd5330c2 add taint-step for URL construction in js/request-forgery 2021-04-08 11:10:33 +02:00
CodeQL CI
a9527fd913 Merge pull request #5621 from erik-krogh/shellSink
Approved by esbena
2021-04-08 09:47:45 +01:00
Tom Hvitved
2faf52b6bd Java: Remove unique wrapper from DataFlow::Node::getEnclosingCallable()` 2021-04-08 10:07:19 +02:00
Dilan
675de07c3e autoformat ql 2021-04-07 15:04:18 -07:00
ihsinme
ed34c96357 Update InsufficientControlFlowManagementWhenUsingBitOperations.ql 2021-04-07 21:40:49 +03:00
ihsinme
eb9b41acab Apply suggestions from code review
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-04-07 21:31:12 +03:00
Artem Smotrakov
a764a79090 Always bind arguments in TaintPropagatingCall 2021-04-07 21:12:21 +03:00
Artem Smotrakov
c13ee0859a LambdaExpression should extend JakartaType 2021-04-07 21:02:21 +03:00
Shati Patel
4cf0b8e725 Merge pull request #5626 from shati-patel/docs/broken-links
Docs: Fix broken link to cached "RemoteFlowSource"
2021-04-07 19:01:33 +01:00
Artem Smotrakov
3d8e173c57 Removed a reference to Apache Commons EL 2021-04-07 20:59:07 +03:00
Artem Smotrakov
80ac2aff26 Fixed typos
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-04-07 20:55:03 +03:00
Shati Patel
f372274857 Docs: Fix broken links 2021-04-07 18:02:29 +01:00
Shati Patel
2373bf2dfb Docs: Link to CodeQL CLI manual from the sidebar 2021-04-07 17:55:05 +01:00
Tom Hvitved
1cf30d2a9e C#: Compute enclosing callable as a transitive closure 2021-04-07 17:44:41 +02:00
Jonas Jensen
ab58cb3d44 Merge pull request #5604 from MathiasVP/fix-false-positive-in-assign-where-compare-meant
C++: Fix FP in cpp/assign-where-compare-meant
2021-04-07 16:54:45 +02:00
CodeQL CI
f0491af64c Merge pull request #5529 from erik-krogh/socketInput
Approved by esbena
2021-04-07 15:03:13 +01:00
Asger F
0c724a8427 Merge pull request #5304 from asgerf/js/non-alert-data
JS: Implement new metric queries for line counting
2021-04-07 14:52:51 +01:00
Mathias Vorreiter Pedersen
03b12dbc6d C++: Inline Location::isBefore. 2021-04-07 15:45:08 +02:00
Erik Krogh Kristensen
365b4d722d backtrack string-concatenations from shell-execution sinks 2021-04-07 15:34:54 +02:00
Taus
903f364dab Python: Improve CallCfgNode interface
Call nodes are always local sources (specifically sources of the return
value of the call), and so inheriting from `LocalSourceNode` will have
no effect on results, but _should_ make it a bit more smooth to use the
API.
2021-04-07 13:31:12 +00:00
CodeQL CI
073a43ce74 Merge pull request #5606 from erik-krogh/shellInput
Approved by esbena
2021-04-07 14:30:31 +01:00
Shati Patel
461d4e45af Merge pull request #5608 from shati-patel/docs/telemetry-settings
Docs: Mention telemetry in "customizing settings"
2021-04-07 13:44:32 +01:00
Erik Krogh Kristensen
c9f54ea1ad update expected output 2021-04-07 12:37:17 +00:00
Asger Feldthaus
ee13ff71d6 JS: Add another change note 2021-04-07 12:29:06 +01:00
Asger Feldthaus
26cddc7d04 JS: Update test output 2021-04-07 12:28:45 +01:00
Taus
6c69c1aeeb Python: Minor cleanup 2021-04-07 10:47:21 +00:00
Asger Feldthaus
69973d0fa2 JS: Autoformat 2021-04-07 11:24:11 +01:00
ihsinme
cbf158ea6b Add files via upload 2021-04-07 13:12:30 +03:00
ihsinme
36de496d47 Add files via upload 2021-04-07 13:12:29 +03:00
ihsinme
ed2a8db8c9 Add files via upload 2021-04-07 13:10:01 +03:00
ihsinme
9c3b7e81c7 Add files via upload 2021-04-07 13:10:00 +03:00
Erik Krogh Kristensen
a66083d685 change "Uncontrolled path" to "Path concatenation" 2021-04-07 08:23:07 +00:00
CodeQL CI
fd4e8f8282 Merge pull request #5526 from erik-krogh/quotedShell
Approved by esbena
2021-04-07 08:39:01 +01:00
CodeQL CI
61880ba90a Merge pull request #5530 from erik-krogh/moreFS
Approved by esbena
2021-04-07 08:37:23 +01:00
Robert Marsh
e22ec50dee Merge pull request #5613 from github/hmakholm/pr/fix-redos
Fix ReDOS in cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
2021-04-06 15:54:27 -07:00
Taus
a93132daae Merge branch 'python-allow-absolute-imports-from-source-directory' of https://github.com/tausbn/codeql into python-allow-absolute-imports-from-source-directory 2021-04-06 19:58:57 +00:00
Taus
43ae7462b4 Python: Only track modules that are imported
This greatly restricts the set of modules that have a new name under
this scheme.

One change to the tests was needed, which reflects the fact that the
two `main.py` files no longer have the name `main` (which makes sense,
since they're never imported under this name).
2021-04-06 21:56:12 +02:00
Taus
b44db460f6 Python: Only track modules that are imported 2021-04-06 19:55:43 +00:00
Henning Makholm
2d615ef503 Fix ReDOS in cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
The sub-regex `(\s|.)*` aims to capture arbitrary string content
(in contrast to `.*` which doesn't match newlines), but it is
unsafe, since non-newline whitespace can match both alternatives.

This caused an evaluator crash in the wild.

Replace with `[\s\S]*`, which matches everything in a safe way.
2021-04-06 20:10:57 +02:00
yo-h
cc63563a88 Merge remote-tracking branch 'upstream-public/main' into yo-h/java16 2021-04-06 13:16:02 -04:00
Taus Brock-Nannestad
8e11abca40 Revert "Merge pull request #5552 from RasmusWL/revert-import-change"
This reverts commit 49d1937dc4, reversing
changes made to d4877a9038.
2021-04-06 17:39:41 +02:00
Tamas Vajk
ffcb345916 C#: Add Dapper support to SQL injection queries 2021-04-06 17:06:20 +02:00
Shati Patel
9a41c80626 Merge pull request #5574 from github/smowton/admin/update-supported-go-version
Update supported Go version to 1.16
2021-04-06 14:54:36 +01:00
Shati Patel
695b02a94c Docs: Mention telemetry in "customizing settings" 2021-04-06 14:30:17 +01:00
Erik Krogh Kristensen
2c1cc9ead6 use local variable instead of module.exports in example
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-04-06 15:17:31 +02:00
Tom Hvitved
f45916efda Merge pull request #5605 from hvitved/csharp/exclude-dependency-queries
C#: Remove mentions of `exclude-dependency-queries.yml`
2021-04-06 14:58:49 +02:00
Mathias Vorreiter Pedersen
8382e85901 C++: Add flow into the source of read step and out of the target of a store step for smart pointers in AST dataflow. 2021-04-06 14:05:55 +02:00
Mathias Vorreiter Pedersen
f07d844362 C++: Add a test containing missing read/store dataflow steps for smart pointers. 2021-04-06 13:59:27 +02:00
Tamas Vajk
98001c494f C#: Add Dapper stub and new SqlInjection test cases 2021-04-06 13:30:31 +02:00
Erik Krogh Kristensen
41b89669a9 add joined paths as a sink to js/shell-command-constructed-from-input 2021-04-06 12:14:00 +02:00
Rasmus Wriedt Larsen
bc49bc7095 Python: Add variable with underscore to __all__ tests 2021-04-06 11:54:25 +02:00
Tom Hvitved
e0e58b24ea C#: Remove mentions of exclude-dependency-queries.yml 2021-04-06 11:50:36 +02:00
Rasmus Wriedt Larsen
224d3790b5 Python: Highlight all_indirect.py is not super important
At least not in my mind
2021-04-06 11:50:04 +02:00
Rasmus Wriedt Larsen
b11703cc74 Python: all_dybamic2 => all_indirect 2021-04-06 11:49:55 +02:00
Mathias Vorreiter Pedersen
5eb1f8abbd C++: Add change-note. 2021-04-06 11:47:57 +02:00
Rasmus Wriedt Larsen
0ebb24ebeb Merge pull request #5398 from yoff/python-api-enhancements
Python: Add small api enhancements determined useful during documentation work
2021-04-06 11:44:51 +02:00
Tom Hvitved
667b26b5d9 Merge pull request #5540 from hvitved/csharp/ssa-impl-tweaks
C#: Performance tweaks in `SsaImplCommon.qll`
2021-04-06 11:43:08 +02:00
Mathias Vorreiter Pedersen
a5f4d43d61 C++: Fix false positive by adding another allow-list pattern in AssignWhereCompareMeant. 2021-04-06 11:01:38 +02:00
Mathias Vorreiter Pedersen
7045597139 C++: Add testcase with false positive from #5318. 2021-04-06 10:58:15 +02:00
Erik Krogh Kristensen
c194598d37 recognize headers/url from the HTTP request to a server WebSocket. 2021-04-06 10:11:27 +02:00
Tom Hvitved
e852540254 C#: Remove unique wrappers from DataFlow::Node::get(EnclosingCallable|ControlFlowNode) 2021-04-06 09:56:09 +02:00
Rasmus Lerchedahl Petersen
c777f1d8d7 Merge branch 'main' of github.com:github/codeql into python-api-enhancements 2021-04-06 09:31:26 +02:00
Mathias Vorreiter Pedersen
32a8b9a857 C++: Move copy constructor to its own line and accept test changes. 2021-04-06 08:56:14 +02:00
yoff
a23d8deb10 Merge pull request #5483 from RasmusWL/minor-fixup-django
Python: Better text for getSourceType in Django
2021-04-06 08:30:58 +02:00
Asger Feldthaus
32500c834d JS: Change note 2021-04-01 16:41:03 +01:00
Asger Feldthaus
acc28df785 JS: Bugfix in tsconfig file inclusion handling 2021-04-01 16:33:05 +01:00
Asger Feldthaus
564a6873f8 JS: Add baseUrl test 2021-04-01 16:33:05 +01:00
Asger Feldthaus
c4ab6fb7b4 JS: Add ImportGraph meta query 2021-04-01 16:33:05 +01:00
Asger Feldthaus
f07030ba97 JS: Update AdditionalFlowStep -> SharedFlowStep 2021-04-01 13:16:47 +01:00
Asger Feldthaus
a9566728b5 JS: Update an import of Unit type 2021-04-01 13:16:47 +01:00
Asger Feldthaus
7119eda009 JS: Add redux change note 2021-04-01 13:16:47 +01:00
Asger Feldthaus
86bc0eb853 JS: Autoformat 2021-04-01 13:16:47 +01:00
Asger Feldthaus
b43989e6a1 JS: Use API nodes to track dispatch/dispatched value sources 2021-04-01 13:16:47 +01:00
Asger Feldthaus
2850b8e952 JS: Fix RangeAnalysis after BasicBlock.dominates change 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cbfa5ad303 JS: Change type of a parameter 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cee1a12489 JS: Fix typo in qldoc 2021-04-01 13:16:47 +01:00
Asger Feldthaus
c926a47d50 JS: QLDoc and test for HeuristicConnectEntryPoint 2021-04-01 13:16:47 +01:00
Asger Feldthaus
cca38a64be JS: Add test for flow to a closure body under a type guard 2021-04-01 13:16:46 +01:00
Asger Feldthaus
53def60e4f JS: Add test for if-based type check 2021-04-01 13:16:46 +01:00
Asger Feldthaus
1ce7c3448f JS: Address some review comments 2021-04-01 13:16:46 +01:00
Asger Feldthaus
fd7cbd0c96 JS: Tweak BasicBlock.dominates and friends 2021-04-01 13:16:46 +01:00
Asger Feldthaus
8fa3fb0561 JS: Redux model 2021-04-01 13:16:46 +01:00
Asger Feldthaus
314839fc09 JS: Add @reduxjs/toolkit to composed functions 2021-04-01 13:16:46 +01:00
Asger Feldthaus
c1651ad30c JS: Factor out Unit type 2021-04-01 13:16:46 +01:00
Asger Feldthaus
125d1465c8 JS: Add DataFlow::functionForwardingStep 2021-04-01 13:16:46 +01:00
Asger Feldthaus
a3421e7ab2 JS: Add getALocalUse 2021-04-01 13:16:45 +01:00
CodeQL CI
20416ae034 Merge pull request #5585 from asgerf/js/more-metadata
Approved by esbena
2021-04-01 13:13:01 +01:00
Asger Feldthaus
c96ee8671e JS: Update more query metadata 2021-04-01 12:15:54 +01:00
Luke Cartey
480ce39618 C#: Exclude jump-to-def information for elements with too many locations
In databases which include multiple duplicated files, we can get an
explosion of definition locations that can cause this query to produce
too many results for the CodeQL toolchain. This commit restricts the
definitions.ql query to producing definition/uses for definitions with
fewer than 10 locations. This replicates the logic used in the C++
definitions.qll library which faces similar problems.
2021-04-01 11:23:31 +01:00
CodeQL CI
a1fab8ac52 Merge pull request #5581 from asgerf/js/dependency-info
Approved by esbena
2021-04-01 09:07:21 +01:00
Shati Patel
36bdee0e8b Merge pull request #5571 from github/docs/bug-fix
Docs: Typo fix
2021-03-31 21:59:43 +01:00
Mathias Vorreiter Pedersen
ecbce88ec7 C++: Fix comment. 2021-03-31 22:23:50 +02:00
Rasmus Wriedt Larsen
95ac2c8edd Python: Add another dynamic __all__ test 2021-03-31 17:31:55 +02:00
CodeQL CI
f08a0e5653 Merge pull request #5580 from asgerf/js/more-metadata-fix
Approved by esbena
2021-03-31 16:29:33 +01:00
Rasmus Wriedt Larsen
ab3edf37d7 Python: Handle __all__ assigned to a tuple
Examples where this is used in real code:

- 76c0b32f82/django/core/files/temp.py (L24)
- 76c0b32f82/django/contrib/gis/gdal/__init__.py (L44-L49)
2021-03-31 17:25:19 +02:00
Rasmus Wriedt Larsen
43306f4700 Python: Add tests for Module.declaredInAll 2021-03-31 17:24:17 +02:00
Asger Feldthaus
8c8e4e6a70 JS: Add test 2021-03-31 16:17:54 +01:00
Asger Feldthaus
068a9d88e7 JS: Ensure Dependency.info() exists even if version range could not be parsed 2021-03-31 16:08:08 +01:00
Asger Feldthaus
c541390c1b JS: Remove precision tag from ExternalDependencies.ql 2021-03-31 13:54:15 +01:00
Mathias Vorreiter Pedersen
9ff894bf83 C++: Add support for AST dataflow out of functions that take a smart pointer by value. 2021-03-31 13:54:32 +02:00
Mathias Vorreiter Pedersen
e9e93c0eea Merge pull request #5558 from geoffw0/replace-tostring
Replace toString use
2021-03-31 13:50:41 +02:00
Geoffrey White
85ecfe2723 Update cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2021-03-31 11:34:56 +01:00
Mathias Vorreiter Pedersen
8159098dc0 C++: Add test from issue #5190. 2021-03-31 11:32:01 +02:00
Calum Grant
49d1937dc4 Merge pull request #5552 from RasmusWL/revert-import-change
Python: Revert #5506 due to bad performance
2021-03-31 09:51:39 +01:00
Asger F
d4877a9038 Merge pull request #5572 from asgerf/js/remove-flow-summary-kinds
JS: Change kind of summary-extraction queries to table
2021-03-31 09:28:56 +01:00
Asger Feldthaus
57784dc746 JS: Update test output 2021-03-31 09:23:47 +01:00
Chris Smowton
4f9b6d1192 Update supported Go version to 1.16 2021-03-31 08:56:27 +01:00
Asger Feldthaus
bc5b477f79 JS: Change kind of summary-extraction queries to table 2021-03-30 21:26:58 +01:00
Dave Bartolomeo
0cc8eaf3b4 Merge pull request #5543 from MathiasVP/smart-ptr-like-class
C++: Add a class that models wrapped pointer types
2021-03-30 16:00:13 -04:00
Rasmus Wriedt Larsen
51c27de049 Merge branch 'main' into revert-import-change 2021-03-30 21:51:53 +02:00
Shati Patel
b9788eb53c Merge pull request #5568 from shati-patel/docs-binding-sets
Docs: Mention that binding sets are available for classes
2021-03-30 18:08:23 +01:00
Sarita Iyer
649286995a Merge pull request #5562 from saritai/saritai/cli-remove-1.23-references
Remove Enterprise 1.23 special instructions and replace references
2021-03-30 13:07:42 -04:00
Shati Patel
fb004bacc3 Describe predicates first 2021-03-30 17:31:20 +01:00
Shati Patel
67835ee273 Address review comments 2021-03-30 17:29:43 +01:00
Shati Patel
23df459c16 remove accidental punctuation 2021-03-30 17:23:33 +01:00
Mathias Vorreiter Pedersen
fe76b0849b Merge pull request #5569 from geoffw0/memoryfree
C++: Add a test of memory freed queries with strdup.
2021-03-30 17:22:18 +02:00
Mathias Vorreiter Pedersen
92839123ae Merge pull request #5570 from geoffw0/mutextest
C++: Add mutex test cases.
2021-03-30 17:16:19 +02:00
Geoffrey White
a8284d5b97 C++: Add mutex test case. 2021-03-30 15:39:21 +01:00
Sarah Edwards
e0a73ce797 Merge pull request #5560 from skedwards88/patch-1
download LGTM database from a project slug
2021-03-30 06:58:28 -07:00
Geoffrey White
244966e216 C++: Add a test with strdup. 2021-03-30 14:49:05 +01:00
Shati Patel
62de15cd22 Docs: Mention that binding sets are available for classes 2021-03-30 14:46:59 +01:00
Asger Feldthaus
f8bbda0cdc JS: Change note 2021-03-30 13:54:01 +01:00
Asger Feldthaus
9db235ac36 JS: Improve @google-cloud/spanner model 2021-03-30 13:54:00 +01:00
Asger Feldthaus
35f294f096 JS: Improve sequelize model 2021-03-30 13:54:00 +01:00
Mathias Vorreiter Pedersen
4b51e22bb4 Merge pull request #5565 from geoffw0/avrule79
C++: Test strdup with AV rule 79
2021-03-30 14:34:46 +02:00
Geoffrey White
ec952248a9 C++: Test strdup with AV Rule 79. 2021-03-30 12:58:04 +01:00
Geoffrey White
f27203cc43 C++: Test spacing. 2021-03-30 12:57:43 +01:00
luchua-bc
1349bf7b0b Create a .qll file to reuse the code and add check of Spring properties 2021-03-30 11:25:29 +00:00
Asger Feldthaus
93500bd95a JS: Improve mssql model 2021-03-30 11:34:01 +01:00
Asger Feldthaus
95937c9ac7 JS: Improve sqlite3 model 2021-03-30 11:34:01 +01:00
Asger Feldthaus
0b21b273ed JS: Improve pg model 2021-03-30 11:33:59 +01:00
Asger Feldthaus
937a620f4d JS: Improve mysql2 model 2021-03-30 11:33:42 +01:00
CodeQL CI
e8d7925084 Merge pull request #5555 from asgerf/js/misc-steps
Approved by esbena
2021-03-30 11:30:12 +01:00
CodeQL CI
25e26b9ac0 Merge pull request #5554 from asgerf/js/non-recursive-propref
Approved by esbena
2021-03-30 11:29:32 +01:00
CodeQL CI
6cceb73807 Merge pull request #5553 from asgerf/js/pg-promise
Approved by esbena
2021-03-30 11:28:24 +01:00
Geoffrey White
d2b991bcb5 Merge pull request #5541 from MathiasVP/definitions-for-unique_ptr
C++: Add shared_ptr and unique_ptr implementations
2021-03-30 09:47:56 +01:00
Mathias Vorreiter Pedersen
09ba25fe9b C++: Accept test changes. I'm actually not sure why we lose these results (and lose the field conflation, yay) It might be due to #3364. 2021-03-30 10:24:01 +02:00
Mathias Vorreiter Pedersen
8c95a9ae39 Merge branch 'main' into definitions-for-unique_ptr 2021-03-30 10:20:36 +02:00
Laura Coursen
2dadc752d6 Merge pull request #5563 from lecoursen/stronger-rec-to-use-lgtm.com-branch
Make stronger recommendations around the use of the lgtm.com branch
2021-03-29 14:29:24 -05:00
Laura Coursen
d57ec5d1ac Merge branch 'stronger-rec-to-use-lgtm.com-branch' of https://github.com/lecoursen/codeql into stronger-rec-to-use-lgtm.com-branch 2021-03-29 14:05:46 -05:00
Laura Coursen
e3b052199a Suggest lgtm.com branch first 2021-03-29 14:04:59 -05:00
Laura Coursen
eb01ffbdae Use correct terminology
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-03-29 14:03:30 -05:00
Ethan Palm
2f98212eca Merge pull request #5561 from ethanpalm/fix-broken-links
Fix broken links
2021-03-29 14:28:49 -04:00
Laura Coursen
8f1c7c57a8 Add 💅 2021-03-29 12:53:16 -05:00
Ethan P
909dc84bb6 Update broken link 2021-03-29 13:46:45 -04:00
Laura Coursen
a18cd74756 Fix typo 2021-03-29 12:42:09 -05:00
Laura Coursen
21576387f3 Add 💅 2021-03-29 12:41:48 -05:00
Laura Coursen
50523e0ac0 Clarify use cases for lgtm.com branch 2021-03-29 12:40:31 -05:00
Ethan P
d126c0a1d3 Fix broken links 2021-03-29 13:38:04 -04:00
Sarita Iyer
3db5dd4661 removed 1.23 instructions and replaced references
Removed special instructions for LGTM 1.23, and replaced leftover references to 1.23 with 1.27.
2021-03-29 13:37:55 -04:00
Sarah Edwards
108bcef104 download LGTM database from a project slug 2021-03-29 10:37:00 -07:00
Henry Mercer
0f710b1981 Merge pull request #5545 from github/henrymercer/ql-pack-version-doc-update
CodeQL CLI Docs: Mention that QL packs use SemVer versioning
2021-03-29 18:18:45 +01:00
Calum Grant
c26d05b1d5 Merge pull request #5532 from RasmusWL/python-cleanup
Python: Delete filter queries, code duplication library, and precision tag from metric queries
2021-03-29 17:16:43 +01:00
Mathias Vorreiter Pedersen
5a4efab742 C++: Add tests for shared_ptr. 2021-03-29 18:04:20 +02:00
Rasmus Wriedt Larsen
96a66fa4ee Python: Apply suggestions from code review 2021-03-29 17:02:56 +02:00
Asger Feldthaus
67ad6d9a0f JS: Update test output 2021-03-29 15:30:29 +01:00
Asger Feldthaus
faf07dac91 JS: Autoformat 2021-03-29 14:52:37 +01:00
Asger Feldthaus
3e26236648 JS: Add recursion guard test 2021-03-29 14:32:13 +01:00
Asger Feldthaus
2770a53d38 JS: More babel.transform steps 2021-03-29 13:00:23 +01:00
Asger Feldthaus
c103939c2d JS: Fix handling of createRequire 2021-03-29 12:47:23 +01:00
Asger Feldthaus
49ca88957c JS: Use types 2021-03-29 12:25:15 +01:00
Asger Feldthaus
603843e698 JS: Add task tests 2021-03-29 12:05:47 +01:00
CodeQL CI
3613ceb07f Merge pull request #5535 from tausbn/python-prevent-bad-TCs
Approved by yoff
2021-03-29 12:03:08 +01:00
Asger F
f1d0b50670 Update javascript/ql/src/semmle/javascript/frameworks/SQL.qll
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-03-29 11:54:45 +01:00
Asger Feldthaus
f453fe26c6 JS: Autoformat 2021-03-29 11:28:46 +01:00
Asger Feldthaus
b381f4826c JS: Add change note 2021-03-29 11:25:28 +01:00
Asger Feldthaus
149af57eac JS: Add model of pg-promise 2021-03-29 11:25:28 +01:00
Asger Feldthaus
88fee2748e JS: Add change note 2021-03-29 11:21:03 +01:00
haby0
0775d35591 update VerificationMethodFlowConfig, add if test 2021-03-29 12:02:37 +08:00
ihsinme
3f215d0954 Update OperatorPrecedenceLogicErrorWhenUseBoolType.ql 2021-03-28 23:43:22 +03:00
ihsinme
093c63ea3b Update OperatorPrecedenceLogicErrorWhenUseBoolType.expected 2021-03-28 23:42:36 +03:00
luchua-bc
5ce3f9d6ff Update qldoc and enhance the query 2021-03-28 16:10:35 +00:00
Rasmus Wriedt Larsen
92e0e195a4 Revert "Merge pull request #5506 from tausbn/python-allow-absolute-imports-from-source-directory"
This reverts commit 8d15680af4, reversing
changes made to 63831cc62b.

This PR caused performance problems, so reverting now to clear up immediate
problems.
2021-03-27 18:08:20 +01:00
luchua-bc
a53cbc1631 Update qldoc and make the query more readable 2021-03-27 00:11:01 +00:00
Geoffrey White
c6e7b8d4fd C++: Repair test. 2021-03-26 19:12:09 +00:00
Geoffrey White
4100d68a71 C++: Test failures. 2021-03-26 18:21:05 +00:00
Geoffrey White
725122decc C++: Replace toString logic. 2021-03-26 17:29:05 +00:00
luchua-bc
a72b1340eb Add a comment on how to run the query 2021-03-26 16:51:43 +00:00
Taus Brock-Nannestad
f17bbd9982 Python: Fix another bad TC.
This one is a bit awkward, since the previous version was supposed to
improve indexing. Unfortunately this is vastly outweighed by the slow
convergence of the TC. Right now we pay the cost of inverting the
`hasFlowSource` relation, but this is still cheaper.
2021-03-26 16:38:13 +01:00
Henry Mercer
c83daa66e7 CodeQL CLI Docs: Mention that QL packs use SemVer versioning 2021-03-26 15:30:23 +00:00
Mathias Vorreiter Pedersen
b466f0515d C++: Respond to more review comments. (1) Use getClassAndName to ensure a good join order, and (2) unify the two abstract predicates on PointerWrapper. 2021-03-26 16:16:23 +01:00
Mathias Vorreiter Pedersen
0ce08617ba C++: Respond to review comments. 2021-03-26 13:42:18 +01:00
Tom Hvitved
e345064a53 C#: Performance tweaks in SsaImplCommon.qll 2021-03-26 13:24:34 +01:00
Jonas Jensen
7f16c52217 Merge pull request #3364 from github/rdmarsh/cpp/use-taint-configuration-dtt
C++: use TaintTracking::Configuration in DefaultTaintTracking
2021-03-26 12:39:25 +01:00
Alexander Eyers-Taylor
b21672c81c Apply suggestions from code review
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-03-26 11:15:46 +00:00
Tom Hvitved
1dbfe2369d Merge pull request #5542 from hvitved/csharp/update-suites
C#: Remove deleted queries from suites
2021-03-26 12:13:09 +01:00
CodeQL CI
f584ff9acf Merge pull request #5533 from asgerf/js/fix-query-metadata
Approved by esbena
2021-03-26 11:09:54 +00:00
Mathias Vorreiter Pedersen
8dc7b6403a C++: Add shared_ptr and unique_ptr implementations. Also add some very basic tests. 2021-03-26 12:03:59 +01:00
Mathias Vorreiter Pedersen
d20a0c9e82 C++: Add a class that models wrapped pointer types. 2021-03-26 11:50:06 +01:00
Asger Feldthaus
cc2a531684 JS: Cache PropRef.getBase 2021-03-26 10:48:25 +00:00
Tom Hvitved
9d1ef21d85 C#: Remove deleted queries from suites 2021-03-26 11:17:27 +01:00
Mathias Vorreiter Pedersen
c7c65736a9 C++: Accept test changes. These happened because of the incorrect usage of multiple configurations in 6c1ec6d96b. 2021-03-26 10:57:58 +01:00
Jonas Jensen
86755c6a98 Merge pull request #5515 from criemen/fix-query-metadata
C++: Fix query metadata warnings.
2021-03-26 10:19:46 +01:00
Anders Schack-Mulligen
506c95d098 Merge pull request #5372 from smowton/smowton/feature/commons-lang-models-to-csv
Java: Convert existing Commons Lang models to CSV
2021-03-26 10:18:23 +01:00
Tom Hvitved
d4ce42ac4f Merge pull request #5416 from hvitved/csharp/rework-summaries
C#: Rework flow summary implementation
2021-03-26 09:47:15 +01:00
Tom Hvitved
e93b72d563 Merge pull request #5459 from hvitved/csharp/update-nuget
C#: Update more nuget packages
2021-03-26 09:28:09 +01:00
Mathias Vorreiter Pedersen
983b64a05f Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-26 09:11:12 +01:00
Tom Hvitved
57fd2e3578 C#: Rename parameter in fieldOf() 2021-03-26 08:49:06 +01:00
luchua-bc
d33b04cd96 Query to detect plaintext credentials in Java properties files 2021-03-26 02:33:40 +00:00
Porcuiney Hairs
2ca95166d9 Java : add query to detect insecure loading of Dex File 2021-03-26 01:59:11 +05:30
yoff
208d5157fa Merge pull request #5500 from RasmusWL/django-forms
Python: Model RemoteFlowSources on Django forms/fields
2021-03-25 20:43:19 +01:00
alexet
2576c86ebf Docs: Update the language specification for changes to super. 2021-03-25 18:16:13 +00:00
Taus Brock-Nannestad
c2f112cb92 Python: Filter _before_ the cartesian product
It's always a sad thing to see a good plan go wrong:

86860032 ~0%      {4} r26 = JOIN r19 WITH DataFlowPublic::TupleElementContent#class#ff CARTESIAN PRODUCT OUTPUT Lhs.0 'nodeFrom', Lhs.1 'nodeTo', Rhs.0, Rhs.1
129256   ~3%      {4} r27 = SELECT r26 ON In.3 <= 7
129256   ~0%      {3} r28 = SCAN r27 OUTPUT In.0 'nodeFrom', In.2 'c', In.1 'nodeTo'

Happily, now it looks like this:

129256  ~0%      {3} r20 = JOIN r19 WITH DataFlowPrivate::small_tuple#f CARTESIAN PRODUCT OUTPUT Lhs.0 'nodeFrom', Rhs.0, Lhs.1 'nodeTo'
2021-03-25 19:06:05 +01:00
Erik Krogh Kristensen
5e59f6d558 Update javascript/ql/src/semmle/javascript/security/dataflow/ShellCommandInjectionFromEnvironmentCustomizations.qll
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-03-25 19:03:37 +01:00
Taus Brock-Nannestad
8734df334b Python: Slight cleanup 2021-03-25 18:35:16 +01:00
Taus Brock-Nannestad
229250dc54 Python: Limit size of TupleElementContent
A more principled approach is possible here, but in the short term
this will prevent an explosion.

For reference, openstack/cinder has roughly 19000 `ForTarget`s and
tuples of size up to 5300, and we were calculating the cartesian
product of these.
2021-03-25 18:28:49 +01:00
yoff
716e0f1404 Merge pull request #5517 from tausbn/python-prevent-potentially-bad-join-order
Python: Prevent potentially bad join order
2021-03-25 18:14:47 +01:00
Tom Hvitved
f100c8a9c0 C++: Make Windows autobuilder tests pass again 2021-03-25 17:43:48 +01:00
Tom Hvitved
ed78acb1d4 C#: Update more nuget packages 2021-03-25 17:32:12 +01:00
Taus Brock-Nannestad
dbef36cbbb Python: Prevent bad TC and add a bit of caching
Using `simpleLocalFlowStep+` with the first argument specialised to
`CfgNode` was causing the compiler to turn this into a very slowly
converging manual TC computation.

Instead, we use `simpleLocalFlowStep*` (which is fast) and then join
that with a single step from any `CfgNode`. This should amount to the
same thing.

I also noticed that the charpred for `LocalSourceNode` was getting
recomputed a lot, so this is now cached. (The recomputation was
especially bad since it relied on `simpleLocalFlowStep+`, but anyway
it's a good idea not to recompute this.)
2021-03-25 17:28:37 +01:00
Chris Smowton
eaa2d4d831 Stop using wildcard Argument
All instances are replaced with a specific Argument or range.
2021-03-25 15:42:35 +00:00
Chris Smowton
2f34588770 Constructor models: use Argument[-1] for the result, not ReturnValue 2021-03-25 15:23:08 +00:00
Asger Feldthaus
a456458a38 JS: Add change note for code duplication library removal 2021-03-25 15:21:48 +00:00
Asger Feldthaus
446ad5ec9e JS: Remove code duplication library 2021-03-25 15:20:59 +00:00
Asger Feldthaus
c812bd948a JS: Add @problem.severity to an example query 2021-03-25 15:14:48 +00:00
Asger Feldthaus
7aae51c876 JS: Add change note for filter query removal 2021-03-25 15:13:51 +00:00
Anders Schack-Mulligen
28fb0edfbe Merge pull request #4920 from luchua-bc/java/hash-without-salt
Java: Query to detect hash without salt
2021-03-25 16:13:26 +01:00
Asger Feldthaus
6cab85712f JS: Delete filter queries 2021-03-25 15:12:35 +00:00
Asger Feldthaus
1c27ca610a JS: Remove precision atags from metric queries 2021-03-25 15:12:09 +00:00
Chris Smowton
a5220bf616 Convert StrBuilder models to CSV 2021-03-25 15:11:52 +00:00
Chris Smowton
25a0e09130 Convert StringUtils models to CSV 2021-03-25 15:11:52 +00:00
Chris Smowton
1beac06236 Translate ArrayUtils models to CSV 2021-03-25 15:11:51 +00:00
Chris Smowton
7fb5bd0cab Add tests for and slightly expand models of Commons Lang's ArrayUtils class 2021-03-25 15:11:51 +00:00
Rasmus Wriedt Larsen
9abe02f419 Python: Fix query metadata for old queries that have been ported
I'm not sure even I want to keep these around much longer. They seem to be
causing more problem than they are doing good.
2021-03-25 16:01:56 +01:00
Jonas Jensen
bc9682c22d Merge pull request #5528 from MathiasVP/fix-join-order-in-avrule-79
C++: Fix join order in AV rule 79
2021-03-25 15:45:41 +01:00
Rasmus Wriedt Larsen
ed2cb739c5 Merge pull request #5486 from yoff/python-document-api-import-node
Python, doc: Note ephemeral nature of import nodes
2021-03-25 15:45:10 +01:00
Anders Schack-Mulligen
344c2d3c3d Update java/ql/src/experimental/Security/CWE/CWE-759/HashWithoutSalt.ql 2021-03-25 15:42:57 +01:00
Tom Hvitved
90868a4788 Merge pull request #5524 from hvitved/csharp/cleanup
C#: Remove legacy queries and `@precision` tags from metric queries
2021-03-25 15:36:12 +01:00
Rasmus Wriedt Larsen
203b0e3d88 Python: Add change note 2021-03-25 15:34:09 +01:00
Tom Hvitved
cdd613358b C#: Sync SSA files 2021-03-25 15:33:06 +01:00
Tom Hvitved
7e20829f36 Merge remote-tracking branch 'upstream/main' into csharp/rework-summaries 2021-03-25 15:32:32 +01:00
Tom Hvitved
6a3859fc83 C#: Remove unnecessary pre call in FlowSummaryImpl.qll 2021-03-25 15:31:43 +01:00
Rasmus Wriedt Larsen
bd4934380a Python: Remove code duplication library 2021-03-25 15:27:55 +01:00
Tom Hvitved
33c990f6b0 Merge pull request #5440 from hvitved/csharp/cil/ssa
C#: Add CIL SSA library
2021-03-25 15:22:40 +01:00
Erik Krogh Kristensen
3d49b8cb91 consider quoted string concatenations as sanitizers for js/shell-command-injection-from-environment 2021-03-25 15:17:02 +01:00
yo-h
0fe4baec34 Merge pull request #5525 from aschackmull/java/cleanup
Java: Delete filter queries, code duplication library, and precision tag from metric queries.
2021-03-25 10:09:41 -04:00
Rasmus Wriedt Larsen
09fbf480db Python: Remove precision tag from metric queries 2021-03-25 15:06:47 +01:00
Rasmus Wriedt Larsen
e3b2e0a1de Python: Delete filter queries 2021-03-25 15:06:46 +01:00
Erik Krogh Kristensen
3b82452d76 detect fs modules that pass through a reduce call 2021-03-25 14:47:43 +01:00
Anders Schack-Mulligen
75afa011ff Java: Add metadata to several more experimental queries. 2021-03-25 13:09:26 +01:00
CodeQL CI
e90035a5a5 Merge pull request #5439 from erik-krogh/topPack
Approved by esbena
2021-03-25 11:49:03 +00:00
Mathias Vorreiter Pedersen
24360d3a4c C++: Fix join order in AV rule 79 by joining with GVN after the recursive call. 2021-03-25 12:00:49 +01:00
Erik Krogh Kristensen
77ba7b473d Merge branch 'main' into topPack 2021-03-25 11:52:58 +01:00
CodeQL CI
0511e72520 Merge pull request #5458 from erik-krogh/shellTrue
Approved by asgerf
2021-03-25 10:49:24 +00:00
luchua-bc
57bd3f3c14 Optimize the taint flow source 2021-03-25 10:44:26 +00:00
Tom Hvitved
6bfc49c069 C#: Address review comments 2021-03-25 11:43:25 +01:00
yoff
32b264bdee Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2021-03-25 10:48:59 +01:00
Anders Schack-Mulligen
d53c334488 Merge branch 'java/fix-experimental-query-metadata' into java/cleanup 2021-03-25 10:36:36 +01:00
Anders Schack-Mulligen
28ff3f412d Java: Add severity and precision metadata to experimental queries. 2021-03-25 10:29:47 +01:00
Cornelius Riemenschneider
867471b122 C++: Delete old queries. 2021-03-25 10:23:17 +01:00
CodeQL CI
9d52db3ca7 Merge pull request #5507 from erik-krogh/joins
Approved by asgerf
2021-03-25 09:18:26 +00:00
Anders Schack-Mulligen
5b905cfe18 Java: Add change note for code duplication library removal. 2021-03-25 10:12:58 +01:00
Anders Schack-Mulligen
1564aee57a Java: Add change note for filter query removal. 2021-03-25 10:11:30 +01:00
Anders Schack-Mulligen
c82b5eb040 Java: Remove code duplication library. 2021-03-25 10:06:10 +01:00
Asger Feldthaus
dbc6cf63c2 JS: Fix bad join order in PropertyProjection 2021-03-25 09:00:10 +00:00
Asger Feldthaus
bd3f6d1234 JS: Add o[o.length] = y taint step 2021-03-25 09:00:10 +00:00
Asger Feldthaus
51f489211b JS: Support react-native-base64 2021-03-25 09:00:10 +00:00
Asger Feldthaus
5d9778c64d JS: Step through babel.transform 2021-03-25 09:00:10 +00:00
Asger Feldthaus
3e67ebacb0 JS: Support lodash-es 2021-03-25 09:00:10 +00:00
Erik Krogh Kristensen
3b6b40489f Merge branch 'main' into topPack 2021-03-25 09:58:15 +01:00
Anders Schack-Mulligen
4b7440d4d5 Java: Remove precision tag from metric queries. 2021-03-25 09:52:05 +01:00
Tom Hvitved
419fbe77ab C#: Remove @precision tags from metric queries 2021-03-25 09:50:24 +01:00
Tom Hvitved
b83da2255c C#: Add change note 2021-03-25 09:50:24 +01:00
Tom Hvitved
b94c189946 C#: Remove VulnerablePackage.ql query 2021-03-25 09:50:24 +01:00
Tom Hvitved
7e33b571c9 C#: Add change note 2021-03-25 09:50:24 +01:00
Tom Hvitved
eeb8c74666 C#: Remove filter and external queries
These are legacy queries that are no longer used.
2021-03-25 09:50:01 +01:00
Anders Schack-Mulligen
70824b3f0b Java: Delete filter queries. 2021-03-25 09:47:31 +01:00
Esben Sparre Andreasen
801eb538db Merge pull request #5514 from github/aibaars/fix-javascript-metadata
Javascript: remove bad QLDoc tag
2021-03-25 08:56:08 +01:00
luchua-bc
fe0e7f5eac Change method check to taint flow 2021-03-25 01:45:13 +00:00
luchua-bc
08c3bf26d5 Update the query to accommodate more cases 2021-03-24 23:32:27 +00:00
Taus Brock-Nannestad
0ae8b69102 Python: Prevent joining on scope in PointsToContext::appliesTo
One of those cases where I _wish_ `pragma[inline]` also meant "don't
join on the stuff inside this predicate -- it's inlined for a reason".

Unsurprisingly, joining on the scope first works poorly.
2021-03-24 23:12:48 +01:00
Taus Brock-Nannestad
28d6cad3d0 Python: Prevent joining on name as the first thing
Many instances of `lookup` are restricted by the presence of
`attributeRequired`, but this does not work well if we join on
`name`. A few instances of `only_bind_into` prevents this.
2021-03-24 23:11:09 +01:00
yo-h
72ae902e0d Merge pull request #5371 from aschackmull/java/framework-coverage
Java: Add query for CSV framework coverage.
2021-03-24 17:36:13 -04:00
Erik Krogh Kristensen
c146b27c1a Merge branch 'main' into shellTrue 2021-03-24 20:09:23 +01:00
CodeQL CI
8ff9c98d26 Merge pull request #5449 from erik-krogh/asExec
Approved by esbena
2021-03-24 19:04:30 +00:00
Aditya Sharad
32dc894d54 Merge pull request #5516 from github/adityasharad/actions/remove-docs-review-workflow
Actions: Remove docs-review workflow
2021-03-24 11:48:03 -07:00
Aditya Sharad
a0465d20cb Actions: Remove docs-review workflow
Being replaced by internal automation that polls the repo for open labelled PRs, since this workflow currently cannot tag the docs team in a comment.
2021-03-24 11:26:00 -07:00
Taus Brock-Nannestad
ed8ffab356 Python: Prevent potentially bad join order
This has no effect on the current compilation (indeed,
`ssa_filter_definition_bool` is not currently inlined), but will
prevent this from ever occurring, should the heuristics for inlining
ever change...
2021-03-24 19:20:19 +01:00
Cornelius Riemenschneider
47530d7526 C++: Fix query metadata warnings. 2021-03-24 18:01:21 +01:00
Arthur Baars
b25dc03dac Javascript: remove bad QLDoc tag 2021-03-24 16:47:27 +01:00
Asger Feldthaus
e13a9c9716 JS: Avoid recursion through SourceNode::Range, again 2021-03-24 15:26:50 +00:00
Anders Schack-Mulligen
d3485cac34 Merge pull request #5512 from aschackmull/java/csv-argument-ranges
Java: Support argument and parameter ranges in CSV models.
2021-03-24 15:03:22 +01:00
yoff
8d15680af4 Merge pull request #5506 from tausbn/python-allow-absolute-imports-from-source-directory
Python: Allow absolute imports in directories with scripts
2021-03-24 14:42:14 +01:00
Anders Schack-Mulligen
4955f95f64 Apply suggestions from code review
Clarify documentation.

Co-authored-by: Chris Smowton <smowton@github.com>
2021-03-24 14:32:18 +01:00
Anders Schack-Mulligen
63831cc62b Merge pull request #5099 from porcupineyhairs/javaLogInjection
Java : Add Log Injection Vulnerability
2021-03-24 14:30:34 +01:00
yoff
b023d73016 Merge pull request #5504 from RasmusWL/type-tracking-first-predicate-private
Python: Ensure first type-tracking predicate is private
2021-03-24 14:23:27 +01:00
Rasmus Wriedt Larsen
1473778bb8 Merge pull request #5493 from yoff/python-add-experimental-structure
Python: Add stub structure to `experimental` for external contributions
2021-03-24 14:11:13 +01:00
Rasmus Wriedt Larsen
70974ea197 Python: Fix grammar in QLDoc
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-03-24 14:06:06 +01:00
Taus Brock-Nannestad
47686a6e4c Python: Disregard all files matching .py% 2021-03-24 14:03:00 +01:00
Taus Brock-Nannestad
8d30ee5c3c Python: Include unmarked Python file in snapshot
Sadly, it seems we're not interpreting this as Python code, even if we
explicitly ask to have it included.
2021-03-24 14:01:13 +01:00
Anders Schack-Mulligen
a1ccbcdaf1 Merge pull request #5260 from artem-smotrakov/spring-http-invoker
Java: Query for detecting unsafe deserialization with Spring exporters
2021-03-24 13:57:17 +01:00
Asger Feldthaus
de879c0707 JS: Make PropRef.getBase non-recursive 2021-03-24 12:57:16 +00:00
Asger Feldthaus
2f2d72f282 JS: Improve react-router support 2021-03-24 12:53:26 +00:00
Asger Feldthaus
88932a495c JS: Handle redux-form HOCs 2021-03-24 12:53:26 +00:00
Rasmus Wriedt Larsen
59200386a7 Python: Fix mistake in refactor 2021-03-24 13:51:29 +01:00
Tom Hvitved
f2fb26df37 C#: Document input/output stack restrictions 2021-03-24 13:48:32 +01:00
CodeQL CI
e3ab94fc6b Merge pull request #5498 from asgerf/js/flow-through-accessors
Approved by erik-krogh, max-schaefer
2021-03-24 12:46:05 +00:00
Anders Schack-Mulligen
41168e2b36 Java: Support argument and parameter ranges. 2021-03-24 13:32:30 +01:00
Anders Schack-Mulligen
234f62fd05 Java: Merge packages that likely belong to the same framework. 2021-03-24 13:17:04 +01:00
Taus Brock-Nannestad
6d86239929 Python: Test all cases
Note that the test in `no_py_extension` isn't complete, since we're
not extracting the `main` file there.
2021-03-24 13:15:59 +01:00
Erik Krogh Kristensen
9610ed163a remove SourceNode type to preserve behavior 2021-03-24 11:59:56 +01:00
CodeQL CI
12a6410a0a Merge pull request #5478 from asgerf/js/shared-flow-step
Approved by erik-krogh
2021-03-24 10:58:30 +00:00
Tom Hvitved
c5c80204d5 C#: Rework flow summary implementation 2021-03-24 11:27:01 +01:00
Tom Hvitved
c96b8301ed C#: Add change note 2021-03-24 09:58:44 +01:00
haby0
3df23eecb6 Merge remote-tracking branch 'upstream/main' into JsonHijacking 2021-03-24 15:52:01 +08:00
Anders Schack-Mulligen
02a5c0875e Merge pull request #5502 from smowton/smowton/fix/less-fluent-method-inferred-edges
Java: partial revert: only introduce inferred taint edges from callsite-crossing value edges if an original taint edge targets the *start* of the value edge.
2021-03-24 08:41:51 +01:00
Rasmus Lerchedahl Petersen
a9af135d7e Python: Remove getALocalTaintSource
and `taintFlowsTo` for now..
2021-03-24 01:22:21 +01:00
yoff
ac0430883a Update docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-24 01:08:12 +01:00
yoff
61cff8faed Update python/ql/src/experimental/semmle/python/Concepts.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-03-24 01:06:03 +01:00
Erik Krogh Kristensen
b8bfdcc719 improve performance in ServiceDefinitions by inlining, and refactoring away a SourceNode 2021-03-23 19:13:40 +01:00
Erik Krogh Kristensen
93bcc3724a use pragma to improve 2 join-orders in TaintTracking 2021-03-23 19:12:33 +01:00
Taus Brock-Nannestad
17d1768259 Python: Allow absolute imports in directories with scripts
Fixes the import logic to account for absolute imports.

We do this by classifying which files and folders may serve as the
entry point for execution, based on a few simple heuristics. If the
file `module.py` is in the same folder as a file `main.py` that may be
executed directly, then we allow `module` to be a valid name for
`module.py` so that `import module` will work as expected.
2021-03-23 18:32:17 +01:00
Taus Brock-Nannestad
4289e358bf Python: Add module import test case
This one will require some explanation...

First, the file structure. This commit adds a test consisting
representing a few different kinds of imports.

- Absolute imports, from `module.py` to `main.py` when the latter is
  executed directly.
- A package (contained in the `package` folder)
- A namespace package (contained in the `namespace_package` folder)

All of these are inside a folder called `code` for reasons I will
detail later.

The file `main.py` is identified as a script, by the presence of the
`!#` comment in its first line.

The files themselves are executable, and `python3 main.py` will print
out all modules in the order they are imported.

The test itself is very simple. It simply lists all modules and their
corresponding names. As is plainly visible, without modification we
only pick up `package` and its component modules as having names. This
is the bit that needs to be fixed.

Convincing the test runner to extract this test in a way that mimics
reality is, unfortunately, a bit complicated. By default, the test
runner itself includes any Python files in the test directory as
modules in the invocation of the extractor, and so we must hide
everything in the `code` subdirectory.

Secondly, a `--path` argument (set to the test directory) is
automatically added, and this would also interfere with extraction,
and hence we must prevent this. Luckily, if we supply our own `--path`
argument -- even if it doesn't make any sense -- then the other
argument is left out.

Finally, we must actually tell the extractor to extract the files (or
it would just happily pass the test with zero files extracted), so the
`-R .` argument ensures that we recurse over the files in the test
directory after all.
2021-03-23 18:21:58 +01:00
Tom Hvitved
6d6150d051 C#: Change some data-flow toString()s 2021-03-23 16:42:58 +01:00
Rasmus Wriedt Larsen
deefbefffc Python: Minor refactor to use CallCfgNode 2021-03-23 16:42:41 +01:00
Rasmus Wriedt Larsen
1f5e52e822 Python: Cleanup "first" type-tracking predicate to be private
Since it's exposed nicely in the version that doesn't have a
`DataFlow::TypeTracker` parameter, these should be private.

Also found one instance where I had accidentially used DataFlow::Node instead of
LocalSourceNode
2021-03-23 16:40:56 +01:00
Asger Feldthaus
98cee7d339 JS: Update Collection step test and its output 2021-03-23 14:53:15 +00:00
Asger Feldthaus
c067d519d9 JS: Inline some public predicates in GlobalAccessPaths 2021-03-23 14:53:15 +00:00
Asger Feldthaus
61e89d4841 JS: Cache StepSummary and PropertyName 2021-03-23 14:53:14 +00:00
Asger Feldthaus
0056c39bdd JS: Deprecate AdditionalFlowStep 2021-03-23 14:53:14 +00:00
Asger Feldthaus
9e6aac8ef4 JS: Deprecate CollectionFlowStep 2021-03-23 14:53:14 +00:00
Asger Feldthaus
f8f3770a58 JS: BadRandomness can just use type-tracking now 2021-03-23 14:53:14 +00:00
Asger Feldthaus
52c2e37aca JS: Update CollectionStep usage in HTTP 2021-03-23 14:53:14 +00:00
Asger Feldthaus
2759d53f42 JS: SetKeys 2021-03-23 14:53:14 +00:00
Asger Feldthaus
c5ddd40dc3 JS: MapAndSetValues 2021-03-23 14:53:14 +00:00
Asger Feldthaus
9abaad65c6 JS: MapSet 2021-03-23 14:53:14 +00:00
Asger Feldthaus
530be38b84 JS: MapGet 2021-03-23 14:53:14 +00:00
Asger Feldthaus
4a45731c85 JS: SetMapForEach 2021-03-23 14:53:14 +00:00
Asger Feldthaus
c9c99464cf JS: ForOfStep (unify with Arrays version) 2021-03-23 14:53:13 +00:00
Asger Feldthaus
1a5eede39f JS: SetConstructor 2021-03-23 14:53:13 +00:00
Asger Feldthaus
5c9a239776 JS: SetAdd 2021-03-23 14:53:13 +00:00
Asger Feldthaus
98398a9efd JS: add two-prop version of loadStoreStep and infer pseudo properties
Initial step towards migrating CollectionFlowStep to PreCallGraphStep
2021-03-23 14:53:13 +00:00
Asger Feldthaus
67ec5d325c JS: Stop caching AdditionalFlowStep 2021-03-23 14:53:13 +00:00
Asger Feldthaus
adaf3234ec JS: IteratorExceptionStep 2021-03-23 14:53:13 +00:00
Asger Feldthaus
7021be05c5 JS: FlowStepThroughImport 2021-03-23 14:53:13 +00:00
Asger Feldthaus
52279d4bea JS: Rename some test predicates to reflect reality 2021-03-23 14:53:13 +00:00
Asger Feldthaus
fae907df65 JS: Update some uses in tests 2021-03-23 14:53:13 +00:00
Asger Feldthaus
bda074835e JS: Replace uses in ExternalApiUsedWithUntrustedData 2021-03-23 14:53:12 +00:00
Asger Feldthaus
2012e97842 JS: NextJSStaticReactComponentPropsStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
64c7d4e597 JS: NextJSStaticPropsStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
0035defd72 JS: ExceptionStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
5051f10586 JS: ImmutableConstructionStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
3e54136086 JS: Rename EventEmitterFlowStep to reflect reality 2021-03-23 14:53:12 +00:00
Asger Feldthaus
5fe3c1a0a9 JS: EventEmitterTaintStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
3a2f87f0a7 JS: AdditionalTypeTrackingStep -> SharedTypeTrackingStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
b8049f19e2 JS: SharedFlowStepFromPreCallGraph 2021-03-23 14:53:12 +00:00
Asger Feldthaus
8f750d4ad3 JS: UrlSearchParamsTaintStep 2021-03-23 14:53:12 +00:00
Asger Feldthaus
f84a05526d JS: ArraySliceStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
633152940c JS: ArrayConcatStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
17d1e6d614 JS: ArraySpliceStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
5d6c6b4b9b JS: ArrayCreationStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
5bfd2ad07f JS: ArrayPopStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
36a8134490 JS: ArrayIndexingAccess 2021-03-23 14:53:11 +00:00
Asger Feldthaus
b7ae62c3a3 JS: ArrayAppendStep 2021-03-23 14:53:11 +00:00
Asger Feldthaus
1c815f12da JS: ArrayCopySpread 2021-03-23 14:53:11 +00:00
Asger Feldthaus
151420fd0f JS: ArrayFrom 2021-03-23 14:53:11 +00:00
Asger Feldthaus
e42f8439de JS: Replace uses of AdditionalFlowStep with SharedFlowStep 2021-03-23 14:53:10 +00:00
Asger Feldthaus
24539dc0ee JS: Remove unneeded default case in loadStoreStep 2021-03-23 14:53:10 +00:00
CodeQL CI
a43bb1fb6d Merge pull request #5499 from asgerf/js/non-recursive-sourcenode
Approved by erik-krogh
2021-03-23 14:52:10 +00:00
Asger Feldthaus
23d2f11840 JS: Handle inheritance 2021-03-23 14:39:37 +00:00
Chris Smowton
fa90655dd0 Partial revert: only introduce inferred taint edges from callsite-crossing value edges if an original taint edge targets the *start* of the value edge.
Previously we would also take a taint edge targeting a result and a value-preserving edge propagating another argument to the result to imply a taint edge targeting that argument.
2021-03-23 14:35:03 +00:00
Asger Feldthaus
3d94ccf5dd JS: Support accessor-calls in object literals via local flow 2021-03-23 14:16:06 +00:00
Mathias Vorreiter Pedersen
ce638096de Merge pull request #5492 from geoffw0/samateissue
C++: Test taint regression
2021-03-23 14:01:03 +01:00
Rasmus Wriedt Larsen
f2bc413318 Python: remove single commented out line of code 2021-03-23 14:00:38 +01:00
Tom Hvitved
3c26779f40 Merge pull request #5415 from tamasvajk/feature/async-flow
C#: add store step for return statements inside async methods
2021-03-23 13:59:19 +01:00
Rasmus Wriedt Larsen
a4924856a2 Python: Model known form/field subclasses in Django
I used some ad-hoc QL queries to help me find all these extra instances, but not
quite ready to share that code yet :P
2021-03-23 13:57:39 +01:00
Rasmus Wriedt Larsen
8d0f6086af Python: Model django forms/fields
I'm not feeling 100% confident about `SelfRefMixin`, but since I needed it for
both DjangoViewClass and DjangoFormClass, I wanted to avoid copy-pasting this
code around. However, I'm not so opitimistic about it that I want to add it to a
sharable utility qll file :D
2021-03-23 13:57:38 +01:00
Anders Schack-Mulligen
27408fefe2 Merge pull request #5008 from torque59/cwe-346
Java: Queries to detect remote source flow origins to CORS header.
2021-03-23 13:54:00 +01:00
Anders Schack-Mulligen
9a56601dd3 Merge pull request #5164 from luchua-bc/java/insecure-ldap-endpoint
Java: CWE-297 Query to detect insecure LDAP endpoint configuration
2021-03-23 13:53:51 +01:00
Asger Feldthaus
b5be9d07aa JS: Add change note 2021-03-23 12:51:14 +00:00
Geoffrey White
b38a9d51e6 C++: Effect of 'Don't override getParameterSizeIndex in the model for Accept'... 2021-03-23 12:26:59 +00:00
Geoffrey White
13eb9e0833 C++: Fix the test. 2021-03-23 12:26:58 +00:00
Geoffrey White
30e1b88b7f C++: Extend test. 2021-03-23 12:26:58 +00:00
Asger Feldthaus
6c8b4a82c1 JS: Autoformat 2021-03-23 11:55:37 +00:00
Geoffrey White
da08c6e63e Merge pull request #5496 from MathiasVP/accept-model-getParameterSizeIndex-should-be-none
C++: Don't override getParameterSizeIndex in Accept
2021-03-23 11:42:50 +00:00
Asger Feldthaus
98143b071d JS: Autoformat 2021-03-23 11:26:29 +00:00
Anders Schack-Mulligen
1e6b5391d6 Merge pull request #4994 from haby0/main
Java: CWE-652: Improper Neutralization of Data within XQuery Expressions ('XQuery Injection')
2021-03-23 12:05:53 +01:00
Taus
b46a3616d8 Merge pull request #5490 from RasmusWL/private-imports
Python: Make import private for better auto-complete
2021-03-23 12:00:35 +01:00
Mathias Vorreiter Pedersen
585606a933 C++: Respond to review comments. 2021-03-23 11:14:29 +01:00
Mathias Vorreiter Pedersen
0b4650a4c9 C++: Accept test changes. 2021-03-23 10:27:19 +01:00
Tom Hvitved
20aa05b090 C#: Add CIL SSA library 2021-03-23 10:07:36 +01:00
Mathias Vorreiter Pedersen
7d0cfc69f1 C++: Don't override getParameterSizeIndex in the model for Accept. This fixes IR construction of calls to accept. 2021-03-23 09:53:09 +01:00
Mathias Vorreiter Pedersen
0ff7cc845c C++: Add reduced testcase that broke IR construction in #5492. 2021-03-23 09:53:04 +01:00
yoff
921b560e89 Merge pull request #5489 from tausbn/python-make-getacall-return-a-callcfgnode
Python: Make `API::Node::getACall` return a `CallCfgNode`
2021-03-23 09:31:38 +01:00
Rasmus Lerchedahl Petersen
198a4ca79b Python: Add files to experimental 2021-03-22 21:42:06 +01:00
Marcono1234
993999f64f Java: Add test for negative numeric literals 2021-03-22 17:43:34 +01:00
Asger Feldthaus
6b19e69d30 JS: Fix some join orders 2021-03-22 16:17:19 +00:00
Rasmus Wriedt Larsen
1890e63d4c Python: Make import private for better auto-complete
With the non-private imports, auto-completing on `API::` gave ALL results
available from `import python`, as well as the ones specified in the `API`
module.

The non-private import in Attributes.qll did the same for `DataFlow::`.
2021-03-22 16:45:44 +01:00
Taus Brock-Nannestad
4a6589d0ae Python: Make API::Node::getACall return a CallCfgNode
This should eliminate the need for explicit casting to
`CallCfgNode` (which does not appear in our code as far as I can see,
but was observed in an external contribution).
2021-03-22 16:37:24 +01:00
Asger Feldthaus
42e6c7eb2e JS: Remove field from InvokeNode 2021-03-22 15:19:31 +00:00
Asger Feldthaus
c03e9d6c75 JS: Address review comments 2021-03-22 15:19:31 +00:00
Asger Feldthaus
5bfdca895b JS: Remove recursive def of SourceNode::Range 2021-03-22 15:07:38 +00:00
Asger Feldthaus
230b9cf5d3 JS: Avoid recursion in SourceNode::Range 2021-03-22 15:07:38 +00:00
Rasmus Lerchedahl Petersen
c1e3ccfb6c Python, doc: Note ephemeral nature of import nodes 2021-03-22 15:07:51 +01:00
Rasmus Wriedt Larsen
c8a6e837b5 Python: Model QuerySet chains in django 2021-03-22 14:38:54 +01:00
Tamas Vajk
7a0bfd1a69 Skip through any stub preamble 2021-03-22 12:29:13 +01:00
Asger Feldthaus
54a91c73b0 JS: Tweak summarizedHigherOrderCall 2021-03-22 10:56:03 +00:00
Mathias Vorreiter Pedersen
d09458a486 C++: Add another taint tracking copy to identical-files.json 2021-03-22 11:35:59 +01:00
Mathias Vorreiter Pedersen
7ec86b5e7f C++: AdjustedConfiguration should not extend the same dataflow configuration as FromGlobalVarTaintTrackingCfg as this causes multiple configurations to be in scope for dataflow. 2021-03-22 11:35:29 +01:00
haby0
fe046ec71e Merge remote-tracking branch 'upstream/main' into main 2021-03-22 17:25:37 +08:00
Rasmus Wriedt Larsen
3a83ecf067 Python: Add test for taint in django forms/fields 2021-03-22 10:03:32 +01:00
Rasmus Wriedt Larsen
f800bf243f Python: Better text for getSourceType in Django 2021-03-22 01:39:19 +01:00
Rasmus Wriedt Larsen
701b935564 Python: Add example of QuerySet chain (django) 2021-03-22 00:57:43 +01:00
Marcono1234
1534b387bb Java: Improve documentation regarding minus in front of numeric literals 2021-03-22 00:54:14 +01:00
Artem Smotrakov
6c24699403 Cover both javax.el and jakarta.el packages 2021-03-21 21:19:39 +03:00
Artem Smotrakov
adb1ed380a Added tests for Jakarta expression injection 2021-03-21 21:19:39 +03:00
Artem Smotrakov
73e940de74 Added query for Jakarta EL injections
- Added JakartaExpressionInjection.ql
- Added a qhelp file with examples
2021-03-21 21:19:39 +03:00
yo-h
0200aedc2e Java 16: adjust test options 2021-03-21 12:55:25 -04:00
ihsinme
26bac9f425 Apply suggestions from code review
Co-authored-by: Robert Marsh <rdmarsh2@gmail.com>
2021-03-21 15:25:29 +03:00
Asger Feldthaus
a54e810804 JS: Include accessor-calls in CallGraph.ql 2021-03-20 13:59:38 +00:00
Asger Feldthaus
f4a476ea4e JS: Change type ValueNode -> Node 2021-03-20 09:05:04 +00:00
Dilan
1385b22642 pr fixes, typo in qhelp file and helper method for queries 2021-03-19 16:43:29 -07:00
Asger Feldthaus
405c1f3fc7 JS: Update test suite 2021-03-19 16:45:31 +00:00
Asger Feldthaus
fa2ae1420a JS: Rename Diagnostics folder to Summary 2021-03-19 16:43:23 +00:00
Asger Feldthaus
347cbe422d JS: Remove the other summary queries 2021-03-19 16:42:43 +00:00
Asger Feldthaus
0c0556bb38 JS: Update LinesOfCode.ql to match the style from C++ 2021-03-19 16:42:05 +00:00
Asger Feldthaus
6ca425f033 JS: Implement new metric queries for line counting 2021-03-19 16:34:29 +00:00
Asger Feldthaus
ea8c8df653 JS: Fix bad join orders in summarizedHigherOrderCall 2021-03-19 15:30:49 +00:00
Mathias Vorreiter Pedersen
6c1ec6d96b C++: Accept test changes. 2021-03-19 16:09:05 +01:00
Erik Krogh Kristensen
8949b9eb0a add shell interpreted arrays as sinks for js/shell-command-constructed-from-input 2021-03-19 15:59:06 +01:00
Asger Feldthaus
01fd00de56 JS: Fix join order in argumentPassing 2021-03-19 11:49:06 +00:00
Asger F
2f3d516413 JS: Track flow into ES accessors 2021-03-19 11:11:25 +00:00
Asger F
4f46908224 JS: Add test with ES getters/setters 2021-03-19 11:07:15 +00:00
Tamas Vajk
79d6731ed8 C#: Adjust make_stubs.py to use codeql instead of odasa 2021-03-19 11:01:28 +01:00
Erik Krogh Kristensen
36b0ab1de5 Apply suggestions from code review
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-03-19 10:29:38 +01:00
Erik Krogh Kristensen
a28a36ab29 add change-note 2021-03-19 10:10:56 +01:00
Erik Krogh Kristensen
e90fb1a225 reuse classes modelling standard library functions 2021-03-19 10:09:33 +01:00
Erik Krogh Kristensen
d489d63b8e recognize object transformations in module.exports when looking for library inputs 2021-03-18 20:54:33 +01:00
Erik Krogh Kristensen
28ad667578 add model for async-execute 2021-03-18 19:40:46 +01:00
Erik Krogh Kristensen
af5a61782c also look for main modules in a lib folder 2021-03-18 14:51:11 +01:00
Erik Krogh Kristensen
0e98ea0c10 remove spurious import of PackageExports 2021-03-18 14:09:08 +01:00
Erik Krogh Kristensen
67a5831ac0 update expected output 2021-03-18 13:59:44 +01:00
Erik Krogh Kristensen
c0bb169342 recognize a src/index.js file as a main module for a package 2021-03-18 13:41:36 +01:00
Erik Krogh Kristensen
add0c88530 loosen the requirement that the package.json file must be the top-most package.json 2021-03-18 13:39:12 +01:00
Erik Krogh Kristensen
d998d06b94 add link to source in alert-message for js/shell-command-constructed-from-input 2021-03-18 13:37:18 +01:00
Porcuiney Hairs
a88c3682ff remove sanitiserGuards 2021-03-18 16:12:00 +05:30
Porcuiney Hairs
84c9137152 Include suggestions from review 2021-03-18 16:12:00 +05:30
porcupineyhairs
f27d2bdf6d Update java/ql/src/experimental/semmle/code/java/Logging.qll
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-03-18 16:12:00 +05:30
Porcuiney Hairs
d0c82d3756 Add flogger and android logging support 2021-03-18 16:12:00 +05:30
Porcuiney Hairs
17d7ba8049 Add Log Injection Vulnerability 2021-03-18 16:12:00 +05:30
Rasmus Lerchedahl Petersen
b3ff3f7ee7 PythonÆ adjust test expectations
I suspect it has to do with ParameterNode being a LocalSourceNode,
but I really have no idea...
2021-03-17 15:11:17 +01:00
Rasmus Lerchedahl Petersen
8f467003d2 Python: More review suggestions 2021-03-17 15:11:17 +01:00
yoff
63b732ce1f Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2021-03-17 15:11:17 +01:00
Rasmus Lerchedahl Petersen
4d856d4461 Python: Add small api enhancements
determined useful during documentation work.
2021-03-17 15:11:17 +01:00
Mathias Vorreiter Pedersen
3914a93504 C++: Remove commonTaintStep from DefaultTaintTracking. 2021-03-17 11:56:59 +01:00
haby0
c516d69b98 Merge remote-tracking branch 'upstream/main' into main 2021-03-17 16:42:48 +08:00
Tamas Vajk
0b1705f302 C#: Adjust Callable::canReturn to handle Task-like async return types 2021-03-17 09:25:57 +01:00
haby0
15206fd2ce JsonpInjection.ql autoformatted 2021-03-17 15:52:05 +08:00
haby0
98204a15a6 Fix the problem 2021-03-17 15:28:04 +08:00
Mathias Vorreiter Pedersen
43fbcc1c8a C++: Convert all the dataflow configurations to taint configurations. 2021-03-16 22:36:17 +01:00
Mathias Vorreiter Pedersen
dd6b27df24 C++: Fix test annotation. 2021-03-16 22:35:47 +01:00
Tamas Vajk
cd820917bc Remove duplicate yield return entries from global dataflow test 2021-03-16 21:28:58 +01:00
Tamas Vajk
2541e9cb6a C#: Handle async data flow in expression bodied callables 2021-03-16 16:32:47 +01:00
Tamas Vajk
048c72a0f2 C#: Remove YieldReturnKind 2021-03-16 16:20:04 +01:00
Tamas Vajk
aa2abf76ba Make ReturnNodes disjoint (normal, yield, async) 2021-03-16 16:17:27 +01:00
Tamas Vajk
732ef92830 C#: add store step for return statements inside async methods 2021-03-16 15:18:00 +01:00
Tamas Vajk
c684b74b3d C#: Add async dataflow tests 2021-03-16 14:46:16 +01:00
Mathias Vorreiter Pedersen
0ffb80e3b1 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-15 09:42:32 +01:00
luchua-bc
1a2e341b7c Refactor the business logic of the query into a separate predicate 2021-03-12 12:19:37 +00:00
luchua-bc
c8b1bc3a89 Enhance the query 2021-03-11 21:41:34 +00:00
Mathias Vorreiter Pedersen
5667901a2a C++: Accept test changes after merge from main (which changed the path explanations). 2021-03-11 21:16:57 +01:00
luchua-bc
0a35feef76 Exclude CSRF cookies to reduce FPs 2021-03-11 17:28:07 +00:00
luchua-bc
57953c523c Update qldoc 2021-03-11 17:16:36 +00:00
Mathias Vorreiter Pedersen
a2d75c4fed Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-11 18:06:37 +01:00
luchua-bc
eeac7e322a Query to detect insecure configuration of Spring Boot Actuator 2021-03-11 13:46:32 +00:00
Artem Smotrakov
4b7c57c077 Added a comment for getBeanIdentifier()
Co-authored-by: Chris Smowton <smowton@github.com>
2021-03-11 11:52:07 +01:00
Artem Smotrakov
0a5d58ed8a Cover more configurations in UnsafeSpringExporterInConfigurationClass.ql 2021-03-10 21:15:19 +03:00
luchua-bc
a0a1ddee86 Update class name 2021-03-10 17:07:31 +00:00
Mathias Vorreiter Pedersen
bc36e0db43 C++: Accept more test changes. 2021-03-10 16:51:13 +01:00
Mathias Vorreiter Pedersen
cc592b124b Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-10 15:59:48 +01:00
Mathias Vorreiter Pedersen
0b6589c8be C++: Accept test changes. 2021-03-10 15:47:06 +01:00
luchua-bc
f0ddfc9283 Minor qldoc changes 2021-03-10 12:18:55 +00:00
luchua-bc
72f28513eb Move test check to the sink 2021-03-10 12:12:27 +00:00
Anders Schack-Mulligen
4941d9b7bf Java: Add query for CSV framework coverage. 2021-03-10 12:03:44 +01:00
Artem Smotrakov
df60268023 Split qhelp files 2021-03-10 10:49:47 +03:00
luchua-bc
48975fa7d2 Replace sanitizers 2021-03-10 00:17:26 +00:00
Mathias Vorreiter Pedersen
19d08d7b40 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-09 12:35:44 +01:00
Artem Smotrakov
a78f2115f2 Split SpringExporterUnsafeDeserialization.ql 2021-03-09 00:06:38 +03:00
Mathias Vorreiter Pedersen
bb53780ba9 C++: Add flow through unary instructions and pointer/indirection conflation for parameters. These rules are copy/pasted from DefaultTaintTracking. The conflation rules will hopefully be removed as part of #5089. 2021-03-08 09:42:47 +01:00
luchua-bc
0ef3eee4ed Revamp the source and the sink of the query 2021-03-06 22:41:54 +00:00
Artem Smotrakov
891b975899 Use correct file names in SpringExporterUnsafeDeserialization.qhelp 2021-03-06 22:07:43 +01:00
Artem Smotrakov
bda223771b Added another example for SpringExporterUnsafeDeserialization.ql 2021-03-06 22:05:00 +01:00
Artem Smotrakov
82cb4a8d68 Renamed SpringHttpInvokerUnsafeDeserialization.ql 2021-03-06 21:48:35 +01:00
Artem Smotrakov
dcabce679a Cover beans from XML configs in SpringHttpInvokerUnsafeDeserialization.ql 2021-03-06 21:40:35 +01:00
luchua-bc
31eaa80f5b Revamp the source 2021-03-06 00:56:15 +00:00
haby0
ecdadd1826 move the query to experimental folder 2021-03-05 14:38:04 +08:00
luchua-bc
a93aabab40 Add the toString() method 2021-03-05 03:05:49 +00:00
luchua-bc
919c6b4b0a Optimize flow steps 2021-03-05 02:50:54 +00:00
Francis Alexander
abdebc29f9 Move to experimental and review feedback 2021-03-05 07:26:29 +05:30
Mathias Vorreiter Pedersen
23876cb581 C++: Only allow taint to a FieldAddressInstruction if it's a union type. 2021-03-04 16:29:44 +01:00
ihsinme
10cc574289 Add files via upload 2021-03-04 16:15:26 +03:00
ihsinme
01c13c4703 Add files via upload 2021-03-04 16:14:11 +03:00
haby0
c5577cb09a Fix the problem 2021-03-04 19:54:49 +08:00
luchua-bc
1784c202a7 Clean up the query 2021-03-03 17:03:37 +00:00
luchua-bc
502cf38fcc Use concise API 2021-03-03 14:07:43 +00:00
luchua-bc
1b1c3f953b Remove localflow from the source 2021-03-03 13:54:26 +00:00
luchua-bc
b366ffa69e Revamp source of the query 2021-03-03 13:38:18 +00:00
Artem Smotrakov
617ba65ef5 Improved docs for SpringHttpInvokerUnsafeDeserialization.ql 2021-03-02 21:36:14 +01:00
Mathias Vorreiter Pedersen
eb4f1e1ba0 C++: Restore some of the lost test results by doing operand -> instruction taint steps in IR TaintTracking. 2021-03-02 15:45:40 +01:00
Mathias Vorreiter Pedersen
23d3109071 C++: Use taintedWithPath in more tests. This is the predicate that's currently hooked up to the new IR taint tracking library. 2021-03-02 13:40:39 +01:00
Mathias Vorreiter Pedersen
6ba35f4aac C++: Fix function renaming and accept test change. 2021-03-02 11:31:24 +01:00
Mathias Vorreiter Pedersen
9f02c144a8 C++: Remove files that were incorrectly added when resolving merge conflicts. 2021-03-02 11:14:49 +01:00
Mathias Vorreiter Pedersen
ffc6af73b7 C++: Accept test changes. 2021-03-02 11:00:43 +01:00
Mathias Vorreiter Pedersen
748f5344ff Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2021-03-02 10:43:37 +01:00
luchua-bc
95d1994196 Query to check sensitive cookies without the HttpOnly flag set 2021-03-01 22:06:52 +00:00
Artem Smotrakov
15a43ffe36 Simplified returnsRemoteInvocationSerializingExporter() 2021-02-27 13:41:20 +01:00
haby0
f795d5e0d3 update JSONP Injection ql 2021-02-27 16:25:17 +08:00
haby0
0521ef87da Merge remote-tracking branch 'upstream/main' into JsonHijacking 2021-02-25 16:31:14 +08:00
Artem Smotrakov
e02b51f42b Improved SpringHttpInvokerUnsafeDeserialization.qhelp 2021-02-24 22:35:20 +01:00
Artem Smotrakov
aac0c27dcd Added tests for SpringHttpInvokerUnsafeDeserialization.ql 2021-02-24 22:35:20 +01:00
Artem Smotrakov
95284ad71d Added SpringHttpInvokerUnsafeDeserialization.qhelp and example 2021-02-24 22:35:20 +01:00
Artem Smotrakov
476309af6d Added SpringHttpInvokerUnsafeDeserialization.ql 2021-02-24 22:35:20 +01:00
haby0
6fe8bafc7d *)update 2021-02-24 20:59:51 +08:00
haby0
872a000a33 *)update to JSONP injection 2021-02-24 20:36:12 +08:00
Francis Alexander
45bdb22db8 Switch from sanitizer to tainttracking, formatting and qldoc changes 2021-02-21 16:45:48 +05:30
haby0
8119fd2ad1 *)add JsonHijacking ql query 2021-02-18 18:11:10 +08:00
Francis Alexander
2baf2aa5c1 Apply suggestions from code review - improved sanitizer checks.
Co-authored-by: Alvaro Muñoz <pwntester@github.com>
2021-02-17 18:58:32 +05:30
Francis Alexander
40f4e71b86 Merge branch 'main' into cwe-346 2021-02-17 18:55:31 +05:30
Francis Alexander
58971f9f4e Switch qualified name to available CollectionType 2021-02-17 16:01:27 +05:30
Francis Alexander
520ba47293 Sanitizer improvements from code review 2021-02-17 08:35:50 +05:30
luchua-bc
e698ee77f7 Update qldoc and test method 2021-02-16 14:11:39 +00:00
haby0
2c96e6cf96 Merge remote-tracking branch 'upstream/main' into main 2021-02-16 17:54:01 +08:00
luchua-bc
5ce3af0591 Enhance the query and update qldoc 2021-02-15 21:38:54 +00:00
haby0
92c00cb741 Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-02-16 00:09:21 +08:00
haby0
f1e44bce4a Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-02-16 00:07:44 +08:00
luchua-bc
a03e6faf37 Optimize the query and update qldoc 2021-02-15 14:10:17 +00:00
Francis Alexander
409d95c522 Sanitizer checks to decrease FP 2021-02-15 14:01:14 +05:30
luchua-bc
23f620d255 Query to detect insecure LDAP endpoint configuration 2021-02-15 05:31:29 +00:00
luchua-bc
6a6727fc80 Reduce the scope of the query to reduce FPs 2021-02-14 15:01:06 +00:00
haby0
6901cd4899 Merge branch 'main' of https://github.com/haby0/codeql into main 2021-02-12 11:18:33 +08:00
haby0
22e741c7a3 *)add XQExpression.executeCommand(0) sink 2021-02-12 11:17:42 +08:00
haby0
dbb3d458f5 *)add XQExpression.executeCommand(0) sink 2021-02-12 10:47:41 +08:00
haby0
a6a0fa28c4 *)add XQExpression.executeQuery(0) sink 2021-02-11 16:05:48 +08:00
haby0
97690b4eb7 Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.qhelp
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-02-08 19:15:28 +08:00
luchua-bc
ff1ed3a012 Revamp the query to use three configurations to detect password hash without salt 2021-01-29 03:39:02 +00:00
haby0
81c56b9bed Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:47:12 +08:00
haby0
31deca016f Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.ql
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:46:45 +08:00
haby0
ca2e6587fe Update java/ql/src/Security/CWE/CWE-652/XQueryInjection.qhelp
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-27 19:46:15 +08:00
haby0
b5ae417851 *)update CWE-652 qhelp references 2021-01-27 10:19:04 +08:00
haby0
b76854a384 *)add CWE-652 test case 2021-01-27 10:14:33 +08:00
Francis Alexander
19872e9aed More Feedback integration 2021-01-26 17:24:17 +05:30
Francis Alexander
985d3d469a PR feedback integration 2021-01-25 23:26:36 +05:30
haby0
42f55e1ebe Merge pull request #1 from smowton/smowton/admin/rewrite-xquery
Rewrite XQuery injection to use an additional taint step instead of multiple configurations
2021-01-25 19:49:20 +08:00
Chris Smowton
d34233b44f Rewrite XQuery injection to use an additional taint step instead of multiple configurations.
Also remove a needless barrier -- the method in question doesn't conduct taint by default, so excluding particular instances of that call is not necessary.
2021-01-25 11:18:45 +00:00
haby0
16308fe557 Update java/ql/src/Security/CWE/CWE-652/XQueryInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-25 19:16:18 +08:00
haby0
14a23eed4f Update java/ql/src/Security/CWE/CWE-652/XQueryInjectionLib.qll
Co-authored-by: Chris Smowton <smowton@github.com>
2021-01-25 19:15:59 +08:00
Francis Alexander
75b79039a1 Example fixes 2021-01-24 20:46:37 +05:30
Francis Alexander
81e372d078 Formatting changes 2021-01-24 20:44:21 +05:30
Francis Alexander
a64fc2b24e Java: Queries to detect remote source flow to CORS header 2021-01-24 18:58:39 +05:30
haby0
0b326aae20 *)update XQueryInjectionLib.qll 2021-01-23 18:27:38 +08:00
haby0
44d99f8cd4 *)update XQueryInjection.ql 2021-01-23 18:26:58 +08:00
haby0
ec4c155043 *)update XQueryInjection.qhelp 2021-01-23 18:26:15 +08:00
haby0
a56dd60baa *)add CWE-652 XQueryInjection detection 2021-01-21 19:18:10 +08:00
luchua-bc
b9809b071e Update the query to work with wrapper classes 2021-01-18 19:22:34 +00:00
luchua-bc
048167d39a Revamp the query to reduce FPs introduced by wrapper calls 2021-01-18 04:23:30 +00:00
luchua-bc
3af8773dd6 Add more cases 2021-01-15 16:20:31 +00:00
luchua-bc
86c04e6971 Detect the scenario of passwords concatenated with a salt to reduce FPs 2021-01-11 16:59:57 +00:00
luchua-bc
39103af718 Remove additional taint step 2021-01-08 13:02:57 +00:00
luchua-bc
b56fe2b25f Remove specific method name in additional taint step 2021-01-07 16:31:21 +00:00
luchua-bc
19ff00bad4 Enhance the additional step flow and update qldoc 2021-01-07 13:15:30 +00:00
luchua-bc
ce2db21f15 Query to detect hash without salt 2021-01-06 17:30:04 +00:00
Robert Marsh
77729918c1 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Update for submodule pointer
2020-11-18 13:09:02 -08:00
Robert Marsh
5aed82a210 C++: Autoformat more 2020-11-17 13:44:20 -08:00
Robert Marsh
04641a3f2d Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2020-11-17 12:55:12 -08:00
Robert Marsh
c2e44fa180 C++: autoformat 2020-11-17 09:28:39 -08:00
Robert Marsh
db8766ca69 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt 2020-11-16 17:46:20 -08:00
Robert Marsh
525aeb6551 C++: autoformat 2020-11-13 16:14:07 -08:00
Robert Marsh
29eacbd28b Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Update for submodule bump
2020-11-13 12:22:41 -08:00
Robert Marsh
bd00988c37 C++: accept test output for DefaultTaintTracking 2020-11-12 14:38:53 -08:00
Robert Marsh
68040b717e C++: autoformat 2020-11-12 14:32:19 -08:00
Robert Marsh
275d75295c Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Fix test conflict
2020-11-12 13:28:10 -08:00
Robert Marsh
049bff09e6 Merge branch 'main' into rdmarsh/cpp/use-taint-configuration-dtt
Make this branch a valid taget for a submodule bump
2020-11-10 14:25:05 -08:00
Robert Marsh
2a6ba40a93 C++: Accept more test changes 2020-11-10 13:59:35 -08:00
Robert Marsh
04ad94d1cc C++: model taint from pointers to aliased buffers 2020-11-09 13:52:08 -08:00
Robert Marsh
afbeca0d54 C++: Accept test outputs 2020-11-09 13:24:31 -08:00
Robert Marsh
95ed5465de C++: improve handling of function arguments in DTT 2020-11-09 13:02:06 -08:00
Robert Marsh
fbe857d1fa C++: require that other operands be predictable
This brings back a constraint that was lost when switching
DefaultTaintTracking to use a TaintTracking::Configuration
2020-11-09 13:00:55 -08:00
Robert Marsh
7d79be71d1 C++: taint tracking conf in DefaultTaintTracking
Switch from using additional flow steps with a DataFlow::Configuration
in DefaultTaintTracking to using a TaintTracking::Configuration. This
makes future improvements to TaintTracking::Configuration reflected in
DefaultTaintTracking without further effort. It also removes the
predictability constraint in DefaultTaintTracking, which increases the
number of results, with both new true positives and new false positives.
Those may need to be addressed on a per-query basis.

There are some additional regressions from losing pointer/object
conflation for arguments. Those can be worked around by adding that
conflation to TaintTracking::Configuration until precise indirect
parameter flow is ready.
2020-11-09 13:00:55 -08:00
dilanbhalla
26b030f8cc fixed pr suggestions 2020-07-07 10:52:26 -07:00
dilanbhalla
dc73fcc4e8 moved to experimental 2020-07-01 09:54:58 -07:00
dilanbhalla
dc58f6fa87 function/class synatax 2020-06-25 11:39:09 -07:00
1065 changed files with 29406 additions and 17962 deletions

30
.github/workflows/close-stale.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Mark stale issues
on:
workflow_dispatch:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
if: github.repository == 'github/codeql'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.'
close-issue-message: 'This issue was closed because it has been inactive for 7 days.'
days-before-stale: 14
days-before-close: 7
only-labels: awaiting-response
# do not mark PRs as stale
days-before-pr-stale: -1
days-before-pr-close: -1
# Uncomment for dry-run
# debug-only: true
# operations-per-run: 1000

View File

@@ -19,13 +19,18 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
security_events: write
pull_requests: read
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: csharp
@@ -34,7 +39,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@main
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -48,4 +53,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@main

View File

@@ -1,29 +0,0 @@
# When a PR is labelled with 'ready-for-docs-review',
# this workflow comments on the PR to notify the GitHub CodeQL docs team.
name: Request docs review
on:
# Runs in the context of the base repo.
# This gives the workflow write access to comment on PRs.
# The workflow should not check out or build the given ref,
# or use untrusted data from the event payload in a command line.
pull_request_target:
types: [labeled]
jobs:
request-docs-review:
name: Request docs review
# Run only on labelled PRs to the main repository.
# Do not run on PRs to forks.
if:
github.event.label.name == 'ready-for-docs-review'
&& github.event.pull_request.draft == false
&& github.event.pull_request.base.repo.full_name == 'github/codeql'
runs-on: ubuntu-latest
steps:
- name: Comment to request docs review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
gh pr comment "$PR_NUMBER" --repo "github/codeql" \
--body "Hello @github/docs-content-codeql - this PR is ready for docs review."

View File

@@ -36,6 +36,7 @@
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
@@ -55,6 +56,10 @@
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
"python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
],
"DataFlow Java/C# Flow Summaries": [
"java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
@@ -376,7 +381,6 @@
],
"DuplicationProblems.inc.qhelp": [
"cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp",
"javascript/ql/src/Metrics/DuplicationProblems.inc.qhelp",
"python/ql/src/Metrics/DuplicationProblems.inc.qhelp"
],
@@ -429,10 +433,11 @@
"SSA C#": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll"
"csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
"csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll"
],
"CryptoAlgorithms Python/JS": [
"javascript/ql/src/semmle/javascript/security/CryptoAlgorithms.qll",
"python/ql/src/semmle/crypto/Crypto.qll"
]
}
}

View File

@@ -5,6 +5,7 @@ using System;
using System.Linq;
using Microsoft.Build.Construction;
using System.Xml;
using System.IO;
namespace Semmle.Autobuild.Cpp.Tests
{
@@ -43,6 +44,8 @@ namespace Semmle.Autobuild.Cpp.Tests
public IDictionary<string, int> RunProcess = new Dictionary<string, int>();
public IDictionary<string, string> RunProcessOut = new Dictionary<string, string>();
public IDictionary<string, string> RunProcessWorkingDirectory = new Dictionary<string, string>();
public HashSet<string> CreateDirectories { get; } = new HashSet<string>();
public HashSet<(string, string)> DownloadFiles { get; } = new HashSet<(string, string)>();
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut)
{
@@ -135,6 +138,14 @@ namespace Semmle.Autobuild.Cpp.Tests
string IBuildActions.GetFullPath(string path) => path;
string? IBuildActions.GetFileName(string? path) => Path.GetFileName(path?.Replace('\\', '/'));
public string? GetDirectoryName(string? path)
{
var dir = Path.GetDirectoryName(path?.Replace('\\', '/'));
return dir is null ? path : path?.Substring(0, dir.Length);
}
void IBuildActions.WriteAllText(string filename, string contents)
{
}
@@ -153,6 +164,18 @@ namespace Semmle.Autobuild.Cpp.Tests
s = s.Replace($"%{kvp.Key}%", kvp.Value);
return s;
}
public void CreateDirectory(string path)
{
if (!CreateDirectories.Contains(path))
throw new ArgumentException($"Missing CreateDirectory, {path}");
}
public void DownloadFile(string address, string fileName)
{
if (!DownloadFiles.Contains((address, fileName)))
throw new ArgumentException($"Missing DownloadFile, {address}, {fileName}");
}
}
/// <summary>
@@ -213,6 +236,7 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_SOURCE_ARCHIVE_DIR"] = "";
Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}";
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
Actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = "win64";
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java";
Actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools";
@@ -273,7 +297,8 @@ namespace Semmle.Autobuild.Cpp.Tests
[Fact]
public void TestCppAutobuilderSuccess()
{
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test.sln"] = 1;
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
@@ -286,11 +311,13 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true;
Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.slx";
Actions.EnumerateDirectories[@"C:\Project"] = "";
Actions.CreateDirectories.Add(@"C:\Project\.nuget");
Actions.DownloadFiles.Add(("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", @"C:\Project\.nuget\nuget.exe"));
var autobuilder = CreateAutoBuilder(true);
var solution = new TestSolution(@"C:\Project\test.sln");
autobuilder.ProjectsOrSolutionsToBuild.Add(solution);
TestAutobuilderScript(autobuilder, 0, 2);
TestAutobuilderScript(autobuilder, 0, 3);
}
}
}

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Assignment where comparison was intended' (cpp/assign-where-compare-meant) query has been improved to flag fewer benign assignments in conditionals.

View File

@@ -0,0 +1,2 @@
lgtm
* The queries cpp/tainted-arithmetic, cpp/uncontrolled-arithmetic, and cpp/arithmetic-with-extreme-values have been improved to produce fewer false positives.

View File

@@ -0,0 +1,2 @@
codescanning
* The 'Pointer to stack object used as return value' (cpp/return-stack-allocated-object) query has been deprecated, and any uses should be replaced with `Returning stack-allocated memory` (cpp/return-stack-allocated-memory).

View File

@@ -7,6 +7,8 @@
* @tags reliability
* security
* external/cwe/cwe-562
* @deprecated This query is not suitable for production use and has been deprecated. Use
* cpp/return-stack-allocated-memory instead.
*/
import semmle.code.cpp.pointsto.PointsTo

View File

@@ -54,7 +54,7 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment {
override predicate isWhitelisted() {
this.getConversion().(ParenthesisExpr).isParenthesised()
or
// whitelist this assignment if all comparison operations in the expression that this
// Allow this assignment if all comparison operations in the expression that this
// assignment is part of, are not parenthesized. In that case it seems like programmer
// is fine with unparenthesized comparison operands to binary logical operators, and
// the parenthesis around this assignment was used to call it out as an assignment.
@@ -62,6 +62,21 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment {
forex(ComparisonOperation op | op = getComparisonOperand*(this.getParent+()) |
not op.isParenthesised()
)
or
// Match a pattern like:
// ```
// if((a = b) && use_value(a)) { ... }
// ```
// where the assignment is meant to update the value of `a` before it's used in some other boolean
// subexpression that is guarenteed to be evaluate _after_ the assignment.
this.isParenthesised() and
exists(LogicalAndExpr parent, Variable var, VariableAccess access |
var = this.getLValue().(VariableAccess).getTarget() and
access = var.getAnAccess() and
not access.isUsedAsLValue() and
parent.getRightOperand() = access.getParent*() and
parent.getLeftOperand() = this.getParent*()
)
}
}

View File

@@ -13,6 +13,7 @@
import cpp
import semmle.code.cpp.dataflow.EscapesTree
import semmle.code.cpp.models.interfaces.PointerWrapper
import semmle.code.cpp.dataflow.DataFlow
/**
@@ -39,6 +40,10 @@ predicate hasNontrivialConversion(Expr e) {
e instanceof ParenthesisExpr
)
or
// A smart pointer can be stack-allocated while the data it points to is heap-allocated.
// So we exclude such "conversions" from this predicate.
e = any(PointerWrapper wrapper).getAnUnwrapperFunction().getACallToThisFunction()
or
hasNontrivialConversion(e.getConversion())
}

View File

@@ -5,7 +5,6 @@
* @kind treemap
* @treemap.warnOn highValues
* @metricType externalDependency
* @precision medium
* @id cpp/external-dependencies
* @tags modularity
*/

View File

@@ -7,7 +7,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision very-high
* @id cpp/lines-of-code-in-files
* @tags maintainability
* complexity

View File

@@ -5,7 +5,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision high
* @id cpp/lines-of-commented-out-code-in-files
* @tags documentation
*/

View File

@@ -7,7 +7,6 @@
* @treemap.warnOn lowValues
* @metricType file
* @metricAggregate avg sum max
* @precision very-high
* @id cpp/lines-of-comments-in-files
* @tags maintainability
* documentation

View File

@@ -8,7 +8,6 @@
* @treemap.warnOn highValues
* @metricType file
* @metricAggregate avg sum max
* @precision high
* @id cpp/duplicated-lines-in-files
* @tags testability
* modularity

View File

@@ -5,7 +5,6 @@
* @treemap.warnOn lowValues
* @metricType file
* @metricAggregate avg sum max
* @precision medium
* @id cpp/tests-in-files
* @tags maintainability
*/

View File

@@ -93,7 +93,7 @@ class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2::Confi
bindingset[s]
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) {
s.regexpMatch("\"([^\"])*\"(\\s|.)*") // The first element (path) is quoted
s.regexpMatch("\"([^\"])*\"[\\s\\S]*") // The first element (path) is quoted
or
s.regexpMatch("[^\\s]+") // There are no spaces in the string
}

View File

@@ -72,9 +72,9 @@ class WrongCheckErrorOperatorNew extends FunctionCall {
}
/**
* Holds if `(std::nothrow)` exists in call `operator new`.
* Holds if `(std::nothrow)` or `(std::noexcept)` exists in call `operator new`.
*/
predicate isExistsNothrow() { this.getAChild().toString() = "nothrow" }
predicate isExistsNothrow() { getTarget().isNoExcept() or getTarget().isNoThrow() }
}
from WrongCheckErrorOperatorNew op

View File

@@ -0,0 +1,17 @@
while(flagsLoop)
{
...
if(flagsIf) break;
...
}while(flagsLoop); // BAD: when exiting through `break`, it is possible to get into an eternal loop.
...
while(flagsLoop)
{
...
if(flagsIf) break;
...
} // GOOD: correct cycle
...
if(intA+intB) return 1; // BAD: possibly no comparison
...
if(intA+intB>intC) return 1; // GOOD: correct comparison

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>In some situations, after code refactoring, parts of the old constructs may remain. They are correctly accepted by the compiler, but can critically affect program execution. For example, if you switch from `do {...} while ();` to `while () {...}` forgetting to remove the old construct completely, you get `while(){...}while();` which may be vulnerable. These code snippets look suspicious and require the developer's attention.</p>
</overview>
<recommendation>
<p>We recommend that you use more explicit code transformations.</p>
</recommendation>
<example>
<p>The following example demonstrates the erroneous and corrected sections of the code.</p>
<sample src="InsufficientControlFlowManagementAfterRefactoringTheCode.c" />
</example>
<references>
<li>
CWE Common Weakness Enumeration:
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,119 @@
/**
* @name Errors After Refactoring
* @description --In some situations, after code refactoring, parts of the old constructs may remain.
* --They are correctly accepted by the compiler, but can critically affect program execution.
* --For example, if you switch from `do {...} while ();` to `while () {...}` with errors, you run the risk of running out of resources.
* --These code snippets look suspicious and require the developer's attention.
* @kind problem
* @id cpp/errors-after-refactoring
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-691
*/
import cpp
import semmle.code.cpp.valuenumbering.HashCons
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* Using `while` directly after the body of another` while`.
*/
class UsingWhileAfterWhile extends WhileStmt {
/**
* Using a loop call after another loop has finished running can result in an eternal loop.
* For example, perhaps as a result of refactoring, the `do ... while ()` loop was incorrectly corrected.
* Even in the case of deliberate use of such an expression, it is better to correct it.
*/
UsingWhileAfterWhile() {
exists(WhileStmt wh1 |
wh1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
this and
hashCons(wh1.getCondition()) = hashCons(this.getCondition()) and
this.getStmt() instanceof EmptyStmt
)
or
exists(ForStmt fr1 |
fr1.getStmt().getAChild*().(BreakStmt).(ControlFlowNode).getASuccessor().getASuccessor() =
this and
hashCons(fr1.getCondition()) = hashCons(this.getCondition()) and
this.getStmt() instanceof EmptyStmt
)
}
}
/**
* Using arithmetic in a condition.
*/
class UsingArithmeticInComparison extends BinaryArithmeticOperation {
/**
* Using arithmetic operations in a comparison operation can be dangerous.
* For example, part of the comparison may have been lost as a result of refactoring.
* Even if you deliberately use such an expression, it is better to add an explicit comparison.
*/
UsingArithmeticInComparison() {
this.getParent*() instanceof IfStmt and
not this.getAChild*().isConstant() and
not this.getParent*() instanceof Call and
not this.getParent*() instanceof AssignExpr and
not this.getParent*() instanceof ArrayExpr and
not this.getParent*() instanceof RemExpr and
not this.getParent*() instanceof AssignBitwiseOperation and
not this.getParent*() instanceof AssignArithmeticOperation and
not this.getParent*() instanceof EqualityOperation and
not this.getParent*() instanceof RelationalOperation
}
/** Holds when the expression is inside the loop body. */
predicate insideTheLoop() { exists(Loop lp | lp.getStmt().getAChild*() = this.getParent*()) }
/** Holds when the expression is used in binary operations. */
predicate workingWithValue() {
this.getParent*() instanceof BinaryBitwiseOperation or
this.getParent*() instanceof NotExpr
}
/** Holds when the expression contains a pointer. */
predicate workingWithPointer() {
this.getAChild*().getFullyConverted().getType() instanceof DerivedType
}
/** Holds when a null comparison expression exists. */
predicate compareWithZero() {
exists(Expr exp |
exp instanceof ComparisonOperation and
(
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
hashCons(exp.getAChild*()) = hashCons(this)
) and
(
exp.(ComparisonOperation).getLeftOperand().getValue() = "0" or
exp.(ComparisonOperation).getRightOperand().getValue() = "0"
)
)
}
/** Holds when a comparison expression exists. */
predicate compareWithOutZero() {
exists(Expr exp |
exp instanceof ComparisonOperation and
(
globalValueNumber(exp.getAChild*()) = globalValueNumber(this) or
hashCons(exp.getAChild*()) = hashCons(this)
)
)
}
}
from Expr exp
where
exp instanceof UsingArithmeticInComparison and
not exp.(UsingArithmeticInComparison).workingWithValue() and
not exp.(UsingArithmeticInComparison).workingWithPointer() and
not exp.(UsingArithmeticInComparison).insideTheLoop() and
not exp.(UsingArithmeticInComparison).compareWithZero() and
exp.(UsingArithmeticInComparison).compareWithOutZero()
or
exists(WhileStmt wst | wst instanceof UsingWhileAfterWhile and exp = wst.getCondition())
select exp, "this expression needs your attention"

View File

@@ -0,0 +1,4 @@
if(len>0 & memset(buf,0,len)) return 1; // BAD: `memset` will be called regardless of the value of the `len` variable. moreover, one cannot be sure that it will happen after verification
...
if(len>0 && memset(buf,0,len)) return 1; // GOOD: `memset` will be called after the `len` variable has been checked.
...

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Using bitwise operations can be a mistake in some situations. For example, if parameters are evaluated in an expression and the function should be called only upon certain test results. These bitwise operations look suspicious and require developer attention.</p>
</overview>
<recommendation>
<p>We recommend that you evaluate the correctness of using the specified bit operations.</p>
</recommendation>
<example>
<p>The following example demonstrates the erroneous and fixed use of bit and logical operations.</p>
<sample src="InsufficientControlFlowManagementWhenUsingBitOperations.c" />
</example>
<references>
<li>
CWE Common Weakness Enumeration:
<a href="https://cwe.mitre.org/data/definitions/691.html"> CWE-691: Insufficient Control Flow Management</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,78 @@
/**
* @name Errors When Using Bit Operations
* @description Unlike the binary operations `||` and `&&`, there is no sequence point after evaluating an
* operand of a bitwise operation like `|` or `&`. If left-to-right evaluation is expected this may be confusing.
* @kind problem
* @id cpp/errors-when-using-bit-operations
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-691
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* Dangerous uses of bit operations.
* For example: `if(intA>0 & intA<10 & charBuf&myFunc(charBuf[intA]))`.
* In this case, the function will be called in any case, and even the sequence of the call is not guaranteed.
*/
class DangerousBitOperations extends BinaryBitwiseOperation {
FunctionCall bfc;
/**
* The assignment indicates the conscious use of the bit operator.
* Use in comparison, conversion, or return value indicates conscious use of the bit operator.
* The use of shifts and bitwise operations on any element of an expression indicates a conscious use of the bitwise operator.
*/
DangerousBitOperations() {
bfc = this.getRightOperand() and
not this.getParent*() instanceof Assignment and
not this.getParent*() instanceof Initializer and
not this.getParent*() instanceof ReturnStmt and
not this.getParent*() instanceof EqualityOperation and
not this.getParent*() instanceof UnaryLogicalOperation and
not this.getParent*() instanceof BinaryLogicalOperation and
not this.getAChild*() instanceof BitwiseXorExpr and
not this.getAChild*() instanceof LShiftExpr and
not this.getAChild*() instanceof RShiftExpr
}
/** Holds when part of a bit expression is used in a logical operation. */
predicate useInLogicalOperations() {
exists(BinaryLogicalOperation blop, Expr exp |
blop.getAChild*() = exp and
exp.(FunctionCall).getTarget() = bfc.getTarget() and
not exp.getParent() instanceof ComparisonOperation and
not exp.getParent() instanceof BinaryBitwiseOperation
)
}
/** Holds when part of a bit expression is used as part of another supply. For example, as an argument to another function. */
predicate useInOtherCalls() {
bfc.hasQualifier() or
bfc.getTarget() instanceof Operator or
exists(FunctionCall fc | fc.getAnArgument().getAChild*() = this) or
bfc.getTarget() instanceof BuiltInFunction
}
/** Holds when the bit expression contains both arguments and a function call. */
predicate dangerousArgumentChecking() {
not this.getLeftOperand() instanceof Call and
globalValueNumber(this.getLeftOperand().getAChild*()) = globalValueNumber(bfc.getAnArgument())
}
/** Holds when function calls are present in the bit expression. */
predicate functionCallsInBitsExpression() {
this.getLeftOperand().getAChild*() instanceof FunctionCall
}
}
from DangerousBitOperations dbo
where
not dbo.useInOtherCalls() and
dbo.useInLogicalOperations() and
(not dbo.functionCallsInBitsExpression() or dbo.dangerousArgumentChecking())
select dbo, "This bitwise operation appears in a context where a Boolean operation is expected."

View File

@@ -0,0 +1,11 @@
if(len=funcReadData()==0) return 1; // BAD: variable `len` will not equal the value returned by function `funcReadData()`
...
if((len=funcReadData())==0) return 1; // GOOD: variable `len` equal the value returned by function `funcReadData()`
...
bool a=true;
a++;// BAD: variable `a` does not change its meaning
bool b;
b=-a;// BAD: variable `b` equal `true`
...
a=false;// GOOD: variable `a` equal `false`
b=!a;// GOOD: variable `b` equal `false`

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Finding places of confusing use of boolean type. For example, a unary minus does not work before a boolean type and an increment always gives true.</p>
</overview>
<recommendation>
<p>we recommend making the code simpler.</p>
</recommendation>
<example>
<p>The following example demonstrates erroneous and fixed methods for using a boolean data type.</p>
<sample src="OperatorPrecedenceLogicErrorWhenUseBoolType.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP00-C.+Use+parentheses+for+precedence+of+operation">EXP00-C. Use parentheses for precedence of operation</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,54 @@
/**
* @name Operator Precedence Logic Error When Use Bool Type
* @description --Finding places of confusing use of boolean type.
* --For example, a unary minus does not work before a boolean type and an increment always gives true.
* @kind problem
* @id cpp/operator-precedence-logic-error-when-use-bool-type
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-783
* external/cwe/cwe-480
*/
import cpp
import semmle.code.cpp.valuenumbering.HashCons
/** Holds if `exp` increments a boolean value. */
predicate incrementBoolType(IncrementOperation exp) {
exp.getOperand().getType() instanceof BoolType
}
/** Holds if `exp` applies the unary minus operator to a boolean type. */
predicate revertSignBoolType(UnaryMinusExpr exp) {
exp.getAnOperand().getType() instanceof BoolType and
exp.getFullyConverted().getType() instanceof BoolType
}
/** Holds, if this is an expression, uses comparison and assignment outside of execution precedence. */
predicate assignBoolType(Expr exp) {
exists(ComparisonOperation co |
exp.(AssignExpr).getRValue() = co and
exp.isCondition() and
not co.isParenthesised() and
not exp.(AssignExpr).getLValue().getType() instanceof BoolType and
not exists(Expr exbl |
hashCons(exbl.(AssignExpr).getLValue()) = hashCons(exp.(AssignExpr).getLValue()) and
not exbl.isCondition() and
exbl.(AssignExpr).getRValue().getType() instanceof BoolType and
exbl.(AssignExpr).getLValue().getType() = exp.(AssignExpr).getLValue().getType()
) and
co.getLeftOperand() instanceof FunctionCall and
not co.getRightOperand().getType() instanceof BoolType and
not co.getRightOperand().getValue() = "0" and
not co.getRightOperand().getValue() = "1"
)
}
from Expr exp
where
incrementBoolType(exp) or
revertSignBoolType(exp) or
assignBoolType(exp)
select exp, "this expression needs attention"

View File

@@ -3,7 +3,7 @@
* @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior.
* If terminal zero is present, then the specified expression is meaningless.
* @kind problem
* @id cpp/access-memory-location-after-end-buffer
* @id cpp/access-memory-location-after-end-buffer-strlen
* @problem.severity warning
* @precision medium
* @tags correctness

View File

@@ -2,7 +2,7 @@
* @name Access Of Memory Location After The End Of A Buffer Using Strncat
* @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer.
* @kind problem
* @id cpp/access-memory-location-after-end-buffer
* @id cpp/access-memory-location-after-end-buffer-strncat
* @problem.severity warning
* @precision medium
* @tags correctness
@@ -11,54 +11,32 @@
*/
import cpp
import semmle.code.cpp.models.implementations.Strcat
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
* A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`.
* Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and
* destination arguments, respectively.
*/
class WrongCallStrncat extends FunctionCall {
Expr leftsomeExpr;
WrongCallStrncat() {
this.getTarget().hasGlobalOrStdName("strncat") and
// the expression of the first argument in `strncat` and `strnlen` is identical
globalValueNumber(this.getArgument(0)) =
globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and
// using a string constant often speaks of manually calculating the length of the required buffer.
(
not this.getArgument(1) instanceof StringLiteral and
not this.getArgument(1) instanceof CharLiteral
) and
// for use in predicates
leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand()
}
/**
* Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`.
*/
predicate isExpressionEqualSizeof() {
// the left side of the expression `someExpr` is `sizeof(buf)`.
globalValueNumber(this.getArgument(0)) =
globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand())
or
// value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array.
leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize()
}
/**
* Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer.
*/
predicate isVariableEqualValueSizegBuffer() {
// the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`.
exists(AllocationExpr alc |
leftsomeExpr.(VariableAccess).getTarget() =
alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget()
)
}
predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
exists(StrcatFunction strcat |
strcat = call.getTarget() and
sizeArg = call.getArgument(strcat.getParamSize()) and
destArg = call.getArgument(strcat.getParamDest())
)
}
from WrongCallStrncat sc
from FunctionCall call, Expr sizeArg, Expr destArg, SubExpr sub, int n
where
sc.isExpressionEqualSizeof() or
sc.isVariableEqualValueSizegBuffer()
select sc, "if the used buffer is full, writing out of the buffer is possible"
interestringCallWithArgs(call, sizeArg, destArg) and
// The destination buffer is an array of size n
destArg.getUnspecifiedType().(ArrayType).getSize() = n and
// The size argument is equivalent to a subtraction
globalValueNumber(sizeArg).getAnExpr() = sub and
// ... where the left side of the subtraction is the constant n
globalValueNumber(sub.getLeftOperand()).getAnExpr().getValue().toInt() = n and
// ... and the right side of the subtraction is a call to `strlen` where the argument is the
// destination buffer.
globalValueNumber(sub.getRightOperand()).getAnExpr().(StrlenCall).getStringExpr() =
globalValueNumber(destArg).getAnExpr()
select call, "Possible out-of-bounds write due to incorrect size argument."

View File

@@ -1,12 +0,0 @@
/**
* @name Defect filter
* @description Only include results in large files (200) lines of code, and change the message.
* @tags filter
*/
import cpp
import external.DefectFilter
from DefectResult res
where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200
select res, "Large files: " + res.getMessage()

View File

@@ -1,18 +0,0 @@
/**
* @name Defect from external data
* @description Insert description here...
* @kind problem
* @problem.severity warning
* @tags external-data
*/
import cpp
import external.ExternalArtifact
from ExternalData d, File u
where
d.getQueryPath() = "external-data.ql" and
u.getShortName() = d.getField(0)
select u,
d.getField(5) + ", " + d.getFieldAsDate(1) + ", " + d.getField(2) + ", " + d.getFieldAsFloat(3) +
", " + d.getFieldAsInt(4) + ": " + d.getNumFields()

View File

@@ -1,12 +0,0 @@
/**
* @name Metric filter
* @description Only include results in large files (200) lines of code.
* @tags filter
*/
import cpp
import external.MetricFilter
from MetricResult res
where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200
select res, res.getValue()

View File

@@ -1,16 +0,0 @@
/**
* @name Filter: exclude results from files that are autogenerated
* @description Use this filter to return results only if they are
* located in files that are maintained manually.
* @kind problem
* @id cpp/autogenerated-filter
* @tags filter
*/
import cpp
import semmle.code.cpp.AutogeneratedFile
import external.DefectFilter
from DefectResult res
where not res.getFile() instanceof AutogeneratedFile
select res, res.getMessage()

View File

@@ -1,16 +0,0 @@
/**
* @name Metric filter: exclude results from files that are autogenerated
* @description Use this filter to return results only if they are
* located in files that are maintained manually.
* @kind treemap
* @id cpp/autogenerated-for-metric-filter
* @tags filter
*/
import cpp
import semmle.code.cpp.AutogeneratedFile
import external.MetricFilter
from MetricResult res
where not res.getFile() instanceof AutogeneratedFile
select res, res.getValue()

View File

@@ -1,16 +0,0 @@
/**
* @name Filter: exclude results from files for which we do not have
* source code
* @description Use this filter to return results only if they are
* located in files for which we have source code.
* @kind problem
* @id cpp/from-source-filter
* @tags filter
*/
import cpp
import external.DefectFilter
from DefectResult res
where res.getFile().fromSource()
select res, res.getMessage()

View File

@@ -1,36 +0,0 @@
/**
* @name Filter: exclude results on lines covered by a macro expansion
* @description Use this filter to return results only when there is no
* macro expansion whose location spans all the lines of
* the result's location.
* @kind problem
* @id cpp/macros-filter
* @tags filter
*/
import cpp
import external.DefectFilter
predicate macroLocation(File f, int startLine, int endLine) {
exists(MacroInvocation mi, Location l |
l = mi.getLocation() and
l.getFile() = f and
l.getStartLine() = startLine and
l.getEndLine() = endLine
)
}
predicate macroCovering(DefectResult r) {
exists(File f, int macroStart, int macroEnd, int defectStart, int defectEnd |
f = r.getFile() and
defectStart = r.getStartLine() and
defectEnd = r.getEndLine() and
macroLocation(f, macroStart, macroEnd) and
macroStart <= defectStart and
macroEnd >= defectEnd
)
}
from DefectResult res
where not macroCovering(res)
select res, res.getMessage()

View File

@@ -91,16 +91,17 @@ private predicate exprReleases(Expr e, Expr released, string kind) {
// `e` is a call to a release function and `released` is the released argument
releaseExpr(e, released, kind)
or
exists(Function f, int arg |
exists(int arg, VariableAccess access, Function f |
// `e` is a call to a function that releases one of it's parameters,
// and `released` is the corresponding argument
(
e.(FunctionCall).getTarget() = f or
e.(FunctionCall).getTarget().(MemberFunction).getAnOverridingFunction+() = f
) and
access = f.getParameter(arg).getAnAccess() and
e.(FunctionCall).getArgument(arg) = released and
exprReleases(_,
exprOrDereference(globalValueNumber(f.getParameter(arg).getAnAccess()).getAnExpr()), kind)
pragma[only_bind_into](exprOrDereference(globalValueNumber(access).getAnExpr())), kind)
)
or
exists(Function f, ThisExpr innerThis |
@@ -112,7 +113,7 @@ private predicate exprReleases(Expr e, Expr released, string kind) {
) and
e.(FunctionCall).getQualifier() = exprOrDereference(released) and
innerThis.getEnclosingFunction() = f and
exprReleases(_, globalValueNumber(innerThis).getAnExpr(), kind)
exprReleases(_, pragma[only_bind_into](globalValueNumber(innerThis).getAnExpr()), kind)
)
}

View File

@@ -72,6 +72,7 @@ class Location extends @location {
}
/** Holds if `this` comes on a line strictly before `l`. */
pragma[inline]
predicate isBefore(Location l) {
this.getFile() = l.getFile() and this.getEndLine() < l.getStartLine()
}

View File

@@ -1307,7 +1307,8 @@ private predicate conditionJumps(Expr test, boolean truth, Node n2, Pos p2) {
)
}
// Factored out for performance. See QL-796.
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate normalGroupMemberBaseCase(Node memberNode, Pos memberPos, Node atNode) {
memberNode = atNode and
memberPos.isAt() and

View File

@@ -104,9 +104,43 @@ private predicate loopConditionAlwaysUponEntry(ControlFlowNode loop, Expr condit
)
}
/**
* This relation is the same as the `el instanceof Function`, only obfuscated
* so the optimizer will not understand that any `FunctionCall.getTarget()`
* should be in this relation.
*/
pragma[noinline]
private predicate isFunction(Element el) {
el instanceof Function
or
el.(Expr).getParent() = el
}
/**
* Holds if `fc` is a `FunctionCall` with no return value for `getTarget`. This
* can happen in case of rare database inconsistencies.
*/
pragma[noopt]
private predicate callHasNoTarget(@funbindexpr fc) {
exists(Function f |
funbind(fc, f) and
not isFunction(f)
)
}
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate potentiallyReturningFunctionCall_base(FunctionCall fc) {
fc.isVirtual()
or
callHasNoTarget(fc)
}
/** A function call that *may* return; if in doubt, we assume it may. */
private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
potentiallyReturningFunction(fc.getTarget()) or fc.isVirtual()
potentiallyReturningFunctionCall_base(fc)
or
potentiallyReturningFunction(fc.getTarget())
}
/** A function that *may* return; if in doubt, we assume it may. */

View File

@@ -15,6 +15,7 @@
*/
private import cpp
private import semmle.code.cpp.models.interfaces.PointerWrapper
/**
* Holds if `f` is an instantiation of the `std::move` or `std::forward`
@@ -94,6 +95,12 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
lvalueIn.getConversion() = referenceOut.(ReferenceToExpr)
or
exists(PointerWrapper wrapper, Call call | call = referenceOut |
referenceOut.getUnspecifiedType() instanceof ReferenceType and
call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and
lvalueIn = call.getQualifier().getFullyConverted()
)
}
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
@@ -106,6 +113,13 @@ private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
stdAddressOf(call.getTarget()) and
referenceIn = call.getArgument(0).getFullyConverted()
)
or
exists(CopyConstructor copy, Call call | call = pointerOut |
copy.getDeclaringType() instanceof PointerWrapper and
call.getTarget() = copy and
// The 0'th argument is the value being copied.
referenceIn = call.getArgument(0).getFullyConverted()
)
}
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
@@ -190,6 +204,19 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
// See the `lvalueToUpdate` case for an explanation of this conjunct.
call.getType().isDeeplyConstBelow()
)
or
// Pointer wrappers behave as raw pointers for dataflow purposes.
outer = call.getAnArgument().getFullyConverted() and
exists(PointerWrapper wrapper | wrapper = outer.getType().stripTopLevelSpecifiers() |
not wrapper.pointsToConst()
)
or
outer = call.getQualifier().getFullyConverted() and
outer.getUnspecifiedType() instanceof PointerWrapper and
not (
call.getTarget().hasSpecifier("const") and
call.getType().isDeeplyConstBelow()
)
)
or
exists(PointerFieldAccess fa |
@@ -218,7 +245,9 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
not stdIdentityFunction(call.getTarget()) and
not stdAddressOf(call.getTarget()) and
exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() |
not rt.getBaseType().isConst()
not rt.getBaseType().isConst() or
rt.getBaseType().getUnspecifiedType() =
any(PointerWrapper wrapper | not wrapper.pointsToConst())
)
) and
reference = outer

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -46,7 +46,7 @@ class Node extends TNode {
/**
* INTERNAL: Do not use. Alternative name for `getFunction`.
*/
final Function getEnclosingCallable() { result = unique(Function f | f = this.getFunction() | f) }
final Function getEnclosingCallable() { result = this.getFunction() }
/** Gets the type of this node. */
Type getType() { none() } // overridden in subclasses
@@ -324,7 +324,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
* A synthetic data flow node used for flow into a collection when an iterator
* write occurs in a callee.
*/
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
@@ -715,6 +715,7 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
}
private module FieldFlow {
private import DataFlowImplCommon
private import DataFlowImplLocal
private import DataFlowPrivate
@@ -747,7 +748,7 @@ private module FieldFlow {
exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and
// This configuration should not be able to cross function boundaries, but
// we double-check here just to be sure.
node1.getEnclosingCallable() = node2.getEnclosingCallable()
getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2)
}
}

View File

@@ -7,6 +7,7 @@ private import semmle.code.cpp.controlflow.SSA
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
private import semmle.code.cpp.dataflow.internal.AddressFlow
private import semmle.code.cpp.models.implementations.Iterator
private import semmle.code.cpp.models.interfaces.PointerWrapper
/**
* A conceptual variable that is assigned only once, like an SSA variable. This
@@ -158,18 +159,14 @@ private module PartialDefinitions {
Expr innerDefinedExpr;
IteratorPartialDefinition() {
exists(Expr convertedInner |
not this instanceof Conversion and
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
(
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
or
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
collection instanceof IteratorParameter
) and
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
innerDefinedExpr = getInnerDefinedExpr(this, node) and
(
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
or
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
collection instanceof IteratorParameter
) and
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
or
// iterators passed by value without a copy constructor
exists(Call call |
@@ -207,16 +204,18 @@ private module PartialDefinitions {
}
}
private Expr getInnerDefinedExpr(Expr e, ControlFlowNode node) {
not e instanceof Conversion and
exists(Expr convertedInner |
valueToUpdate(convertedInner, e.getFullyConverted(), node) and
result = convertedInner.getUnconverted()
)
}
class VariablePartialDefinition extends PartialDefinition {
Expr innerDefinedExpr;
VariablePartialDefinition() {
not this instanceof Conversion and
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted()
)
}
VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) }
deprecated override predicate partiallyDefines(Variable v) {
innerDefinedExpr = v.getAnAccess()
@@ -296,7 +295,8 @@ module FlowVar_internal {
// treating them as immutable, but for data flow it gives better results in
// practice to make the variable synonymous with its contents.
not v.getUnspecifiedType() instanceof ReferenceType and
not v instanceof IteratorParameter
not v instanceof IteratorParameter and
not v instanceof PointerWrapperParameter
}
/**
@@ -644,10 +644,19 @@ module FlowVar_internal {
predicate parameterIsNonConstReference(Parameter p) {
exists(ReferenceType refType |
refType = p.getUnderlyingType() and
not refType.getBaseType().isConst()
(
not refType.getBaseType().isConst()
or
// A field of a parameter of type `const std::shared_ptr<A>& p` can still be changed even though
// the base type of the reference is `const`.
refType.getBaseType().getUnspecifiedType() =
any(PointerWrapper wrapper | not wrapper.pointsToConst())
)
)
or
p instanceof IteratorParameter
or
p instanceof PointerWrapperParameter
}
/**
@@ -836,6 +845,10 @@ module FlowVar_internal {
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
}
class PointerWrapperParameter extends Parameter {
PointerWrapperParameter() { this.getUnspecifiedType() instanceof PointerWrapper }
}
/**
* Holds if `v` is initialized to have value `assignedExpr`.
*/

View File

@@ -11,6 +11,7 @@
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.Iterator
private import semmle.code.cpp.models.interfaces.PointerWrapper
private module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlowUtil
@@ -141,7 +142,10 @@ private predicate noFlowFromChildExpr(Expr e) {
or
e instanceof LogicalOrExpr
or
e instanceof Call
// Allow taint from `operator*` on smart pointers.
exists(Call call | e = call |
not call.getTarget() = any(PointerWrapper wrapper).getAnUnwrapperFunction()
)
or
e instanceof SizeofOperator
or

View File

@@ -300,17 +300,25 @@ class FunctionCall extends Call, @funbindexpr {
}
}
/** A _user-defined_ unary `operator*` function. */
class OverloadedPointerDereferenceFunction extends Function {
OverloadedPointerDereferenceFunction() {
this.hasName("operator*") and
this.getEffectiveNumberOfParameters() = 1
}
}
/**
* An instance of a _user-defined_ unary `operator*` applied to its argument.
* ```
* T1 operator*(const T2 &);
* T1 a; T2 b;
* a = *b;
* ```
*/
class OverloadedPointerDereferenceExpr extends FunctionCall {
OverloadedPointerDereferenceExpr() {
getTarget().hasName("operator*") and
getTarget().getEffectiveNumberOfParameters() = 1
this.getTarget() instanceof OverloadedPointerDereferenceFunction
}
override string getAPrimaryQlClass() { result = "OverloadedPointerDereferenceExpr" }

View File

@@ -1271,7 +1271,8 @@ private predicate convparents(Expr child, int idx, Element parent) {
)
}
// Pulled out for performance. See QL-796.
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
/**

View File

@@ -2,13 +2,16 @@ import cpp
import semmle.code.cpp.security.Security
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.DataFlow2
private import semmle.code.cpp.ir.dataflow.DataFlow3
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.ir.dataflow.TaintTracking
private import semmle.code.cpp.ir.dataflow.TaintTracking2
private import semmle.code.cpp.ir.dataflow.TaintTracking3
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
/**
* A predictable instruction is one where an external user can predict
@@ -65,23 +68,19 @@ private DataFlow::Node getNodeForExpr(Expr node) {
not argv(node.(VariableAccess).getTarget())
}
private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
private class DefaultTaintTrackingCfg extends TaintTracking::Configuration {
DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
}
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration {
private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration {
ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
@@ -90,20 +89,18 @@ private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration {
sink.asVariable() instanceof GlobalOrNamespaceVariable
}
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
or
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
}
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration {
private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration {
FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" }
override predicate isSource(DataFlow::Node source) {
@@ -114,18 +111,16 @@ private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration {
override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) }
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
// Additional step for flow out of variables. There is no flow _into_
// variables in this configuration, so this step only serves to take flow
// out of a variable that's a source.
readsVariable(n2.asInstruction(), n1.asVariable())
}
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) }
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
private predicate readsVariable(LoadInstruction load, Variable var) {
@@ -202,206 +197,26 @@ private predicate nodeIsBarrierIn(DataFlow::Node node) {
// `getNodeForSource`.
node = DataFlow::definitionByReferenceNodeFromArgument(source)
)
}
cached
private predicate commonTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
operandToInstructionTaintStep(fromNode.asOperand(), toNode.asInstruction())
or
instructionToOperandTaintStep(fromNode.asInstruction(), toNode.asOperand())
}
private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) {
// Propagate flow from the definition of an operand to the operand, even when the overlap is inexact.
// We only do this in certain cases:
// 1. The instruction's result must not be conflated, and
// 2. The instruction's result type is one the types where we expect element-to-object flow. Currently
// this is array types and union types. This matches the other two cases of element-to-object flow in
// `DefaultTaintTracking`.
toOperand.getAnyDef() = fromInstr and
not fromInstr.isResultConflated() and
(
fromInstr.getResultType() instanceof ArrayType or
fromInstr.getResultType() instanceof Union
// don't use dataflow into binary instructions if both operands are unpredictable
exists(BinaryInstruction iTo |
iTo = node.asInstruction() and
not predictableInstruction(iTo.getLeft()) and
not predictableInstruction(iTo.getRight()) and
// propagate taint from either the pointer or the offset, regardless of predictability
not iTo instanceof PointerArithmeticInstruction
)
or
exists(ReadSideEffectInstruction readInstr |
fromInstr = readInstr.getArgumentDef() and
toOperand = readInstr.getSideEffectOperand()
)
}
private predicate operandToInstructionTaintStep(Operand fromOperand, Instruction toInstr) {
// Expressions computed from tainted data are also tainted
exists(CallInstruction call, int argIndex | call = toInstr |
isPureFunction(call.getStaticCallTarget().getName()) and
fromOperand = getACallArgumentOrIndirection(call, argIndex) and
forall(Operand argOperand | argOperand = call.getAnArgumentOperand() |
argOperand = getACallArgumentOrIndirection(call, argIndex) or
predictableInstruction(argOperand.getAnyDef())
) and
// flow through `strlen` tends to cause dubious results, if the length is
// bounded.
not call.getStaticCallTarget().getName() = "strlen"
)
or
// Flow from argument to return value
toInstr =
any(CallInstruction call |
exists(int indexIn |
modelTaintToReturnValue(call.getStaticCallTarget(), indexIn) and
fromOperand = getACallArgumentOrIndirection(call, indexIn) and
not predictableOnlyFlow(call.getStaticCallTarget().getName())
)
)
or
// Flow from input argument to output argument
// TODO: This won't work in practice as long as all aliased memory is tracked
// together in a single virtual variable.
// TODO: Will this work on the test for `TaintedPath.ql`, where the output arg
// is a pointer addition expression?
toInstr =
any(WriteSideEffectInstruction outInstr |
exists(CallInstruction call, int indexIn, int indexOut |
modelTaintToParameter(call.getStaticCallTarget(), indexIn, indexOut) and
fromOperand = getACallArgumentOrIndirection(call, indexIn) and
outInstr.getIndex() = indexOut and
outInstr.getPrimaryInstruction() = call
)
)
or
// Flow through pointer dereference
toInstr.(LoadInstruction).getSourceAddressOperand() = fromOperand
or
// Flow through partial reads of arrays and unions
toInstr.(LoadInstruction).getSourceValueOperand() = fromOperand and
exists(Instruction fromInstr | fromInstr = fromOperand.getAnyDef() |
not fromInstr.isResultConflated() and
(
fromInstr.getResultType() instanceof ArrayType or
fromInstr.getResultType() instanceof Union
)
)
or
// Unary instructions tend to preserve enough information in practice that we
// want taint to flow through.
// The exception is `FieldAddressInstruction`. Together with the rule for
// `LoadInstruction` above and for `ChiInstruction` below, flow through
// `FieldAddressInstruction` could cause flow into one field to come out an
// unrelated field. This would happen across function boundaries, where the IR
// would not be able to match loads to stores.
toInstr.(UnaryInstruction).getUnaryOperand() = fromOperand and
(
not toInstr instanceof FieldAddressInstruction
or
toInstr.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
)
or
// Flow from an element to an array or union that contains it.
toInstr.(ChiInstruction).getPartialOperand() = fromOperand and
not toInstr.isResultConflated() and
exists(Type t | toInstr.getResultLanguageType().hasType(t, false) |
t instanceof Union
or
t instanceof ArrayType
)
or
exists(BinaryInstruction bin |
bin = toInstr and
predictableInstruction(toInstr.getAnOperand().getDef()) and
fromOperand = toInstr.getAnOperand()
)
or
// This is part of the translation of `a[i]`, where we want taint to flow
// from `a`.
toInstr.(PointerAddInstruction).getLeftOperand() = fromOperand
or
// Until we have flow through indirections across calls, we'll take flow out
// of the indirection and into the argument.
// When we get proper flow through indirections across calls, this code can be
// moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class.
exists(ReadSideEffectInstruction read |
read.getSideEffectOperand() = fromOperand and
read.getArgumentDef() = toInstr
)
or
// Until we have from through indirections across calls, we'll take flow out
// of the parameter and into its indirection.
// `InitializeIndirectionInstruction` only has a single operand: the address of the
// value whose indirection we are initializing. When initializing an indirection of a parameter `p`,
// the IR looks like this:
// ```
// m1 = InitializeParameter[p] : &r1
// r2 = Load[p] : r2, m1
// m3 = InitializeIndirection[p] : &r2
// ```
// So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the
// `LoadOperand`'s overlap being exact.
toInstr.(InitializeIndirectionInstruction).getAnOperand() = fromOperand
}
/**
* Returns the index of the side effect instruction corresponding to the specified function output,
* if one exists.
*/
private int getWriteSideEffectIndex(FunctionOutput output) {
output.isParameterDeref(result)
or
output.isQualifierObject() and result = -1
}
/**
* Get an operand that goes into argument `argumentIndex` of `call`. This
* can be either directly or through one pointer indirection.
*/
private Operand getACallArgumentOrIndirection(CallInstruction call, int argumentIndex) {
result = call.getPositionalArgumentOperand(argumentIndex)
or
exists(ReadSideEffectInstruction readSE |
// TODO: why are read side effect operands imprecise?
result = readSE.getSideEffectOperand() and
readSE.getPrimaryInstruction() = call and
readSE.getIndex() = argumentIndex
)
}
private predicate modelTaintToParameter(Function f, int parameterIn, int parameterOut) {
exists(FunctionInput modelIn, FunctionOutput modelOut |
(
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut)
or
f.(TaintFunction).hasTaintFlow(modelIn, modelOut)
) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
parameterOut = getWriteSideEffectIndex(modelOut)
)
}
private predicate modelTaintToReturnValue(Function f, int parameterIn) {
// Taint flow from parameter to return value
exists(FunctionInput modelIn, FunctionOutput modelOut |
f.(TaintFunction).hasTaintFlow(modelIn, modelOut) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
(modelOut.isReturnValue() or modelOut.isReturnValueDeref())
)
or
// Data flow (not taint flow) to where the return value points. For the time
// being we will conflate pointers and objects in taint tracking.
exists(FunctionInput modelIn, FunctionOutput modelOut |
f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) and
(modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and
modelOut.isReturnValueDeref()
)
or
// Taint flow from one argument to another and data flow from an argument to a
// return value. This happens in functions like `strcat` and `memcpy`. We
// could model this flow in two separate steps, but that would add reverse
// flow from the write side-effect to the call instruction, which may not be
// desirable.
exists(int parameterMid, InParameter modelMid, OutReturnValue returnOut |
modelTaintToParameter(f, parameterIn, parameterMid) and
modelMid.isParameter(parameterMid) and
f.(DataFlowFunction).hasDataFlow(modelMid, returnOut)
// don't use dataflow through calls to pure functions if two or more operands
// are unpredictable
exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo |
iTo = node.asInstruction() and
isPureFunction(iTo.getStaticCallTarget().getName()) and
iFrom1 = iTo.getAnArgument() and
iFrom2 = iTo.getAnArgument() and
not predictableInstruction(iFrom1) and
not predictableInstruction(iFrom2) and
iFrom1 != iFrom2
)
}
@@ -440,6 +255,14 @@ private Element adjustedSink(DataFlow::Node sink) {
or
// Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted.
result.(AssignOperation).getAnOperand() = sink.asExpr()
or
result =
sink.asOperand()
.(SideEffectOperand)
.getUse()
.(ReadSideEffectInstruction)
.getArgumentDef()
.getUnconvertedResultExpression()
}
/**
@@ -558,7 +381,7 @@ module TaintedWithPath {
string toString() { result = "TaintTrackingConfiguration" }
}
private class AdjustedConfiguration extends DataFlow3::Configuration {
private class AdjustedConfiguration extends TaintTracking3::Configuration {
AdjustedConfiguration() { this = "AdjustedConfiguration" }
override predicate isSource(DataFlow::Node source) {
@@ -571,21 +394,34 @@ module TaintedWithPath {
exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink)))
}
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
commonTaintStep(n1, n2)
or
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
// Steps into and out of global variables
exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() |
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
or
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
)
or
// Step to return value of a modeled function when an input taints the
// dereference of the return value
exists(CallInstruction call, Function func, FunctionInput modelIn, FunctionOutput modelOut |
n1.asOperand() = callInput(call, modelIn) and
(
func.(TaintFunction).hasTaintFlow(modelIn, modelOut)
or
func.(DataFlowFunction).hasDataFlow(modelIn, modelOut)
) and
call.getStaticCallTarget() = func and
modelOut.isReturnValueDeref() and
call = n2.asInstruction()
)
}
override predicate isBarrier(DataFlow::Node node) {
override predicate isSanitizer(DataFlow::Node node) {
exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e))
}
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
}
/*

View File

@@ -0,0 +1,15 @@
/**
* Provides a `TaintTracking3` module, which is a copy of the `TaintTracking`
* module. Use this class when data-flow configurations or taint-tracking
* configurations must depend on each other. Two classes extending
* `DataFlow::Configuration` should never depend on each other, but one of them
* should instead depend on a `DataFlow2::Configuration`, a
* `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The
* `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and
* `TaintTracking2::Configuration` extends `DataFlow2::Configuration`.
*
* See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation.
*/
module TaintTracking3 {
import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl
}

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -2133,11 +2133,8 @@ private module Stage4 {
bindingset[node, cc, config]
private LocalCc getLocalCc(Node node, Cc cc, Configuration config) {
exists(Cc cc0 |
cc = pragma[only_bind_into](cc0) and
localFlowEntry(node, config) and
result = getLocalCallContext(cc0, getNodeEnclosingCallable(node))
)
localFlowEntry(node, config) and
result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node))
}
private predicate localStep(
@@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and
localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and

View File

@@ -362,15 +362,22 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
/**
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
* For instance, an update to a field of a struct containing only one field. For these cases we
* attach the PostUpdateNode to the store instruction. There's no obvious pre update node for this case
* (as the entire memory is updated), so `getPreUpdateNode` is implemented as `none()`.
* For instance, an update to a field of a struct containing only one field. Even if the store does
* have a chi instruction, a subsequent use of the result of the store may be linked directly to the
* result of the store as an inexact definition if the store totally overlaps the use. For these
* cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node
* for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as
* `none()`.
*/
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
override StoreInstruction instr;
ExplicitSingleFieldStoreQualifierNode() {
not exists(ChiInstruction chi | chi.getPartial() = instr) and
(
instr.getAUse().isDefinitionInexact()
or
not exists(ChiInstruction chi | chi.getPartial() = instr)
) and
// Without this condition any store would create a `PostUpdateNode`.
instr.getDestinationAddress() instanceof FieldAddressInstruction
}

View File

@@ -9,30 +9,18 @@ private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Gets the instruction that goes into `input` for `call`.
*/
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
// A positional argument
Operand callInput(CallInstruction call, FunctionInput input) {
// An argument or qualifier
exists(int index |
result.asInstruction() = call.getPositionalArgument(index) and
input.isParameter(index)
result = call.getArgumentOperand(index) and
input.isParameterOrQualifierAddress(index)
)
or
// A value pointed to by a positional argument
// A value pointed to by an argument or qualifier
exists(ReadSideEffectInstruction read |
result.asOperand() = read.getSideEffectOperand() and
result = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
input.isParameterDeref(read.getIndex())
)
or
// The qualifier pointer
result.asInstruction() = call.getThisArgument() and
input.isQualifierAddress()
or
// The qualifier object
exists(ReadSideEffectInstruction read |
result.asOperand() = read.getSideEffectOperand() and
read.getPrimaryInstruction() = call and
read.getIndex() = -1 and
input.isQualifierObject()
input.isParameterDerefOrQualifierObject(read.getIndex())
)
}
@@ -44,19 +32,11 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) {
result = call and
output.isReturnValue()
or
// The side effect of a call on the value pointed to by a positional argument
// The side effect of a call on the value pointed to by an argument or qualifier
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
output.isParameterDeref(effect.getIndex())
)
or
// The side effect of a call on the qualifier object
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
effect.getIndex() = -1 and
output.isQualifierObject()
output.isParameterDerefOrQualifierObject(effect.getIndex())
)
// TODO: return value dereference
}

View File

@@ -6,34 +6,7 @@ private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
/**
* Gets a short ID for an IR dataflow node.
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
* instruction and a dot (e.g. `m128.left`).
* - For `Variable`s, this is the qualified name of the variable.
*/
private string nodeId(DataFlow::Node node, int order1, int order2) {
exists(Instruction instruction | instruction = node.asInstruction() |
result = instruction.getResultId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
exists(Operand operand, Instruction instruction |
operand = node.asOperand() and
instruction = operand.getUse()
|
result = instruction.getResultId() + "." + operand.getDumpId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
result = "var(" + node.asVariable().getQualifiedName() + ")" and
order1 = 1000000 and
order2 = 0
}
private import PrintIRUtilities
/**
* Gets the local dataflow from other nodes in the same function to this node.

View File

@@ -0,0 +1,33 @@
/**
* Print the dataflow local store steps in IR dumps.
*/
private import cpp
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
// that the cached IR gets the same checksum here as it does in queries that use
// `ValueNumbering` without `DataFlow`.
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import PrintIRUtilities
/**
* Property provider for local IR dataflow store steps.
*/
class LocalFlowPropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instruction, string key) {
exists(DataFlow::Node objectNode, Content content |
key = "content[" + content.toString() + "]" and
instruction = objectNode.asInstruction() and
result =
strictconcat(string element, DataFlow::Node fieldNode |
storeStep(fieldNode, content, objectNode) and
element = nodeId(fieldNode, _, _)
|
element, ", "
)
)
}
}

View File

@@ -0,0 +1,39 @@
/**
* Shared utilities used when printing dataflow annotations in IR dumps.
*/
private import cpp
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
// that the cached IR gets the same checksum here as it does in queries that use
// `ValueNumbering` without `DataFlow`.
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Gets a short ID for an IR dataflow node.
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
* instruction and a dot (e.g. `m128.left`).
* - For `Variable`s, this is the qualified name of the variable.
*/
string nodeId(DataFlow::Node node, int order1, int order2) {
exists(Instruction instruction | instruction = node.asInstruction() |
result = instruction.getResultId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
exists(Operand operand, Instruction instruction |
operand = node.asOperand() and
instruction = operand.getUse()
|
result = instruction.getResultId() + "." + operand.getDumpId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
result = "var(" + node.asVariable().getQualifiedName() + ")" and
order1 = 1000000 and
order2 = 0
}

View File

@@ -21,53 +21,104 @@ predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
*/
cached
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
localInstructionTaintStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction())
or
modeledTaintStep(nodeFrom, nodeTo)
instructionToOperandTaintStep(nodeFrom.asInstruction(), nodeTo.asOperand())
}
private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) {
// Propagate flow from the definition of an operand to the operand, even when the overlap is inexact.
// We only do this in certain cases:
// 1. The instruction's result must not be conflated, and
// 2. The instruction's result type is one the types where we expect element-to-object flow. Currently
// this is array types and union types. This matches the other two cases of element-to-object flow in
// `DefaultTaintTracking`.
toOperand.getAnyDef() = fromInstr and
not fromInstr.isResultConflated() and
(
fromInstr.getResultType() instanceof ArrayType or
fromInstr.getResultType() instanceof Union
)
or
exists(ReadSideEffectInstruction readInstr |
fromInstr = readInstr.getArgumentDef() and
toOperand = readInstr.getSideEffectOperand()
)
or
toOperand.(LoadOperand).getAnyDef() = fromInstr
}
/**
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
* (intra-procedural) step.
*/
private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction nodeTo) {
private predicate operandToInstructionTaintStep(Operand opFrom, Instruction instrTo) {
// Taint can flow through expressions that alter the value but preserve
// more than one bit of it _or_ expressions that follow data through
// pointer indirections.
nodeTo.getAnOperand().getAnyDef() = nodeFrom and
instrTo.getAnOperand() = opFrom and
(
nodeTo instanceof ArithmeticInstruction
instrTo instanceof ArithmeticInstruction
or
nodeTo instanceof BitwiseInstruction
instrTo instanceof BitwiseInstruction
or
nodeTo instanceof PointerArithmeticInstruction
or
nodeTo instanceof FieldAddressInstruction
instrTo instanceof PointerArithmeticInstruction
or
// The `CopyInstruction` case is also present in non-taint data flow, but
// that uses `getDef` rather than `getAnyDef`. For taint, we want flow
// from a definition of `myStruct` to a `myStruct.myField` expression.
nodeTo instanceof CopyInstruction
instrTo instanceof CopyInstruction
)
or
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom
or
// Flow through partial reads of arrays and unions
nodeTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = nodeFrom and
not nodeFrom.isResultConflated() and
// Unary instructions tend to preserve enough information in practice that we
// want taint to flow through.
// The exception is `FieldAddressInstruction`. Together with the rules below for
// `LoadInstruction`s and `ChiInstruction`s, flow through `FieldAddressInstruction`
// could cause flow into one field to come out an unrelated field.
// This would happen across function boundaries, where the IR would not be able to
// match loads to stores.
instrTo.(UnaryInstruction).getUnaryOperand() = opFrom and
(
nodeFrom.getResultType() instanceof ArrayType or
nodeFrom.getResultType() instanceof Union
not instrTo instanceof FieldAddressInstruction
or
instrTo.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
)
or
instrTo.(LoadInstruction).getSourceAddressOperand() = opFrom
or
// Flow from an element to an array or union that contains it.
nodeTo.(ChiInstruction).getPartial() = nodeFrom and
not nodeTo.isResultConflated() and
exists(Type t | nodeTo.getResultLanguageType().hasType(t, false) |
instrTo.(ChiInstruction).getPartialOperand() = opFrom and
not instrTo.isResultConflated() and
exists(Type t | instrTo.getResultLanguageType().hasType(t, false) |
t instanceof Union
or
t instanceof ArrayType
)
or
// Until we have flow through indirections across calls, we'll take flow out
// of the indirection and into the argument.
// When we get proper flow through indirections across calls, this code can be
// moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class.
exists(ReadSideEffectInstruction read |
read.getSideEffectOperand() = opFrom and
read.getArgumentDef() = instrTo
)
or
// Until we have from through indirections across calls, we'll take flow out
// of the parameter and into its indirection.
// `InitializeIndirectionInstruction` only has a single operand: the address of the
// value whose indirection we are initializing. When initializing an indirection of a parameter `p`,
// the IR looks like this:
// ```
// m1 = InitializeParameter[p] : &r1
// r2 = Load[p] : r2, m1
// m3 = InitializeIndirection[p] : &r2
// ```
// So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the
// `LoadOperand`'s overlap being exact.
instrTo.(InitializeIndirectionInstruction).getAnOperand() = opFrom
or
modeledTaintStep(opFrom, instrTo)
}
/**
@@ -110,17 +161,19 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
* modeled function.
*/
predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) {
predicate modeledTaintStep(Operand nodeIn, Instruction nodeOut) {
exists(CallInstruction call, TaintFunction func, FunctionInput modelIn, FunctionOutput modelOut |
(
nodeIn = callInput(call, modelIn)
or
exists(int n |
modelIn.isParameterDeref(n) and
nodeIn = callInput(call, any(InParameter inParam | inParam.getIndex() = n))
modelIn.isParameterDerefOrQualifierObject(n) and
if n = -1
then nodeIn = callInput(call, any(InQualifierObject inQualifier))
else nodeIn = callInput(call, any(InParameter inParam | inParam.getIndex() = n))
)
) and
nodeOut.asInstruction() = callOutput(call, modelOut) and
nodeOut = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.hasTaintFlow(modelIn, modelOut)
)
@@ -135,11 +188,29 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) {
int indexMid, InParameter modelMidIn, OutReturnValue modelOut
|
nodeIn = callInput(call, modelIn) and
nodeOut.asInstruction() = callOutput(call, modelOut) and
nodeOut = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.(TaintFunction).hasTaintFlow(modelIn, modelMidOut) and
func.(DataFlowFunction).hasDataFlow(modelMidIn, modelOut) and
modelMidOut.isParameterDeref(indexMid) and
modelMidIn.isParameter(indexMid)
)
or
// Taint flow from a pointer argument to an output, when the model specifies flow from the deref
// to that output, but the deref is not modeled in the IR for the caller.
exists(
CallInstruction call, ReadSideEffectInstruction read, Function func, FunctionInput modelIn,
FunctionOutput modelOut
|
read.getSideEffectOperand() = callInput(call, modelIn) and
read.getArgumentDef() = nodeIn.getDef() and
not read.getSideEffect().isResultModeled() and
call.getStaticCallTarget() = func and
(
func.(DataFlowFunction).hasDataFlow(modelIn, modelOut)
or
func.(TaintFunction).hasTaintFlow(modelIn, modelOut)
) and
nodeOut = callOutput(call, modelOut)
)
}

View File

@@ -0,0 +1,115 @@
/**
* Provides an implementation of global (interprocedural) taint tracking.
* This file re-exports the local (intraprocedural) taint-tracking analysis
* from `TaintTrackingParameter::Public` and adds a global analysis, mainly
* exposed through the `Configuration` class. For some languages, this file
* exists in several identical copies, allowing queries to use multiple
* `Configuration` classes that depend on each other without introducing
* mutual recursion among those configurations.
*/
import TaintTrackingParameter::Public
private import TaintTrackingParameter::Private
/**
* A configuration of interprocedural taint tracking analysis. This defines
* sources, sinks, and any other configurable aspect of the analysis. Each
* use of the taint tracking library must define its own unique extension of
* this abstract class.
*
* A taint-tracking configuration is a special data flow configuration
* (`DataFlow::Configuration`) that allows for flow through nodes that do not
* necessarily preserve values but are still relevant from a taint tracking
* perspective. (For example, string concatenation, where one of the operands
* is tainted.)
*
* To create a configuration, extend this class with a subclass whose
* characteristic predicate is a unique singleton string. For example, write
*
* ```ql
* class MyAnalysisConfiguration extends TaintTracking::Configuration {
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
* // Override `isSource` and `isSink`.
* // Optionally override `isSanitizer`.
* // Optionally override `isSanitizerIn`.
* // Optionally override `isSanitizerOut`.
* // Optionally override `isSanitizerGuard`.
* // Optionally override `isAdditionalTaintStep`.
* }
* ```
*
* Then, to query whether there is flow between some `source` and `sink`,
* write
*
* ```ql
* exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink))
* ```
*
* Multiple configurations can coexist, but it is unsupported to depend on
* another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the
* overridden predicates that define sources, sinks, or additional steps.
* Instead, the dependency should go to a `TaintTracking2::Configuration` or a
* `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc.
*/
abstract class Configuration extends DataFlow::Configuration {
bindingset[this]
Configuration() { any() }
/**
* Holds if `source` is a relevant taint source.
*
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSource(DataFlow::Node source);
/**
* Holds if `sink` is a relevant taint sink.
*
* The smaller this predicate is, the faster `hasFlow()` will converge.
*/
// overridden to provide taint-tracking specific qldoc
abstract override predicate isSink(DataFlow::Node sink);
/** Holds if the node `node` is a taint sanitizer. */
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
* must be taken into account in the analysis.
*/
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
/**
* Holds if taint may flow from `source` to `sink` for this configuration.
*/
// overridden to provide taint-tracking specific qldoc
override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) {
super.hasFlow(source, sink)
}
}

View File

@@ -0,0 +1,5 @@
import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public
module Private {
import semmle.code.cpp.ir.dataflow.DataFlow3::DataFlow3 as DataFlow
}

View File

@@ -0,0 +1,109 @@
/**
* Predicates to compute the modeled side effects of calls during IR construction.
*
* These are used in `TranslatedElement.qll` to generate the `TTranslatedSideEffect` instances, and
* also in `TranslatedCall.qll` to inject the actual side effect instructions.
*/
private import cpp
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.models.interfaces.SideEffect
/**
* Holds if the specified call has a side effect that does not come from a `SideEffectFunction`
* model.
*/
private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buffer, boolean isWrite) {
not call.getTarget() instanceof SideEffectFunction and
(
exists(MemberFunction mfunc |
// A non-static member function, including a constructor or destructor, may write to `*this`,
// and may also read from `*this` if it is not a constructor.
i = -1 and
mfunc = call.getTarget() and
not mfunc.isStatic() and
buffer = false and
(
isWrite = false and not mfunc instanceof Constructor
or
isWrite = true and not mfunc instanceof ConstMemberFunction
)
)
or
exists(Expr expr |
// A pointer-like argument is assumed to read from the pointed-to buffer, and may write to the
// buffer as well unless the pointer points to a `const` value.
i >= 0 and
buffer = true and
expr = call.getArgument(i).getFullyConverted() and
exists(Type t | t = expr.getUnspecifiedType() |
t instanceof ArrayType or
t instanceof PointerType or
t instanceof ReferenceType
) and
(
isWrite = true and
not call.getTarget().getParameter(i).getType().isDeeplyConstBelow()
or
isWrite = false
)
)
)
}
/**
* Returns a side effect opcode for parameter index `i` of the specified call.
*
* This predicate will return at most two results: one read side effect, and one write side effect.
*/
Opcode getASideEffectOpcode(Call call, ParameterIndex i) {
exists(boolean buffer |
(
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(i, buffer)
or
not call.getTarget() instanceof SideEffectFunction and
hasDefaultSideEffect(call, i, buffer, false)
) and
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i))
then (
buffer = true and
result instanceof Opcode::SizedBufferReadSideEffect
) else (
buffer = false and result instanceof Opcode::IndirectReadSideEffect
or
buffer = true and result instanceof Opcode::BufferReadSideEffect
)
)
or
exists(boolean buffer, boolean mustWrite |
(
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(i, buffer, mustWrite)
or
not call.getTarget() instanceof SideEffectFunction and
hasDefaultSideEffect(call, i, buffer, true) and
mustWrite = false
) and
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i))
then (
buffer = true and
mustWrite = false and
result instanceof Opcode::SizedBufferMayWriteSideEffect
or
buffer = true and
mustWrite = true and
result instanceof Opcode::SizedBufferMustWriteSideEffect
) else (
buffer = false and
mustWrite = false and
result instanceof Opcode::IndirectMayWriteSideEffect
or
buffer = false and
mustWrite = true and
result instanceof Opcode::IndirectMustWriteSideEffect
or
buffer = true and mustWrite = false and result instanceof Opcode::BufferMayWriteSideEffect
or
buffer = true and mustWrite = true and result instanceof Opcode::BufferMustWriteSideEffect
)
)
}

View File

@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.CppType
private import semmle.code.cpp.models.interfaces.SideEffect
private import InstructionTag
private import SideEffects
private import TranslatedElement
private import TranslatedExpr
private import TranslatedFunction
@@ -424,12 +425,15 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
}
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
TranslatedStructorCallSideEffects() {
getParent().(TranslatedStructorCall).hasQualifier() and
getASideEffectOpcode(expr, -1) instanceof WriteSideEffectOpcode
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {
opcode instanceof Opcode::IndirectMayWriteSideEffect and
tag instanceof OnlyInstructionTag and
t = getTypeForPRValue(expr.getTarget().getDeclaringType())
t = getTypeForPRValue(expr.getTarget().getDeclaringType()) and
opcode = getASideEffectOpcode(expr, -1).(WriteSideEffectOpcode)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -460,9 +464,11 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
Call call;
Expr arg;
int index;
boolean write;
SideEffectOpcode sideEffectOpcode;
TranslatedSideEffect() { this = TTranslatedArgumentSideEffect(call, arg, index, write) }
TranslatedSideEffect() {
this = TTranslatedArgumentSideEffect(call, arg, index, sideEffectOpcode)
}
override Locatable getAST() { result = arg }
@@ -472,13 +478,13 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
int getArgumentIndex() { result = index }
predicate isWrite() { write = true }
predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode }
override string toString() {
write = true and
isWrite() and
result = "(write side effect for " + arg.toString() + ")"
or
write = false and
not isWrite() and
result = "(read side effect for " + arg.toString() + ")"
}
@@ -489,29 +495,29 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
isWrite() and
hasSpecificWriteSideEffect(opcode) and
tag = OnlyInstructionTag() and
opcode = sideEffectOpcode and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() |
if baseType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(baseType)
isWrite() and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() |
if baseType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(baseType)
)
or
index = -1 and
not arg.getUnspecifiedType() instanceof DerivedType and
type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType())
)
or
index = -1 and
not arg.getUnspecifiedType() instanceof DerivedType and
type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType())
not isWrite() and
type = getVoidType()
)
or
not isWrite() and
hasSpecificReadSideEffect(opcode) and
tag = OnlyInstructionTag() and
type = getVoidType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -535,7 +541,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) {
not isWrite() and
if hasSpecificReadSideEffect(any(BufferAccessOpcode op))
if sideEffectOpcode instanceof BufferAccessOpcode
then
result = getUnknownType() and
tag instanceof OnlyInstructionTag and
@@ -557,56 +563,6 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
)
}
predicate hasSpecificWriteSideEffect(Opcode op) {
exists(boolean buffer, boolean mustWrite |
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
then
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, true, mustWrite) and
buffer = true and
(
mustWrite = false and op instanceof Opcode::SizedBufferMayWriteSideEffect
or
mustWrite = true and op instanceof Opcode::SizedBufferMustWriteSideEffect
)
else (
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and
(
buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect
or
buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect
or
buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect
or
buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect
)
)
)
or
not call.getTarget() instanceof SideEffectFunction and
getArgumentIndex() != -1 and
op instanceof Opcode::BufferMayWriteSideEffect
or
not call.getTarget() instanceof SideEffectFunction and
getArgumentIndex() = -1 and
op instanceof Opcode::IndirectMayWriteSideEffect
}
predicate hasSpecificReadSideEffect(Opcode op) {
exists(boolean buffer |
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and
if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
then buffer = true and op instanceof Opcode::SizedBufferReadSideEffect
else (
buffer = true and op instanceof Opcode::BufferReadSideEffect
or
buffer = false and op instanceof Opcode::IndirectReadSideEffect
)
)
or
not call.getTarget() instanceof SideEffectFunction and
op instanceof Opcode::BufferReadSideEffect
}
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getTranslatedCallInstruction(call)

View File

@@ -12,6 +12,7 @@ private import TranslatedStmt
private import TranslatedExpr
private import IRConstruction
private import semmle.code.cpp.models.interfaces.SideEffect
private import SideEffects
/**
* Gets the "real" parent of `expr`. This predicate treats conversions as if
@@ -41,7 +42,8 @@ IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
*/
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
// Pulled out to work around QL-796
// Pulled out for performance. See
// https://github.com/github/codeql-coreql-team/issues/1044.
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
/**
@@ -635,46 +637,15 @@ newtype TTranslatedElement =
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
TTranslatedAllocationSideEffects(AllocationExpr expr) { not ignoreExpr(expr) } or
// A precise side effect of an argument to a `Call`
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
(
expr = call.getArgument(n).getFullyConverted()
or
expr = call.getQualifier().getFullyConverted() and
n = -1 and
// Exclude calls to static member functions. They don't modify the qualifier
not exists(MemberFunction func | func = call.getTarget() and func.isStatic())
) and
(
call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(n, _) and
isWrite = false
or
call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(n, _, _) and
isWrite = true
or
not call.getTarget() instanceof SideEffectFunction and
exists(Type t | t = expr.getUnspecifiedType() |
t instanceof ArrayType or
t instanceof PointerType or
t instanceof ReferenceType
) and
(
isWrite = true and
not call.getTarget().getParameter(n).getType().isDeeplyConstBelow()
or
isWrite = false
)
or
not call.getTarget() instanceof SideEffectFunction and
n = -1 and
(
isWrite = true and
not call.getTarget() instanceof ConstMemberFunction
or
isWrite = false
)
) and
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, SideEffectOpcode opcode) {
not ignoreExpr(expr) and
not ignoreExpr(call)
not ignoreExpr(call) and
(
n >= 0 and expr = call.getArgument(n).getFullyConverted()
or
n = -1 and expr = call.getQualifier().getFullyConverted()
) and
opcode = getASideEffectOpcode(call, n)
}
/**

View File

@@ -15,9 +15,7 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction {
Accept() { this.hasGlobalName(["accept", "accept4", "WSAAccept"]) }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 1 and countParam = 2
}
override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 1 }
override predicate hasArrayInput(int bufParam) { bufParam = 1 }
@@ -46,8 +44,8 @@ private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEf
i = 1 and buffer = false
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
// NOTE: The size parameter is a pointer to the size. So we can't implement `getParameterSizeIndex` for
// this model.
// NOTE: We implement thse two predicates as none because we can't model the low-level changes made to
// the structure pointed to by the file-descriptor argument.
override predicate hasOnlySpecificReadSideEffects() { none() }

View File

@@ -1,10 +1,37 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.PointerWrapper
/**
* The `std::shared_ptr` and `std::unique_ptr` template classes.
*/
private class UniqueOrSharedPtr extends Class {
private class UniqueOrSharedPtr extends Class, PointerWrapper {
UniqueOrSharedPtr() { this.hasQualifiedName(["std", "bsl"], ["shared_ptr", "unique_ptr"]) }
override MemberFunction getAnUnwrapperFunction() {
result.(OverloadedPointerDereferenceFunction).getDeclaringType() = this
or
result.getClassAndName(["operator->", "get"]) = this
}
override predicate pointsToConst() { this.getTemplateArgument(0).(Type).isConst() }
}
/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */
private class PointerWrapperFlow extends TaintFunction, DataFlowFunction {
PointerWrapperFlow() {
this = any(PointerWrapper wrapper).getAnUnwrapperFunction() and
not this.getUnspecifiedType() instanceof ReferenceType
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReturnValueDeref() and
output.isQualifierObject()
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and output.isReturnValue()
}
}
/**

View File

@@ -0,0 +1,17 @@
/** Provides classes for modeling pointer wrapper types and expressions. */
private import cpp
/** A class that wraps a pointer type. For example, `std::unique_ptr` and `std::shared_ptr`. */
abstract class PointerWrapper extends Class {
/**
* Gets a member function of this class that returns the wrapped pointer, if any.
*
* This includes both functions that return the wrapped pointer by value, and functions
* that return a reference to the pointed-to object.
*/
abstract MemberFunction getAnUnwrapperFunction();
/** Holds if the type of the data that is pointed to by this pointer wrapper is `const`. */
abstract predicate pointsToConst();
}

View File

@@ -5,6 +5,8 @@
import cpp
import semmle.code.cpp.controlflow.Dominance
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
/**
* Holds if the value of `use` is guarded using `abs`.
@@ -94,9 +96,15 @@ predicate guardedGreater(Operation e, Expr use) {
VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
/**
* Holds if `e` is not guarded against overflow by `use`.
* Holds if `e` potentially overflows and `use` is an operand of `e` that is not guarded.
*/
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
(
convertedExprMightOverflowPositively(e)
or
// Ensure that the predicate holds when range analysis cannot determine an upper bound
upperBound(e.getFullyConverted()) = exprMaxVal(e.getFullyConverted())
) and
use = e.getAnOperand() and
exists(LocalScopeVariable v | use.getTarget() = v |
// overflow possible if large
@@ -115,9 +123,15 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
}
/**
* Holds if `e` is not guarded against underflow by `use`.
* Holds if `e` potentially underflows and `use` is an operand of `e` that is not guarded.
*/
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
(
convertedExprMightOverflowNegatively(e)
or
// Ensure that the predicate holds when range analysis cannot determine a lower bound
lowerBound(e.getFullyConverted()) = exprMinVal(e.getFullyConverted())
) and
use = e.getAnOperand() and
exists(LocalScopeVariable v | use.getTarget() = v |
// underflow possible if use is left operand and small

View File

@@ -14,8 +14,8 @@ using namespace std;
void* operator new(std::size_t _Size);
void* operator new[](std::size_t _Size);
void* operator new( std::size_t count, const std::nothrow_t& tag );
void* operator new[]( std::size_t count, const std::nothrow_t& tag );
void* operator new( std::size_t count, const std::nothrow_t& tag ) noexcept;
void* operator new[]( std::size_t count, const std::nothrow_t& tag ) noexcept;
void badNew_0_0()
{

View File

@@ -0,0 +1,4 @@
| test.c:15:6:15:16 | ... + ... | this expression needs your attention |
| test.c:17:17:17:27 | ... + ... | this expression needs your attention |
| test.c:22:10:22:15 | ... > ... | this expression needs your attention |
| test.c:26:10:26:15 | ... > ... | this expression needs your attention |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementAfterRefactoringTheCode.ql

View File

@@ -0,0 +1,2 @@
| test.c:8:6:8:51 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. |
| test.c:10:6:10:30 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql

View File

@@ -0,0 +1,32 @@
int tmpFunction(){
return 5;
}
void workFunction_0(char *s) {
int intSize;
char buf[80];
if(intSize>0 && intSize<80 && memset(buf,0,intSize)) return; // GOOD
if(intSize>0 & intSize<80 & memset(buf,0,intSize)) return; // BAD
if(intSize>0 && tmpFunction()) return;
if(intSize<0 & tmpFunction()) return; // BAD
}
void workFunction_1(char *s) {
int intA,intB;
if(intA + intB) return; // BAD
if(intA + intB>4) return; // GOOD
if(intA>0 && (intA + intB)) return; // BAD
while(intA>0)
{
if(intB - intA<10) break;
intA--;
}while(intA>0); // BAD
for(intA=100; intA>0; intA--)
{
if(intB - intA<10) break;
}while(intA>0); // BAD
while(intA>0)
{
if(intB - intA<10) break;
intA--;
} // GOOD
}

View File

@@ -1,9 +1,9 @@
| test.c:42:3:42:24 | ... = ... | potential unsafe or redundant assignment. |
| test.c:43:3:43:40 | ... = ... | potential unsafe or redundant assignment. |
| test.c:44:3:44:40 | ... = ... | potential unsafe or redundant assignment. |
| test.c:45:3:45:44 | ... = ... | potential unsafe or redundant assignment. |
| test.c:46:3:46:44 | ... = ... | potential unsafe or redundant assignment. |
| test.c:47:3:47:48 | ... = ... | potential unsafe or redundant assignment. |
| test.c:48:3:48:48 | ... = ... | potential unsafe or redundant assignment. |
| test.c:49:3:49:50 | ... = ... | potential unsafe or redundant assignment. |
| test.c:50:3:50:50 | ... = ... | potential unsafe or redundant assignment. |
| test.c:54:3:54:24 | ... = ... | potential unsafe or redundant assignment. |
| test.c:55:3:55:40 | ... = ... | potential unsafe or redundant assignment. |
| test.c:56:3:56:44 | ... = ... | potential unsafe or redundant assignment. |
| test.c:57:3:57:44 | ... = ... | potential unsafe or redundant assignment. |
| test.c:58:3:58:48 | ... = ... | potential unsafe or redundant assignment. |
| test.c:59:3:59:48 | ... = ... | potential unsafe or redundant assignment. |
| test.c:60:3:60:52 | ... = ... | potential unsafe or redundant assignment. |
| test.c:61:3:61:50 | ... = ... | potential unsafe or redundant assignment. |
| test.c:62:3:62:54 | ... = ... | potential unsafe or redundant assignment. |

View File

@@ -1,3 +1,5 @@
| test.c:4:3:4:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
| test.c:11:3:11:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
| test.c:19:3:19:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible |
| test.c:8:3:8:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
| test.c:9:3:9:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
| test.c:17:3:17:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
| test.c:18:3:18:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |
| test.c:46:3:46:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. |

View File

@@ -0,0 +1,5 @@
| test.cpp:10:8:10:10 | - ... | this expression needs attention |
| test.cpp:12:3:12:6 | ... ++ | this expression needs attention |
| test.cpp:13:3:13:6 | ++ ... | this expression needs attention |
| test.cpp:14:6:14:21 | ... = ... | this expression needs attention |
| test.cpp:16:6:16:21 | ... = ... | this expression needs attention |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql

View File

@@ -1,70 +1,84 @@
void workFunction_0(char *s) {
char * strncat(char*, const char*, unsigned);
unsigned strlen(const char*);
void* malloc(unsigned);
void strncat_test1(char *s) {
char buf[80];
strncat(buf, s, sizeof(buf)-strlen(buf)-1); // GOOD
strncat(buf, s, sizeof(buf)-strlen(buf)); // BAD
strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD [NOT DETECTED]
strncat(buf, s, sizeof(buf) - strlen(buf) - 1); // GOOD
strncat(buf, s, sizeof(buf) - strlen(buf)); // BAD
strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD
}
void workFunction_1(char *s) {
#define MAX_SIZE 80
void strncat_test2(char *s) {
char buf[MAX_SIZE];
strncat(buf, s, MAX_SIZE-strlen(buf)-1); // GOOD
strncat(buf, s, MAX_SIZE-strlen(buf)); // BAD
strncat(buf, "fix", MAX_SIZE-strlen(buf)); // BAD [NOT DETECTED]
strncat(buf, s, MAX_SIZE - strlen(buf) - 1); // GOOD
strncat(buf, s, MAX_SIZE - strlen(buf)); // BAD
strncat(buf, "fix", MAX_SIZE - strlen(buf)); // BAD
}
void workFunction_2_0(char *s) {
char * buf;
int len=80;
buf = (char *) malloc(len);
strncat(buf, s, len-strlen(buf)-1); // GOOD
strncat(buf, s, len-strlen(buf)); // BAD
strncat(buf, "fix", len-strlen(buf)); // BAD [NOT DETECTED]
void strncat_test3(char *s) {
int len = 80;
char* buf = (char *) malloc(len);
strncat(buf, s, len - strlen(buf) - 1); // GOOD
strncat(buf, s, len - strlen(buf)); // BAD [NOT DETECTED]
strncat(buf, "fix", len - strlen(buf)); // BAD [NOT DETECTED]
}
void workFunction_2_1(char *s) {
char * buf;
int len=80;
buf = (char *) malloc(len+1);
strncat(buf, s, len-strlen(buf)-1); // GOOD
strncat(buf, s, len-strlen(buf)); // GOOD
void strncat_test4(char *s) {
int len = 80;
char* buf = (char *) malloc(len + 1);
strncat(buf, s, len - strlen(buf) - 1); // GOOD
strncat(buf, s, len - strlen(buf)); // GOOD
}
struct buffers
{
unsigned char buff1[50];
unsigned char *buff2;
unsigned char array[50];
unsigned char *pointer;
} globalBuff1,*globalBuff2,globalBuff1_c,*globalBuff2_c;
void strncat_test5(char* s, struct buffers* buffers) {
unsigned len_array = strlen(buffers->array);
unsigned max_size = sizeof(buffers->array);
unsigned free_size = max_size - len_array;
strncat(buffers->array, s, free_size); // BAD
}
void badFunc0(){
void strlen_test1(){
unsigned char buff1[12];
struct buffers buffAll;
struct buffers * buffAll1;
buff1[strlen(buff1)]=0; // BAD
buffAll.buff1[strlen(buffAll.buff1)]=0; // BAD
buffAll.buff2[strlen(buffAll.buff2)]=0; // BAD
buffAll1->buff1[strlen(buffAll1->buff1)]=0; // BAD
buffAll1->buff2[strlen(buffAll1->buff2)]=0; // BAD
globalBuff1.buff1[strlen(globalBuff1.buff1)]=0; // BAD
globalBuff1.buff2[strlen(globalBuff1.buff2)]=0; // BAD
globalBuff2->buff1[strlen(globalBuff2->buff1)]=0; // BAD
globalBuff2->buff2[strlen(globalBuff2->buff2)]=0; // BAD
buffAll.array[strlen(buffAll.array)]=0; // BAD
buffAll.pointer[strlen(buffAll.pointer)]=0; // BAD
buffAll1->array[strlen(buffAll1->array)]=0; // BAD
buffAll1->pointer[strlen(buffAll1->pointer)]=0; // BAD
globalBuff1.array[strlen(globalBuff1.array)]=0; // BAD
globalBuff1.pointer[strlen(globalBuff1.pointer)]=0; // BAD
globalBuff2->array[strlen(globalBuff2->array)]=0; // BAD
globalBuff2->pointer[strlen(globalBuff2->pointer)]=0; // BAD
}
void noBadFunc0(){
void strlen_test2(){
unsigned char buff1[12],buff1_c[12];
struct buffers buffAll,buffAll_c;
struct buffers * buffAll1,*buffAll1_c;
buff1[strlen(buff1_c)]=0; // GOOD
buffAll.buff1[strlen(buffAll_c.buff1)]=0; // GOOD
buffAll.buff2[strlen(buffAll.buff1)]=0; // GOOD
buffAll1->buff1[strlen(buffAll1_c->buff1)]=0; // GOOD
buffAll1->buff2[strlen(buffAll1->buff1)]=0; // GOOD
globalBuff1.buff1[strlen(globalBuff1_c.buff1)]=0; // GOOD
globalBuff1.buff2[strlen(globalBuff1.buff1)]=0; // GOOD
globalBuff2->buff1[strlen(globalBuff2_c->buff1)]=0; // GOOD
globalBuff2->buff2[strlen(globalBuff2->buff1)]=0; // GOOD
buffAll.array[strlen(buffAll_c.array)]=0; // GOOD
buffAll.pointer[strlen(buffAll.array)]=0; // GOOD
buffAll1->array[strlen(buffAll1_c->array)]=0; // GOOD
buffAll1->pointer[strlen(buffAll1->array)]=0; // GOOD
globalBuff1.array[strlen(globalBuff1_c.array)]=0; // GOOD
globalBuff1.pointer[strlen(globalBuff1.array)]=0; // GOOD
globalBuff2->array[strlen(globalBuff2_c->array)]=0; // GOOD
globalBuff2->pointer[strlen(globalBuff2->array)]=0; // GOOD
}
void goodFunc0(){
void strlen_test3(){
unsigned char buffer[12];
int i;
for(i = 0; i < 6; i++)

View File

@@ -0,0 +1,26 @@
int tmpFunc()
{
return 12;
}
void testFunction()
{
int i1,i2,i3;
bool b1,b2,b3;
char c1,c2,c3;
b1 = -b2; //BAD
b1 = !b2; //GOOD
b1++; //BAD
++b1; //BAD
if(i1=tmpFunc()!=i2) //BAD
return;
if(i1=tmpFunc()!=11) //BAD
return;
if((i1=tmpFunc())!=i2) //GOOD
return;
if((i1=tmpFunc())!=11) //GOOD
return;
if(i1=tmpFunc()!=1) //GOOD
return;
if(i1=tmpFunc()==b1) //GOOD
return;
}

View File

@@ -6,6 +6,7 @@
import cpp
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath
import TestUtilities.InlineExpectationsTest
predicate isSink(Element sink) {
@@ -17,7 +18,13 @@ predicate isSink(Element sink) {
predicate astTaint(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) }
predicate irTaint(Expr source, Element sink) { IRDefaultTaintTracking::tainted(source, sink) }
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
override predicate isSink(Element e) { any() }
}
predicate irTaint(Expr source, Element sink) {
TaintedWithPath::taintedWithPath(source, sink, _, _)
}
class IRDefaultTaintTrackingTest extends InlineExpectationsTest {
IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" }

View File

@@ -19,7 +19,7 @@ int main() {
char untainted_buf[100] = "";
char buf[100] = "VAR = ";
sink(strcat(buf, getenv("VAR"))); // $ ast,ir
sink(strcat(buf, getenv("VAR"))); // $ ast MISSING: ir
sink(buf); // $ ast,ir
sink(untainted_buf); // the two buffers would be conflated if we added flow through all partial chi inputs
@@ -250,12 +250,12 @@ void sink(iovec);
int test_readv_and_writev(iovec* iovs) {
readv(0, iovs, 16);
sink(iovs); // $ast,ir
sink(iovs[0]); // $ast MISSING: ir
sink(*iovs); // $ast MISSING: ir
sink(iovs[0]); // $ast,ir
sink(*iovs); // $ast,ir
char* p = (char*)iovs[1].iov_base;
sink(p); // $ MISSING: ast,ir
sink(*p); // $ MISSING: ast,ir
sink(p); // $ ir MISSING: ast
sink(*p); // $ ir MISSING: ast
writev(0, iovs, 16); // $ remote
}

View File

@@ -73,7 +73,7 @@ void test_string()
sink(b); // clean
sink(c); // $ ir MISSING: ast
sink(b.c_str()); // clean
sink(c.c_str()); // $ MISSING: ast,ir
sink(c.c_str()); // $ ir MISSING: ast
}
void test_stringstream()
@@ -93,10 +93,10 @@ void test_stringstream()
sink(ss4); // $ ir MISSING: ast
sink(ss5); // $ ir MISSING: ast
sink(ss1.str());
sink(ss2.str()); // $ MISSING: ast,ir
sink(ss2.str()); // $ ir MISSING: ast
sink(ss3.str()); // $ MISSING: ast,ir
sink(ss4.str()); // $ MISSING: ast,ir
sink(ss5.str()); // $ MISSING: ast,ir
sink(ss4.str()); // $ ir MISSING: ast
sink(ss5.str()); // $ ir MISSING: ast
}
void test_stringstream_int(int source)
@@ -123,14 +123,14 @@ void sink(const char *filename, const char *mode);
void test_strings2()
{
string path1 = user_input();
sink(path1.c_str(), "r"); // $ MISSING: ast,ir
sink(path1.c_str(), "r"); // $ ir MISSING: ast
string path2;
path2 = user_input();
sink(path2.c_str(), "r"); // $ MISSING: ast,ir
sink(path2.c_str(), "r"); // $ ir MISSING: ast
string path3(user_input());
sink(path3.c_str(), "r"); // $ MISSING: ast,ir
sink(path3.c_str(), "r"); // $ ir MISSING: ast
}
void test_string3()
@@ -154,6 +154,6 @@ void test_string4()
// convert back std::string -> char *
cs = ss.c_str();
sink(cs); // $ ast MISSING: ir
sink(cs); // $ ast,ir
sink(ss); // $ ir MISSING: ast
}

View File

@@ -7,9 +7,10 @@
import cpp
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath
import TestUtilities.InlineExpectationsTest
predicate isSink(Element sink) {
predicate argToSinkCall(Element sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink = call.getAnArgument()
@@ -17,11 +18,15 @@ predicate isSink(Element sink) {
}
predicate astTaint(Expr source, Element sink) {
ASTTaintTracking::tainted(source, sink) and isSink(sink)
ASTTaintTracking::tainted(source, sink) and argToSinkCall(sink)
}
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
override predicate isSink(Element e) { argToSinkCall(e) }
}
predicate irTaint(Expr source, Element sink) {
IRDefaultTaintTracking::tainted(source, sink) and isSink(sink)
TaintedWithPath::taintedWithPath(source, sink, _, _)
}
class IRDefaultTaintTrackingTest extends InlineExpectationsTest {

View File

@@ -26,6 +26,7 @@ unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
| test.cpp:373:5:373:20 | Store | PostUpdateNode should have one pre-update node but has 0. |
uniquePostUpdate
postIsInSameCallable
reverseRead
@@ -82,4 +83,5 @@ postWithInFlow
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
| test.cpp:373:5:373:20 | Store | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -20,7 +20,9 @@ unreachableNodeCCtx
localCallNodes
postIsNotPre
postHasUniquePre
| D.cpp:57:5:57:42 | Store | PostUpdateNode should have one pre-update node but has 0. |
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
| simple.cpp:83:9:83:28 | Store | PostUpdateNode should have one pre-update node but has 0. |
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. |
uniquePostUpdate
postIsInSameCallable
@@ -54,6 +56,7 @@ postWithInFlow
| D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. |
| D.cpp:57:5:57:42 | Store | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. |
| aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
@@ -150,6 +153,7 @@ postWithInFlow
| simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. |
| simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. |
| simple.cpp:83:9:83:28 | Store | PostUpdateNode should not be the target of local flow. |
| simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. |
| struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. |
| struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. |

View File

@@ -228,8 +228,8 @@ edges
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | this indirection [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Chi [f1] |
| simple.cpp:83:9:83:28 | Store [f1] | simple.cpp:84:14:84:20 | this indirection [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store [f1] |
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
@@ -494,7 +494,7 @@ nodes
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
| simple.cpp:83:9:83:28 | Chi [f1] | semmle.label | Chi [f1] |
| simple.cpp:83:9:83:28 | Store [f1] | semmle.label | Store [f1] |
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
| simple.cpp:84:14:84:20 | this indirection [f1] | semmle.label | this indirection [f1] |

View File

@@ -19,15 +19,19 @@ class IRPartialDefNode extends IRNode {
override string toString() { result = n.asPartialDefinition().toString() }
}
from Node node, AST::Node astNode, IR::Node irNode, string msg
from Node node, string msg
where
node.asIR() = irNode and
exists(irNode.asPartialDefinition()) and
not exists(AST::Node otherNode | otherNode.asPartialDefinition() = irNode.asPartialDefinition()) and
exists(IR::Node irNode, Expr partial |
node.asIR() = irNode and
partial = irNode.asPartialDefinition() and
not exists(AST::Node otherNode | otherNode.asPartialDefinition() = partial)
) and
msg = "IR only"
or
node.asAST() = astNode and
exists(astNode.asPartialDefinition()) and
not exists(IR::Node otherNode | otherNode.asPartialDefinition() = astNode.asPartialDefinition()) and
exists(AST::Node astNode, Expr partial |
node.asAST() = astNode and
partial = astNode.asPartialDefinition() and
not exists(IR::Node otherNode | otherNode.asPartialDefinition() = partial)
) and
msg = "AST only"
select node, msg

View File

@@ -1,19 +1,42 @@
| test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | AST only |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:14:38:19 | envStr | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:14:49:19 | envStr | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:15:50:24 | envStr_ptr | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:28:50:40 | & ... | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:29:50:40 | envStrGlobal | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:2:52:12 | * ... | AST only |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:3:52:12 | envStr_ptr | AST only |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | AST only |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:67:7:67:13 | copying | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:17:68:24 | userName | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:5:70:10 | call to strcpy | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | AST only |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:15:22:15:25 | nptr | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | AST only |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | AST only |
| test.cpp:100:12:100:15 | call to gets | test.cpp:98:8:98:14 | pointer | AST only |
| test.cpp:100:12:100:15 | call to gets | test.cpp:100:2:100:8 | pointer | AST only |
| test.cpp:100:17:100:22 | buffer | test.cpp:93:18:93:18 | s | AST only |
| test.cpp:100:17:100:22 | buffer | test.cpp:97:7:97:12 | buffer | AST only |
| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion | IR only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:17:106:24 | userName | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:108:8:108:11 | copy | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:2:109:7 | call to strcpy | AST only |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:9:109:12 | copy | AST only |

View File

@@ -2,14 +2,18 @@ import semmle.code.cpp.security.TaintTrackingImpl as AST
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IR
import cpp
class SourceConfiguration extends IR::TaintedWithPath::TaintTrackingConfiguration {
override predicate isSink(Element e) { any() }
}
from Expr source, Element tainted, string side
where
AST::taintedIncludingGlobalVars(source, tainted, _) and
not IR::taintedIncludingGlobalVars(source, tainted, _) and
not IR::TaintedWithPath::taintedWithPath(source, tainted, _, _) and
not tainted.getLocation().getFile().getExtension() = "h" and
side = "AST only"
or
IR::taintedIncludingGlobalVars(source, tainted, _) and
IR::TaintedWithPath::taintedWithPath(source, tainted, _, _) and
not AST::taintedIncludingGlobalVars(source, tainted, _) and
not tainted.getLocation().getFile().getExtension() = "h" and
side = "IR only"

View File

@@ -1,71 +1,48 @@
| test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:40 | (const char *)... | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:6:25:29 | ! ... | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:12 | call to strcmp | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:29 | (bool)... | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:14:25:19 | envStr | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:6:29:28 | ! ... | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:12 | call to strcmp | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:28 | (bool)... | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:14:29:19 | envStr | |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:8:24:8:25 | s1 | |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:14:38:19 | envStr | |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:28 | call to getenv | |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:40 | (const char *)... | |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:40:14:40:19 | envStr | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:14:49:19 | envStr | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv | |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... | |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:17:68:24 | userName | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:33 | call to getenv | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:46 | (const char *)... | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:5:70:10 | call to strcpy | |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:18:70:25 | userName | |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:15:22:15:25 | nptr | |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | |
| test.cpp:100:12:100:15 | call to gets | test.cpp:98:8:98:14 | pointer | |
| test.cpp:100:12:100:15 | call to gets | test.cpp:100:12:100:15 | call to gets | |
| test.cpp:100:17:100:22 | buffer | test.cpp:93:18:93:18 | s | |
| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion | |
| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | buffer | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:8:24:8:25 | s1 | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:17:106:24 | userName | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:33 | call to getenv | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:46 | (const char *)... | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:2:109:7 | call to strcpy | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:15:109:22 | userName | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:6:111:27 | ! ... | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:12 | call to strcmp | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:27 | (bool)... | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | (const char *)... | |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | copy | |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:40 | (const char *)... |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:6:25:29 | ! ... |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:12 | call to strcmp |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:29 | (bool)... |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:14:25:19 | envStr |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:6:29:28 | ! ... |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:12 | call to strcmp |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:28 | (bool)... |
| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:14:29:19 | envStr |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:28 | call to getenv |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:40 | (const char *)... |
| test.cpp:38:23:38:28 | call to getenv | test.cpp:40:14:40:19 | envStr |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... |
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:33 | call to getenv |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:46 | (const char *)... |
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:18:70:25 | userName |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv |
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... |
| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy |
| test.cpp:100:12:100:15 | call to gets | test.cpp:100:12:100:15 | call to gets |
| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion |
| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | buffer |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:33 | call to getenv |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:46 | (const char *)... |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:15:109:22 | userName |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:6:111:27 | ! ... |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:12 | call to strcmp |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:27 | (bool)... |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | (const char *)... |
| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | copy |

View File

@@ -1,7 +1,11 @@
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking
from Expr source, Element tainted, string globalVar
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
override predicate isSink(Element e) { any() }
}
from Expr source, Element tainted
where
taintedIncludingGlobalVars(source, tainted, globalVar) and
TaintedWithPath::taintedWithPath(source, tainted, _, _) and
not tainted.getLocation().getFile().getExtension() = "h"
select source, tainted, globalVar
select source, tainted

View File

@@ -0,0 +1,127 @@
namespace std {
namespace detail {
template<typename T>
class compressed_pair_element {
T element;
public:
compressed_pair_element() = default;
compressed_pair_element(const T& t) : element(t) {}
T& get() { return element; }
const T& get() const { return element; }
};
template<typename T, typename U>
struct compressed_pair : private compressed_pair_element<T>, private compressed_pair_element<U> {
compressed_pair() = default;
compressed_pair(T& t) : compressed_pair_element<T>(t), compressed_pair_element<U>() {}
compressed_pair(const compressed_pair&) = delete;
compressed_pair(compressed_pair<T, U>&&) noexcept = default;
T& first() { return static_cast<compressed_pair_element<T>&>(*this).get(); }
U& second() { return static_cast<compressed_pair_element<U>&>(*this).get(); }
const T& first() const { return static_cast<const compressed_pair_element<T>&>(*this).get(); }
const U& second() const { return static_cast<const compressed_pair_element<U>&>(*this).get(); }
};
}
template<class T>
struct default_delete {
void operator()(T* ptr) const { delete ptr; }
};
template<class T>
struct default_delete<T[]> {
template<class U>
void operator()(U* ptr) const { delete[] ptr; }
};
template<class T, class Deleter = default_delete<T> >
class unique_ptr {
private:
detail::compressed_pair<T*, Deleter> data;
public:
constexpr unique_ptr() noexcept {}
explicit unique_ptr(T* ptr) noexcept : data(ptr) {}
unique_ptr(const unique_ptr& ptr) = delete;
unique_ptr(unique_ptr&& ptr) noexcept = default;
unique_ptr& operator=(unique_ptr&& ptr) noexcept = default;
T& operator*() const { return *get(); }
T* operator->() const noexcept { return get(); }
T* get() const noexcept { return data.first(); }
~unique_ptr() {
Deleter& d = data.second();
d(data.first());
}
};
template<typename T, class... Args> unique_ptr<T> make_unique(Args&&... args) {
return unique_ptr<T>(new T(args...)); // std::forward calls elided for simplicity.
}
class ctrl_block {
unsigned uses;
public:
ctrl_block() : uses(1) {}
void inc() { ++uses; }
bool dec() { return --uses == 0; }
virtual void destroy() = 0;
virtual ~ctrl_block() {}
};
template<typename T, class Deleter = default_delete<T> >
struct ctrl_block_impl: public ctrl_block {
T* ptr;
Deleter d;
ctrl_block_impl(T* ptr, Deleter d) : ptr(ptr), d(d) {}
virtual void destroy() override { d(ptr); }
};
template<class T>
class shared_ptr {
private:
ctrl_block* ctrl;
T* ptr;
void dec() {
if(ctrl->dec()) {
ctrl->destroy();
delete ctrl;
}
}
void inc() {
ctrl->inc();
}
public:
constexpr shared_ptr() noexcept = default;
shared_ptr(T* ptr) : ctrl(new ctrl_block_impl<T>(ptr, default_delete<T>())) {}
shared_ptr(const shared_ptr& s) noexcept : ptr(s.ptr), ctrl(s.ctrl) {
inc();
}
shared_ptr(shared_ptr&& s) noexcept = default;
T* operator->() const { return ptr; }
T& operator*() const { return *ptr; }
~shared_ptr() { dec(); }
};
template<typename T, class... Args> shared_ptr<T> make_shared(Args&&... args) {
return shared_ptr<T>(new T(args...)); // std::forward calls elided for simplicity.
}
}

View File

@@ -0,0 +1,39 @@
import TestUtilities.dataflow.FlowTestCommon
module ASTTest {
private import semmle.code.cpp.dataflow.TaintTracking
class ASTSmartPointerTaintConfig extends TaintTracking::Configuration {
ASTSmartPointerTaintConfig() { this = "ASTSmartPointerTaintConfig" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(FunctionCall).getTarget().getName() = "source"
}
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
)
}
}
}
module IRTest {
private import semmle.code.cpp.ir.dataflow.TaintTracking
class IRSmartPointerTaintConfig extends TaintTracking::Configuration {
IRSmartPointerTaintConfig() { this = "IRSmartPointerTaintConfig" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(FunctionCall).getTarget().getName() = "source"
}
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
)
}
}
}

Some files were not shown because too many files have changed in this diff Show More