Compare commits

..

413 Commits

Author SHA1 Message Date
Mathias Vorreiter Pedersen
79947956bc Merge pull request #14509 from MathiasVP/tag-redundant-null-check-simple-as-security
C++: Mark `cpp/redundant-null-check-simple` as a security query
2023-10-16 11:58:21 +01:00
Mathias Vorreiter Pedersen
ba27a0d515 Update cpp/ql/src/change-notes/2023-10-16-redundant-null-check-simple.md
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-10-16 12:48:53 +02:00
Mathias Vorreiter Pedersen
32d82380f1 C++: Add change note. 2023-10-16 11:08:27 +01:00
Joe Farebrother
fe2468e7d0 Merge pull request #14498 from joefarebrother/csharp-missing-access-control
C#: Fix FP in Missing Function Level Access Control and Insecure Direct Object Reference
2023-10-16 10:46:19 +01:00
Mathias Vorreiter Pedersen
20c3984872 C++: Add the 'security' tag and add a 'security-severity' rating to 'cpp/redundant-null-check-simple'. 2023-10-16 09:54:36 +01:00
Arthur Baars
0e3369f93f Merge pull request #14484 from aibaars/ts53-js
JS: Support import attributes
2023-10-16 10:47:49 +02:00
Erik Krogh Kristensen
80c5e1ea77 Merge pull request #14497 from erik-krogh/jsp
JS: add support for extracting `.jsp` files
2023-10-16 09:27:46 +02:00
Erik Krogh Kristensen
c30e004506 Merge pull request #14506 from github/dependabot/cargo/ql/tracing-0.1.39
Bump tracing from 0.1.38 to 0.1.39 in /ql
2023-10-16 09:24:12 +02:00
Tony Torralba
ae8e237f2c Merge pull request #14494 from atorralba/atorralba/remove-library
Java/C/C#: Remove library annotations
2023-10-16 09:01:40 +02:00
Tamás Vajk
d723905035 Merge pull request #14368 from tamasvajk/standalone/use-legacy-framework-dlls
C#: Choose between .NET framework or core DLLs in standalone
2023-10-16 08:53:55 +02:00
dependabot[bot]
7700210ed2 Bump tracing from 0.1.38 to 0.1.39 in /ql
Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.38 to 0.1.39.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.38...tracing-0.1.39)

---
updated-dependencies:
- dependency-name: tracing
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-16 03:21:13 +00:00
Owen Mansel-Chan
53561008a1 Merge pull request #14445 from owen-mc/go/automated-mad-coverage-report
Go: automated mad coverage report
2023-10-15 21:49:47 +01:00
Owen Mansel-Chan
39bca2d4bb Merge pull request #14276 from tunnelshade/enable-gokit-by-default
Go: Enable GoKit module into the default list
2023-10-15 21:44:27 +01:00
BD
0ef83b3c74 Merge branch 'main' into enable-gokit-by-default 2023-10-15 10:22:27 +05:30
Jeroen Ketema
d56a9f0781 Merge pull request #14424 from jketema/rewrite-cgi-xss
C++: Rewrite `cpp/cgi-xss` to not use default taint tracking
2023-10-13 17:57:04 +02:00
Mathias Vorreiter Pedersen
fb0016e4f6 Merge pull request #14485 from geoffw0/logging
Swift: Add more sinks to `swift/cleartext-logging`
2023-10-13 16:09:19 +01:00
Mathias Vorreiter Pedersen
9a2ac65f53 Merge pull request #14394 from geoffw0/sqlpathinject3
Swift: Add sinks for sqlite3 and SQLite.swift to swift/hardcoded-key
2023-10-13 16:07:09 +01:00
Joe Farebrother
915352861d Check for generic base types in Missing Function Level Access Control and Insecure Direct Object Reference. 2023-10-13 14:22:45 +01:00
erik-krogh
69c3e62965 add change-note 2023-10-13 15:16:39 +02:00
Tamas Vajk
15ec0a10c9 Code quality improvements 2023-10-13 14:09:58 +02:00
Jeroen Ketema
61676277e8 C++: Fix barrier in cpp/cgi-xss 2023-10-13 14:05:47 +02:00
Tony Torralba
0cea3f8531 Remove library annotations 2023-10-13 12:46:56 +02:00
Harry Maclean
1297acf5b1 Merge pull request #14216 from hmac/hmac-graphql-enum
Ruby: Restrict GraphQL remote flow sources
2023-10-13 11:31:50 +01:00
erik-krogh
9080e84fc9 add support for extracting .jsp files 2023-10-13 12:09:27 +02:00
Tony Torralba
5e921784fb Merge pull request #14399 from ebickle/fix/thread-resource-arithmetic
Java: Flow taint through arithmetic expressions for java/thread-resource-abuse experimental query
2023-10-13 10:06:33 +02:00
Erik Krogh Kristensen
b1ad61e27d Merge pull request #14481 from erik-krogh/proper-codepoints
ReDoS: use the new codePointAt and codePointCount methods instead of regex hacks
2023-10-13 09:35:55 +02:00
Felicity Chapman
2ddcd1d9cc Merge pull request #14489 from github/felicitymay-typo-fix
Fix typo in link
2023-10-12 21:45:30 +01:00
Felicity Chapman
8f70b55158 Fix typo in link 2023-10-12 20:53:44 +01:00
Ian Lynagh
2edc70da79 Merge pull request #14390 from igfoo/igfoo/compr
Kotlin: Improve support for TRAP compression options
2023-10-12 20:22:10 +01:00
Geoffrey White
fe57cd0784 Merge pull request #14488 from geoffw0/strlentest
Swift: Additional test cases for `swift\string-length-conflation`
2023-10-12 19:39:43 +01:00
AlexDenisov
6ab2de10e3 Merge pull request #14437 from github/alexdenisov/ignore-unavailable-declarations
Swift: skip declarations marked as unavailable
2023-10-12 20:08:18 +02:00
Ian Lynagh
ed9502fd0b Kotlin: Enhance the TRAP compression test 2023-10-12 18:13:07 +01:00
Ian Lynagh
adb47399c7 Kotlin: Improve support for TRAP compression options
While you could control compression with
    CODEQL_EXTRACTOR_JAVA_OPTION_TRAP_COMPRESSION
before, most TRAP files used gzip regardless for compatibility with the
Java extractor. Now Java understands the option too we can use it for
shared TRAP files.
2023-10-12 18:13:06 +01:00
Mathias Vorreiter Pedersen
3c34638438 Merge pull request #14486 from MathiasVP/simplify-overrun-write
C++: Remove unnecessary `FlowState` from `cpp/overrun-write`
2023-10-12 17:48:52 +01:00
Geoffrey White
9f683b8630 Swift: Remove duplicate results. 2023-10-12 17:38:58 +01:00
Geoffrey White
cf7f355fc4 Swift: Additional test cases. 2023-10-12 17:11:56 +01:00
Mathias Vorreiter Pedersen
64fa6c8bbd C++: Remove the hacky flow state since this is no longer needed after #13717. 2023-10-12 13:58:36 +01:00
Geoffrey White
5c0085880f Swift: Change note. 2023-10-12 13:24:10 +01:00
Geoffrey White
e2a8569940 Swift: Clean up indentation. 2023-10-12 13:05:20 +01:00
Geoffrey White
8f852f2e7d Swift: Turn sink models into flow summary models, where appropriate. 2023-10-12 12:57:05 +01:00
erik-krogh
fa1e8ee426 add getACodepoint to the shared Strings library, and use it in NfaUtils 2023-10-12 13:38:19 +02:00
erik-krogh
822ba2ae59 add documentation for the new string methods in ql-language-specification.rst 2023-10-12 13:38:19 +02:00
erik-krogh
116025c569 use the new codePointAt and codePointCount methods instead of regex hacks 2023-10-12 13:38:19 +02:00
Arthur Baars
a4d0ef6350 Add changenote 2023-10-12 13:04:00 +02:00
Arthur Baars
a9a21aa313 Rename DynamicImportExpr::getImport{Attributes => Options} 2023-10-12 13:00:39 +02:00
Arthur Baars
1f4fcf1f31 Rename test files 2023-10-12 13:00:39 +02:00
Arthur Baars
a1c1f7b910 Add tests for deprecated 'assert' syntax 2023-10-12 13:00:39 +02:00
Arthur Baars
f38d2e1b89 Replace 'assert' with 'with' in QL test files 2023-10-12 13:00:39 +02:00
Arthur Baars
c28004f2a6 Rename 'getImportAssertion()' to 'getImportAttributes()' in QL library 2023-10-12 13:00:39 +02:00
Arthur Baars
07172da1bc Add tests for deprecated 'assert' syntax 2023-10-12 12:51:13 +02:00
Arthur Baars
f7b02c01dd Rename getAssertion() to getAttributes() in the extractor 2023-10-12 12:51:13 +02:00
Arthur Baars
1d9ee5da3c Rename 'assertions' to 'attributes' in JS extractor 2023-10-12 12:49:25 +02:00
Erik Krogh Kristensen
59c43c7904 Merge pull request #14410 from erik-krogh/bigger-compilation-cache
use a bigger compilation cache in the compile-queries workflow
2023-10-12 12:35:44 +02:00
Mathias Vorreiter Pedersen
02f73145d6 Merge pull request #14354 from geoffw0/conversions2
Swift: Improve models for Numeric, RangeReplaceableCollection
2023-10-12 11:13:50 +01:00
Arthur Baars
b936e91fe9 Support JS import attributes (previously import assertions) 2023-10-12 11:43:42 +02:00
Michael B. Gale
f6570710e7 Merge pull request #14441 from github/dependabot/go_modules/go/extractor/golang.org/x/tools-0.14.0
Bump golang.org/x/tools from 0.13.0 to 0.14.0 in /go/extractor
2023-10-12 10:19:34 +01:00
Tamas Vajk
3b4ea27caf Be more explicit about expected assembly loading exceptions 2023-10-12 11:10:30 +02:00
Tamas Vajk
09c1c715a3 Filter analyzer assemblies from nuget packages 2023-10-12 11:10:30 +02:00
Geoffrey White
7916bd39b4 Swift: Generalize 'write' models. 2023-10-12 09:21:33 +01:00
Geoffrey White
09974b5176 Swift: Extend sink models. 2023-10-12 09:17:04 +01:00
Tamas Vajk
8a0dc31ab0 Revert "Add source generators to framework stubs"
This reverts commit 2e8a91efda.
2023-10-12 09:35:08 +02:00
Tamas Vajk
2e8a91efda Add source generators to framework stubs 2023-10-12 08:51:06 +02:00
Tamas Vajk
534ea3ecac Adjust stub generator test to fix the nuget package version 2023-10-12 08:50:32 +02:00
Owen Mansel-Chan
5fcdb9e112 Merge pull request #14442 from owen-mc/go/test-qldoc-coverage
Fix module name
2023-10-11 23:45:53 +01:00
Owen Mansel-Chan
286271340e Merge branch 'main' into go/automated-mad-coverage-report 2023-10-11 21:31:25 +01:00
Tamas Vajk
e82076d558 Lock SDK version in standalone test 2023-10-11 22:28:47 +02:00
Owen Mansel-Chan
e300440a8b Delete redundant import 2023-10-11 21:28:31 +01:00
Owen Mansel-Chan
dfcdb4ace8 Update CSV to MaD in description for java and C# 2023-10-11 21:09:59 +01:00
Eric Bickle
ee2d8f84de Merge branch 'main' into fix/thread-resource-arithmetic 2023-10-11 13:09:57 -07:00
Owen Mansel-Chan
e5e9c33005 Generated reports 2023-10-11 21:09:55 +01:00
Owen Mansel-Chan
06a600c7fb Set up automated coverage reports for Go
Copied from https://github.com/github/codeql/pull/6148
2023-10-11 21:09:54 +01:00
Eric Bickle
f018d83951 Merge branch 'fix/thread-resource-arithmetic' of https://github.com/ebickle/codeql into fix/thread-resource-arithmetic 2023-10-11 13:09:39 -07:00
Eric Bickle
4cb78ab3c7 Remove change notes 2023-10-11 13:08:56 -07:00
Tamas Vajk
da096553a2 Do not throw exception when working directory cleanup fails 2023-10-11 20:48:17 +02:00
Geoffrey White
0e4cd7f52f Swift: Additional test cases. 2023-10-11 18:37:24 +01:00
Henry Mercer
1a370bfbbe Merge pull request #14443 from github/post-release-prep/codeql-cli-2.15.0
Post-release preparation for codeql-cli-2.15.0
2023-10-11 17:39:04 +01:00
Tamas Vajk
4f31b5a214 C#: Fix stub generator to use framework references from nuget packages 2023-10-11 16:40:09 +02:00
Tamas Vajk
ada5dcced4 Adjust expected test result in windows standalone test 2023-10-11 16:25:35 +02:00
Tamas Vajk
e718796f23 Separate standalone dependency integration tests by platform 2023-10-11 16:25:35 +02:00
Tamas Vajk
e1b283c14a Exclude nuget packages with prefix runtime. from the references 2023-10-11 16:25:34 +02:00
Tamas Vajk
93380f8cbb Force the nuget download of dotnet framework reference assemblies 2023-10-11 16:25:34 +02:00
Tamas Vajk
12fdb3427b Add integration test targetting .NET 4.8 2023-10-11 16:25:34 +02:00
Tamas Vajk
b8effa3a1c Add integration test listing standalone extracted assemblies 2023-10-11 16:25:34 +02:00
Tamas Vajk
4e2c6ff8d7 C#: Consider possibly restored reference assemblies 2023-10-11 16:25:34 +02:00
Tamas Vajk
4887c697c9 C#: Choose between .NET framework or core DLLs in standalone 2023-10-11 16:25:34 +02:00
github-actions[bot]
ae6af17c74 Post-release preparation for codeql-cli-2.15.0 2023-10-11 14:19:20 +00:00
Tamás Vajk
a31f946d6f Merge pull request #14436 from tamasvajk/void-type-value-type
C#: Include the `void` type in value types
2023-10-11 16:16:06 +02:00
Asger F
7780fe9472 Merge pull request #14435 from asgerf/ruby/port-synced-queries
JS/Ruby: desync two queries and port the Ruby version to ConfigSig-style
2023-10-11 15:50:58 +02:00
Owen Mansel-Chan
b6bf4d04ff Fix module name 2023-10-11 14:47:46 +01:00
dependabot[bot]
442a4fe9cf Bump golang.org/x/tools from 0.13.0 to 0.14.0 in /go/extractor
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.13.0 to 0.14.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 13:12:49 +00:00
Michael B. Gale
7a98afe6ec Merge pull request #14439 from github/mbg/go/workspace-experiments
Go: Move `go.mod` into `extractor` subdirectory
2023-10-11 14:11:07 +01:00
Jean Helie
a4eb3fd997 Merge pull request #14438 from github/jhelie/fix-automodel-extraction-queries
Automodel: Fix automodel extraction queries
2023-10-11 14:30:01 +02:00
Michael B. Gale
7d7d90e7e0 Update expected test output 2023-10-11 13:18:27 +01:00
Michael B. Gale
94b0bc1e35 Move go.mod into extractor directory 2023-10-11 13:10:20 +01:00
Jean Helie
6260768e6a update query message to incoude extensibleType 2023-10-11 14:02:24 +02:00
Jean Helie
c41676a21a update query message to incoude extensibleType 2023-10-11 14:02:12 +02:00
Owen Mansel-Chan
477d8f8b9a Merge pull request #14064 from amammad/amammad-go-NewFileSystemAccess
Go: New File System Access Sinks
2023-10-11 12:58:38 +01:00
Owen Mansel-Chan
96543b8337 Merge pull request #14075 from amammad/amammad-go-JWT
Go: Improved JWT query, JWT decoding without verification
2023-10-11 12:31:43 +01:00
Mathias Vorreiter Pedersen
02915582eb Merge pull request #14432 from MathiasVP/select-the-right-node-for-flow-sources
C++: Use fully converted instructions as the target of modelled functions
2023-10-11 13:04:16 +02:00
Owen Mansel-Chan
8a3aa2c767 Fix formatting 2023-10-11 11:46:31 +01:00
Tamas Vajk
267fd23b26 C#: Include the void type in value types 2023-10-11 12:01:17 +02:00
Tamás Vajk
304d7a4395 Merge pull request #14429 from tamasvajk/relax-metadata_handle-keyset
C#: Remove `keyset` from `metadata_handle` relation
2023-10-11 12:00:11 +02:00
Erik Krogh Kristensen
85bb14f04f Merge pull request #14405 from erik-krogh/tagCall
JS: recognize tagged template literals as `DataFlow::CallNode`
2023-10-11 11:25:34 +02:00
Mathias Vorreiter Pedersen
d54ab640c7 Merge branch 'main' into select-the-right-node-for-flow-sources 2023-10-11 10:17:10 +01:00
Alex Denisov
4133284bc8 Swift: skip declarations marked as unavailable 2023-10-11 10:55:49 +02:00
Tamás Vajk
aa7a667919 Merge pull request #14421 from tamasvajk/csharp/autobuilder-test
C#: Add autobuilder test with global.json
2023-10-11 10:35:53 +02:00
amammad
5e273238ca fix qldoc 2023-10-11 10:33:44 +02:00
Asger F
89bd00a4ec Ruby: port queries to ConfigSig-style 2023-10-11 10:06:19 +02:00
Asger F
6df919a917 JS/Ruby: remove sync between two queries 2023-10-11 10:06:11 +02:00
Rasmus Wriedt Larsen
68d00a829e Merge pull request #14430 from RasmusWL/api-graph-import-star
Python: Better allow `import *` to work with API graphs
2023-10-11 10:03:46 +02:00
Erik Krogh Kristensen
6377e92067 Update javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
Co-authored-by: Asger F <asgerf@github.com>
2023-10-11 09:52:48 +02:00
Erik Krogh Kristensen
e99b1598d1 Merge pull request #14433 from erik-krogh/delete-expected
JS: delete an .expected file outside the test directories
2023-10-11 09:44:04 +02:00
Tamás Vajk
c587dbb72a Merge pull request #14428 from tamasvajk/feature/deterministic-conflict-resolution
C#: Make conflicting assembly selection deterministic in standalone
2023-10-11 08:40:50 +02:00
amammad
4499048d8e better query quality thanks to owen 2023-10-10 23:41:45 +02:00
amammad
877605d31b change c to C for fixing the qhelp error :) 2023-10-10 23:35:05 +02:00
amammad
b6968d9260 fix beego tests 2023-10-10 23:30:26 +02:00
amammad
8d6f985aea fix afero additional step and tests 2023-10-10 23:24:04 +02:00
amammad
db9f74bc78 fix tests 2023-10-10 23:15:07 +02:00
amammad
82483a206e fix tests 2023-10-10 23:14:11 +02:00
amammad
38b0ed8176 fix issues according to codereview 2023-10-10 23:12:30 +02:00
erik-krogh
ccd06c78b9 delete an .expected file outside the test directories 2023-10-10 21:35:19 +02:00
Eric Bickle
7a4382fb69 Merge branch 'main' into fix/thread-resource-arithmetic 2023-10-10 09:38:16 -07:00
Eric Bickle
80c8259e34 Remove unnecessary AdditionalValueStep check 2023-10-10 09:35:45 -07:00
Mathias Vorreiter Pedersen
f1cefc8900 Merge branch 'main' into select-the-right-node-for-flow-sources 2023-10-10 17:35:37 +01:00
Mathias Vorreiter Pedersen
496f190d70 C++: Accept test changes. 2023-10-10 16:45:31 +01:00
Mathias Vorreiter Pedersen
512c10ec59 C++: Use the fully converted expression when converting models to dataflow nodes. 2023-10-10 16:45:25 +01:00
Rasmus Wriedt Larsen
ee75b104eb Python: Add change-note 2023-10-10 17:45:11 +02:00
Rasmus Wriedt Larsen
72d0dcdaba Python: Workaround for module level items from import * not being LocalSourceNodes 2023-10-10 17:45:11 +02:00
Rasmus Wriedt Larsen
6521e5165c Python: Extend import * with plain use
(no calls or anything)
2023-10-10 17:45:11 +02:00
yoff
f1266a3e81 Merge pull request #14417 from github/tausbn/python-add-flow-for-assignment-expressions 2023-10-10 17:09:20 +02:00
Tamas Vajk
4c6073ebce C#: Remove keyset from metadata_handle relation 2023-10-10 16:49:48 +02:00
Tamas Vajk
2378e31c5e C#: Make conflicting assembly selection deterministic 2023-10-10 16:32:02 +02:00
Michael B. Gale
be16cb4190 Merge pull request #14415 from github/mbg/go/dependabot-config 2023-10-10 14:36:34 +01:00
Michael B. Gale
ce905bba41 Apply suggestions from code review
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2023-10-10 14:21:20 +01:00
Tamás Vajk
bc1c22cda2 Merge pull request #14425 from tamasvajk/standalone/nuget-download-lazy
C#: Only download nuget.exe if there are packages.config files
2023-10-10 14:28:43 +02:00
Rasmus Wriedt Larsen
2d947a4f53 Merge pull request #13781 from maikypedia/maikypedia/python-unsafe-deserialization
Python: Add unsafe deserialization sinks (CWE-502)
2023-10-10 13:30:38 +02:00
Owen Mansel-Chan
542d5a2451 Merge pull request #14414 from owen-mc/go/fix-incorrect-integer-conversion-performance-regression
Go: Change MaxValueState API to get architecture bit size
2023-10-10 11:27:18 +01:00
Jeroen Ketema
3b777c2764 C++: Rewrite cpp/cgi-xss to not use default taint tracking
Also add a test that demonstrates that we need to look at inidrect expressions
and not direct ones.
2023-10-10 11:56:39 +02:00
Tamas Vajk
1872a937d5 C#: Only download nuget.exe if there are packages.config files 2023-10-10 11:39:39 +02:00
Owen Mansel-Chan
fd9c1d30f9 Remove argument that is always one value 2023-10-10 10:35:04 +01:00
Owen Mansel-Chan
cf0411e7e2 Change MaxValueState API to get architecture bit size
This fixes a performance regression, though it is not clear why.
2023-10-10 10:35:02 +01:00
Taus
8e1bb4b364 Python: Accept moved consistency test results
Co-authored-by: Rasmus Lerchedahl Petersen <yoff@github.com>
2023-10-10 09:22:36 +00:00
Geoffrey White
0d562d4874 Swift: Autoformat. 2023-10-10 10:01:37 +01:00
Geoffrey White
48ee4add08 Merge branch 'main' into sqlpathinject3 2023-10-10 08:54:44 +01:00
Geoffrey White
0374414798 Swift: Fix TupleElement syntax. 2023-10-10 08:31:50 +01:00
Michael Nebel
5c44f8bbad Merge pull request #14370 from michaelnebel/java/enablethreatmodels
Java: Enable threat models for most Java queries.
2023-10-10 09:25:47 +02:00
Tamas Vajk
538df1bb6d C#: Add autobuilder test with global.json 2023-10-10 09:11:40 +02:00
Erik Krogh Kristensen
5cb3543899 Merge pull request #14420 from github/dependabot/cargo/ql/regex-1.10.0
Bump regex from 1.9.6 to 1.10.0 in /ql
2023-10-10 08:43:46 +02:00
dependabot[bot]
0e09420e7b Bump regex from 1.9.6 to 1.10.0 in /ql
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.6 to 1.10.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.9.6...1.10.0)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-10 03:56:00 +00:00
Erik Krogh Kristensen
4489e2bf28 Merge pull request #14403 from erik-krogh/dDEps
All: delete outdated deprecations
2023-10-09 21:04:55 +02:00
amammad
2579791f51 fix examples 2023-10-09 19:00:55 +02:00
Jeroen Ketema
fe60269fdd Merge pull request #14416 from jketema/revert-cgi-xss-rewrite
Revert "C++: Rewrite `cpp/cgi-xss` to not use default taint tracking"
2023-10-09 18:52:54 +02:00
Jeroen Ketema
6ff8e06ace Revert "C++: Rewrite cpp/cgi-xss to not use default taint tracking"
This reverts commit b6132d2a0f.
2023-10-09 16:30:21 +02:00
Taus
e8ac258994 Python: Add missing flow for AssignmentExpr nodes
Also extend the tests surrounding this construct to be a bit more comprehensive.

Co-authored-by: Rasmus Lerchedahl Petersen <yoff@github.com>
2023-10-09 14:16:03 +00:00
Michael B. Gale
f186b93c93 Add dependabot configuration for Go dependencies 2023-10-09 15:14:17 +01:00
Robert Marsh
8af727734e Merge pull request #13909 from rdmarsh2/rdmarsh2/swift/for-in
Swift: dataflow for `for-in` loops
2023-10-09 10:00:27 -04:00
Michael B. Gale
ebd640da04 Merge pull request #14391 from github/mbg/go/update-newer-go-version-needed
Go: Fix version detection and test for `newer-go-version-needed`
2023-10-09 14:47:37 +01:00
Erik Krogh Kristensen
625e889c62 Merge pull request #14339 from erik-krogh/range-printing
JS/PY/RB/Java: escape unicode chars in overly-large-range
2023-10-09 14:22:38 +02:00
Geoffrey White
57e32b47b7 Merge pull request #14386 from geoffw0/swiftperf
Swift: defaultImplicitTaintRead performance improvement
2023-10-09 13:07:11 +01:00
Geoffrey White
62b0ebf2fe Merge pull request #14407 from geoffw0/grdbsinks
Swift: Add sinks for the GRDB database library to swift/hardcoded-key
2023-10-09 12:58:17 +01:00
erik-krogh
e1b2f81f43 Revert "update doc example to not use isBarrierGuard"
This reverts commit 28f8c1cc11.
2023-10-09 13:29:41 +02:00
erik-krogh
ef63d9dd47 use a bigger compilation cache in the compile-queries workflow 2023-10-09 13:21:37 +02:00
Michael Nebel
cf3a62d201 Java: Address review comments. 2023-10-09 13:06:59 +02:00
Anders Schack-Mulligen
4a0ab4a050 Merge pull request #14402 from Marcono1234/marcono1234/MemberRefExpr-getReceiverExpr
Java: Add predicate `MemberRefExpr::getReceiverExpr`
2023-10-09 13:01:36 +02:00
Anders Schack-Mulligen
8c6a1be070 Merge pull request #14401 from Marcono1234/marcono1234/ClassInstanceExpr-type-argument-doc
Java: Adjust `ClassInstanceExpr` type argument predicates docs
2023-10-09 13:01:18 +02:00
Robert
e38ba27a65 Merge pull request #14408 from github/robertbrignull/telemetryLevel-docs
Update about-telemetry-in-codeql-for-visual-studio-code.rst to mention telemtry.telemetryLevel
2023-10-09 11:38:33 +01:00
Robert
ada331588f Update about-telemetry-in-codeql-for-visual-studio-code.rst to mention telemtry.telemetryLevel 2023-10-09 11:04:52 +01:00
Jeroen Ketema
f7bd801e00 Merge pull request #11716 from jketema/rewrite-cgi-xss
C++: Rewrite `cpp/cgi-xss` to not use default taint tracking
2023-10-09 11:26:14 +02:00
Mathias Vorreiter Pedersen
a1d417d8b6 Merge pull request #14385 from alexet/ir-debug-perf
CPP: Improve performance of IR debugging
2023-10-09 11:21:03 +02:00
Tony Torralba
0258dd4fed Merge pull request #14379 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-10-09 10:06:22 +02:00
erik-krogh
a7ab9fd93b add change-notes 2023-10-09 09:43:06 +02:00
erik-krogh
f48b47c656 JavaScript: add import that populate the shared abstract classes 2023-10-09 09:14:55 +02:00
erik-krogh
57c757c0a6 Ruby: delete outdated deprecation in test code 2023-10-09 09:14:55 +02:00
erik-krogh
194f918c0b Python: delete various outdated deprecations 2023-10-09 09:14:55 +02:00
erik-krogh
c2942b37a7 JS: delete various outdated deprecations 2023-10-09 09:14:55 +02:00
erik-krogh
e0fefce2a3 Ruby: delete various deprecated predicates 2023-10-09 09:14:54 +02:00
erik-krogh
e3e8f3d7c4 Java: delete various outdated deprecations 2023-10-09 09:14:54 +02:00
erik-krogh
689eda4dae CPP: delete the deprecated AnalysedString class 2023-10-09 09:14:54 +02:00
erik-krogh
1c9f59e491 Python:delete deprecated files modelling web frameworks 2023-10-09 09:14:54 +02:00
erik-krogh
0d992a3d1f delete old deprecated aliases of various regex libraries 2023-10-09 09:14:54 +02:00
erik-krogh
28f8c1cc11 update doc example to not use isBarrierGuard 2023-10-09 09:14:51 +02:00
github-actions[bot]
7c332a31a8 Add changed framework coverage reports 2023-10-09 00:16:19 +00:00
Geoffrey White
8a7325268a Swift: Change note. 2023-10-07 23:19:24 +01:00
Geoffrey White
c492b5f2dd Swift: Model sinks. 2023-10-07 23:19:09 +01:00
Geoffrey White
8bf6fd67d1 Swift: Add a test for GRDB hardcoded key sinks. 2023-10-07 23:07:32 +01:00
erik-krogh
4bc4e0845d delete the deprecated isBarrierGuard predicate from the shared dataflow library, and its uses 2023-10-07 21:48:49 +02:00
erik-krogh
d261cec3cd add change-note 2023-10-07 15:41:08 +02:00
Marcono1234
f3e5045259 Java: Add predicate MemberRefExpr::getReceiverExpr 2023-10-07 14:53:07 +02:00
erik-krogh
56e9eda2b9 fix performance by caching getArgument 2023-10-07 13:06:45 +02:00
Marcono1234
2c0dcd3a2d Java: Adjust ClassInstanceExpr type argument predicates docs
The type arguments which these predicates have as result are for the
type of the created instance.

Previously the documentation said "provided to the constructor", which
is misleading / incorrect. Type arguments provided to the constructor
are specified directly after the `new` keyword:
```
class C {
    <T> C() {
    }
}

new <String> C();
```

And those are not part of the results of these predicates.
2023-10-07 03:43:58 +02:00
Eric Bickle
4dca396106 Add change notes for ThreadResourceAbuse ArithExpr fix 2023-10-06 14:31:37 -07:00
Eric Bickle
000c1f7ec8 Java: Flow taint through ArithExpr for ThreadResourceAbuse
Ensure that tainted values flow through arithmetic operations when
checking for ThreadResourceAbuse vulnerabilities.

For example, multiplying 'number of seconds' by 1000 as an input
to Thread.Sleep, which accepts milliseconds, is a common scenario.
2023-10-06 14:24:37 -07:00
erik-krogh
7ca0996912 add a taint-tracking tests for calls to tagged template strings 2023-10-06 21:39:42 +02:00
erik-krogh
9b6501787a add API-graph test for the new tagged template calls 2023-10-06 21:25:34 +02:00
Geoffrey White
0918e50b05 Swift: Switch pragma to inline_late. 2023-10-06 20:23:51 +01:00
erik-krogh
18e6a5491c recognize tagged templates as DataFlow::CallNode 2023-10-06 21:14:00 +02:00
erik-krogh
951ed01d6b combine the library-tests/CallGraphs/FullTest tests into one file 2023-10-06 20:57:09 +02:00
Geoffrey White
7c28528eac Swift: Change note. 2023-10-06 18:26:21 +01:00
Geoffrey White
676179620a Swift: Get sqlite3 C API results (model Data.withUnsafeBytes, Data.withUnsafeMutableBytes, permit flow out of collections at the query sink) 2023-10-06 18:26:20 +01:00
Geoffrey White
bc9d8cc40f Swift: Get another SQLite.swift result. 2023-10-06 18:26:20 +01:00
Geoffrey White
691665fca8 Swift: Add models for SQLite.swift. 2023-10-06 18:26:19 +01:00
Geoffrey White
bece2e8689 Swift: Add models for sqlite3 C API. 2023-10-06 18:26:19 +01:00
Geoffrey White
9a628d4165 Swift: Add test for sqlite3 C API. 2023-10-06 18:26:18 +01:00
Geoffrey White
8006996f46 Swift: Add test for SQLite.swift. 2023-10-06 18:26:18 +01:00
Robert Marsh
85587413d0 Swift: fix QLDoc formatting for getSequence 2023-10-06 15:29:56 +00:00
Robert Marsh
c281db6b5b Swift: improve QLDoc for getSequence 2023-10-06 15:23:58 +00:00
Robert Marsh
ec292ca4e1 Swift: Split for-each change note into two lines 2023-10-06 15:21:55 +00:00
amammad
7d36c23d59 fix qhelp and PascalCase issues 2023-10-06 16:14:10 +02:00
Jeroen Ketema
b6132d2a0f C++: Rewrite cpp/cgi-xss to not use default taint tracking 2023-10-06 16:11:13 +02:00
Michael Nebel
dca39348ab Java: Add change note. 2023-10-06 15:09:16 +02:00
Michael Nebel
fb10af9042 Jave: Remove the local threat model from the default configuration. 2023-10-06 14:58:48 +02:00
amammad
7d73808d60 fix a test mistake, add comments for JWT extension points 2023-10-06 13:31:09 +02:00
amammad
aa127b1662 do review improvements 2023-10-06 13:22:43 +02:00
Michael B. Gale
0b13da35eb Go: Update newer-go-version-needed test
- Use a version that is accepted by Go tooling
- Run is no longer successful with Go 1.21
2023-10-06 11:57:47 +01:00
Michael B. Gale
01a1d814f4 Do not call EmitNewerGoVersionNeeded for v1.21+ 2023-10-06 11:57:37 +01:00
Michael B. Gale
c63f6807c4 Go: Run go version with GOTOOLCHAIN=local 2023-10-06 11:57:26 +01:00
Michael B. Gale
76781e5d75 Go: Add GoVersionInfo type
Refactors `tryReadGoDirective` to return this instead of a pair.
This will make it easier to return multiple versions.
2023-10-06 11:57:08 +01:00
Mathias Vorreiter Pedersen
a08356979f Merge pull request #14382 from MathiasVP/deduplicate-why
C++: Project away `why` to prevent tuple duplication in `Buffer.qll`
2023-10-06 12:52:58 +02:00
Mathias Vorreiter Pedersen
eb3f1967a5 Merge pull request #14365 from MathiasVP/disable-flow-through-pointer-arith-for-size
C++: Disable size-flow through pointer arithmetics in `cpp/invalid-pointer-deref`
2023-10-06 10:14:31 +02:00
Asger F
97b3ebe385 Merge pull request #14380 from asgerf/js/amd-range
JS: Add AmdModuleDefinition::Range
2023-10-05 21:05:28 +02:00
Mathias Vorreiter Pedersen
b231b1ccaf Merge pull request #14384 from MathiasVP/handle-instructions-in-reverse-flow 2023-10-05 20:26:38 +02:00
Robert Marsh
bbec4082c0 Merge pull request #14312 from geoffw0/sqlpathinject2
Swift: Add sinks for sqlite3 and SQLite.swift to swift/cleartext-storage-database
2023-10-05 14:08:55 -04:00
Geoffrey White
66637e8c03 Swift: Autoformat. 2023-10-05 18:53:30 +01:00
Geoffrey White
81d4ec1e98 pragma node 2023-10-05 18:30:50 +01:00
Alex Eyers-Taylor
c79ec8c37a CPP: Improve performance of IR debugging 2023-10-05 17:35:52 +01:00
Geoffrey White
fdcc6b482d Swift: Simplify allowImplicitRead slightly. 2023-10-05 16:42:43 +01:00
Geoffrey White
7ddece1560 Swift: Update .expected after merge. 2023-10-05 16:20:56 +01:00
Geoffrey White
6bea7f89a8 Merge branch 'main' into sqlpathinject2 2023-10-05 16:15:37 +01:00
Cornelius Riemenschneider
d3a1dbc0c7 Merge pull request #14381 from github/criemen/add-bazel-dbschemes
Add skeleton bazel files for accessing the dbschemes.
2023-10-05 16:53:45 +02:00
Geoffrey White
e31ca58a2f Swift: Post-merge fix. 2023-10-05 15:45:22 +01:00
Geoffrey White
17894db501 Merge branch 'main' into conversions2 2023-10-05 15:33:05 +01:00
Mathias Vorreiter Pedersen
20900dafc0 C++: Handle reverse flow when 'nodeTo' is an instruction. 2023-10-05 16:28:57 +02:00
Michael Nebel
96f93cefba UNDO AGAIN: Add local threat models. 2023-10-05 16:16:00 +02:00
Ian Lynagh
e124a70380 Merge pull request #14378 from igfoo/igfoo/compr
Kotlin: Some compression simplification
2023-10-05 13:16:00 +01:00
Ian Lynagh
0cf309b64e Merge pull request #14369 from igfoo/igfoo/remove_unused
Kotlin: Remove some unused code
2023-10-05 13:15:20 +01:00
Mathias Vorreiter Pedersen
2f39ab1977 C++: Project away 'why' to prevent tuple duplication in 'Buffer.qll'. 2023-10-05 13:32:52 +02:00
Owen Mansel-Chan
602bb4083c Merge pull request #13949 from owen-mc/go/change-flowstate-for-incorrect-integer-conversion
Go: Improve incorrect integer conversion
2023-10-05 09:59:36 +01:00
Mathias Vorreiter Pedersen
333e607536 Merge pull request #14376 from MathiasVP/unique-in-hasIRRepresentationOfIndirectInstruction 2023-10-05 10:22:54 +02:00
Chris Smowton
399fab0c6c Merge pull request #14322 from smowton/smowton/admin/add-buildless-diagnostic-expectations
Add Java buildless diagnostic expectations
2023-10-05 09:02:02 +01:00
Cornelius Riemenschneider
96edc1d349 Add skeleton bazel files for accessing the dbschemes. 2023-10-05 09:00:38 +02:00
Asger F
315272839d JS: Change note 2023-10-05 08:13:43 +02:00
Robert Marsh
a402bfcfb0 Swift: update for-in change note 2023-10-04 20:05:11 +00:00
Robert Marsh
5dd7c14d36 Swift: add getSequence back to ForEachStmt 2023-10-04 20:05:00 +00:00
Asger F
162c477236 JS: Add AmdModuleDefinition::Range 2023-10-04 20:38:37 +02:00
Mathias Vorreiter Pedersen
e38f65981e C++: Accept test changes. 2023-10-04 20:12:42 +02:00
Ian Lynagh
4d3863461e Kotlin: Determine our compression method later
This way, we already have a logger at the point that we want to log a
warning.
2023-10-04 18:32:12 +01:00
Ian Lynagh
cc63bb55c2 Kotlin: Change how we handle not supporting Brotli
This removes the potential for impossible cases.
2023-10-04 18:32:11 +01:00
Mathias Vorreiter Pedersen
75c74d50f9 C++: Use 'unique' in 'hasIRRepresentationOfIndirectInstruction' similar to how it's done in 'hasIRRepresentationOfIndirectOperand'. 2023-10-04 19:00:33 +02:00
Edward Minnix III
8e653d01a8 Merge pull request #14127 from egregius313/egregius313/java/mad/localuserinput
Java: Convert implementations of `LocalUserInput` to Models-as-Data
2023-10-04 12:55:44 -04:00
Robert Marsh
9c3b72cf3f Swift: remove TODO comment 2023-10-04 15:59:12 +00:00
Robert Marsh
00068d6157 Merge branch 'main' into rdmarsh2/swift/for-in
Fix conflict in AST test output
2023-10-04 15:58:36 +00:00
Ed Minnix
e2a14c7616 Add note about results to change note 2023-10-04 11:08:40 -04:00
Owen Mansel-Chan
11b92608c7 Add ".md" to the change note filename 2023-10-04 15:49:10 +01:00
Owen Mansel-Chan
ab07a38c25 Use ternary type for architecture bit size 2023-10-04 15:43:51 +01:00
Owen Mansel-Chan
015519e9e0 Combine isBoundFor and isBoundFor2 2023-10-04 15:31:00 +01:00
Owen Mansel-Chan
cd40663ca4 Address lots of review comments 2023-10-04 15:24:56 +01:00
Henry Mercer
74368540ae Merge pull request #14375 from github/release-prep/2.15.0
Release preparation for version 2.15.0
2023-10-04 15:18:55 +01:00
github-actions[bot]
9fe993bec3 Release preparation for version 2.15.0 2023-10-04 14:15:27 +00:00
Robert Marsh
b5f1296cc2 Swift: Use getFullyConverted in CFG generation
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-10-04 09:44:48 -04:00
Robert Marsh
f7ca8e5b39 Merge pull request #14224 from rdmarsh2/rdmarsh2/swift/nil-coalescing-cfg
Swift: CFG and data flow for nil coalescing operator
2023-10-04 09:43:31 -04:00
Owen Mansel-Chan
4122fd881f Move UpperBoundCheckGuard 2023-10-04 14:17:00 +01:00
Mathias Vorreiter Pedersen
843e9ad254 C++: Add more QLDoc. 2023-10-04 14:37:05 +02:00
Michael Nebel
40e63a63e2 Java: Re-factor most queries and tests to use threat models. 2023-10-04 14:01:58 +02:00
amammad
0f5dd40ff1 fix beego tests 2023-10-04 13:41:26 +02:00
amammad
0c2275ddb1 fix Gin tests 2023-10-04 12:57:15 +02:00
Owen Mansel-Chan
3703c5626f Merge pull request #14364 from owen-mc/go/improve-output-of-check-formatting-in-makefile
Go: improve output of check formatting in makefile
2023-10-04 11:54:40 +01:00
amammad
c3a21daf83 fix Echo tests 2023-10-04 12:54:34 +02:00
amammad
06ec3bbbb5 fix beego tests 2023-10-04 12:52:59 +02:00
Rasmus Wriedt Larsen
9c02b4f21c Merge pull request #14289 from microsoft/jb1/16-cryptography-models-libraries-and-queries-migration
16 cryptography models libraries and queries migration
2023-10-04 12:27:59 +02:00
Ian Lynagh
ec3f08037c Kotlin: Remove some unused code 2023-10-04 11:15:47 +01:00
Owen Mansel-Chan
bd2c49fcf0 Improve message 2023-10-04 11:07:19 +01:00
Owen Mansel-Chan
567052f35e Keep line breaks in list of files formatting 2023-10-04 10:23:29 +01:00
Michael Nebel
f0fb065446 Java: Opt-in the SQL injection query to use threat model flow sources. 2023-10-04 10:51:07 +02:00
Michael Nebel
5fd6dc3b87 Java: Opt-in the XSS query to use threat model flow sources. 2023-10-04 10:48:09 +02:00
BD
31550b22b6 Merge branch 'main' into enable-gokit-by-default 2023-10-04 12:42:09 +05:30
Ed Minnix
581d410304 Add change note 2023-10-03 22:29:00 -04:00
Ed Minnix
e122d81336 Add new source kinds for threat modeling 2023-10-03 22:29:00 -04:00
Edward Minnix III
a1d3667f1c Refactor Hudson file methods to MaD 2023-10-03 22:28:59 -04:00
Edward Minnix III
3a75c0fde7 Refactor DatabaseInput to MaD 2023-10-03 22:28:59 -04:00
Edward Minnix III
655470f3da Refactor EnvInput to MaD 2023-10-03 22:28:47 -04:00
Josh Brown
de2e8b0b12 explicit "this" qualifiers 2023-10-03 16:13:54 -07:00
Josh Brown
ad86e576a4 autoformat 2023-10-03 13:40:17 -07:00
Josh Brown
b683a3caf8 Merge branch 'main' into jb1/16-cryptography-models-libraries-and-queries-migration 2023-10-04 07:24:29 +11:00
Robert Marsh
06da5fd05c Swift: move import to make codegen happy 2023-10-03 17:23:00 +00:00
amammad
22c4b5113d do gofmt 2023-10-03 18:29:34 +02:00
Robert Marsh
cdef0796e3 Swift: QLDoc for NilCoalescingExpr.qll 2023-10-03 15:00:03 +00:00
Robert Marsh
497f0aa8ab Swift: sync test files and update expectation 2023-10-03 14:57:04 +00:00
Mathias Vorreiter Pedersen
9a139ea903 C++: Accept test changes. 2023-10-03 15:58:35 +02:00
Mathias Vorreiter Pedersen
57d3f3f482 C++: Actually propagate the 'isBarrier1' or 'isBarrier2' predicates to the dataflow configurations. 2023-10-03 15:58:24 +02:00
Mathias Vorreiter Pedersen
9df5e43fae C++: Block flow through indirect flow through pointer-arithmetic instructions when following flow for the allocation size. 2023-10-03 15:31:50 +02:00
Owen Mansel-Chan
7c8233aade Add change note 2023-10-03 13:35:26 +01:00
Owen Mansel-Chan
5433636d49 Fix formatting errors in files included in qhelp 2023-10-03 12:48:03 +01:00
Owen Mansel-Chan
2a52455619 Improve output of check-formatting in Makefile
The list of files that would change when reformatted is now printed.
Also, parsing errors now make the check fail.
2023-10-03 12:48:01 +01:00
Bharadwaj Machiraju
53a291aeae Remove GoKit from untrusted flow sources test 2023-10-03 15:39:52 +05:30
Bharadwaj Machiraju
6c8ae55a68 Enable GoKit module into the default list 2023-10-03 15:39:52 +05:30
Geoffrey White
0f1711fe1e Swift: Test insertMany. 2023-10-02 23:04:07 +01:00
Robert Marsh
ca722dc74c Swift: add NilCoalescingTest node to CFG
Fixes an issue where a nil-coalescing operation used in a boolean
context would result in no control flow out of the default operand of
the nil-coalescing operator.
2023-10-02 18:07:11 +00:00
Geoffrey White
db5e0ff7a8 Swift: Autoformat. 2023-10-02 16:06:38 +01:00
Geoffrey White
3d552d7d5d Swift: Simplify FloatPoint model now that it works to do so. 2023-10-02 11:59:26 +01:00
Geoffrey White
3265d49a98 Swift: Remove duplicate row. 2023-10-02 11:59:26 +01:00
Geoffrey White
f83456a398 Swift: Change note. 2023-10-02 11:59:25 +01:00
Geoffrey White
c61edc13e7 Swift: Model RangeReplaceableCollection initializers. 2023-10-02 11:59:25 +01:00
Geoffrey White
0c534b69eb Swift: Extend Numeric models. 2023-10-02 11:59:25 +01:00
Geoffrey White
2863a14cd1 Swift: Add more tests for Arrays. 2023-10-02 11:59:24 +01:00
Geoffrey White
df1bc1a597 Swift: Add more tests for Numerics. 2023-10-02 11:59:24 +01:00
amammad
95363455af fix tests, and review suggestions. 2023-09-30 22:50:08 +10:00
amammad
f0f60c3b7d move JWT.qll to experimental 2023-09-30 22:30:30 +10:00
erik-krogh
5d4b542995 escape unicode chars in overly-large-range 2023-09-28 20:16:09 +02:00
amammad
8d47a7b21d Update python/ql/lib/semmle/python/security/dataflow/PathInjectionQuery.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-09-28 18:13:34 +03:30
Owen Mansel-Chan
832e78c518 Unify approach to architecture bit size in isSink2 2023-09-28 11:24:48 +01:00
Owen Mansel-Chan
cf5d1e36fe Add QLDoc 2023-09-28 11:02:04 +01:00
Owen Mansel-Chan
e0b61b2d68 Reduce the number of UpperBoundChecks
No need to have a separate class for each state
being blocked.
2023-09-28 11:00:43 +01:00
Owen Mansel-Chan
c0b579c49f Improve tests 2023-09-28 11:00:41 +01:00
Owen Mansel-Chan
7d34ce4dea Rewrite with different flow state 2023-09-28 11:00:34 +01:00
Rasmus Wriedt Larsen
f3acc89900 Python: Accept .expected 2023-09-28 10:41:16 +02:00
Robert Marsh
77fd9172fa Swift: Fix extra param in downgrade script 2023-09-27 20:55:08 +00:00
Robert Marsh
64e4c1ea6d Swift: remove another table from downgrade script 2023-09-27 20:52:06 +00:00
Robert Marsh
d71d6b265a Swift: remove table from downgrade properties 2023-09-27 20:50:21 +00:00
Robert Marsh
4799ba0069 Swift: yet another downgrade script fix 2023-09-27 20:47:45 +00:00
Robert Marsh
188ad6a571 Swift: another attempt at fixing downgrade script 2023-09-27 20:07:26 +00:00
Robert Marsh
9975a18a29 Swift: Hopefully fix codegen test failure 2023-09-27 20:06:13 +00:00
Robert Marsh
a7a50cfc9a Swift: more downgrade script fixes 2023-09-27 18:01:17 +00:00
Benjamin Rodes
25203db4e7 Removing 'security' tags from all queries. 2023-09-27 12:43:51 -04:00
Owen Mansel-Chan
84c0c09673 Always use getters for FlowState 2023-09-27 17:13:58 +01:00
Owen Mansel-Chan
72ca6b8c5f Add isSigned to IntegerParsers 2023-09-27 17:13:56 +01:00
Owen Mansel-Chan
c796cba02f Improve UpperBoundCheckGuard.isBoundFor 2023-09-27 17:13:55 +01:00
amammad
7d5bbc3b1e put each new sink in its own framework 2023-09-28 01:02:05 +10:00
amammad
9598bb5a68 stash 2023-09-27 23:22:29 +10:00
amammad
c6ad358751 fix package FPs, fix additioanlstep issue 2023-09-27 21:11:07 +10:00
amammad
c78f390128 add go generate support, upgrade JWT.qll 2023-09-27 20:17:31 +10:00
amammad
73803eaac9 fix tests
add missed afero sinks
2023-09-27 06:27:05 +10:00
Robert Marsh
50521f7b45 Swift: fix ql reference in downgrade script 2023-09-26 20:08:23 +00:00
amammad
cea44e2bee added the go generate commands for depstubber 2023-09-27 05:22:52 +10:00
amammad
3febbec64e fix qldoc and review suggestions 2023-09-27 05:16:35 +10:00
Robert Marsh
81ee932e62 Swift: Fix db types in downgrade script for for-in 2023-09-26 18:03:08 +00:00
Robert Marsh
293400a623 Swift: change note for for-in dataflow 2023-09-26 15:13:05 +00:00
Robert Marsh
ae1072e09f Merge branch 'main' into rdmarsh2/swift/for-in 2023-09-26 15:12:46 +00:00
Chris Smowton
a123f62a38 Add Java buildless diagnostic expectations 2023-09-26 15:25:58 +01:00
Robert Marsh
811c33b016 Swift: finish downgrade script for for-in PR 2023-09-25 20:23:43 +00:00
Robert Marsh
92fdb7a35f Swift: finish upgrade script for for-in PR 2023-09-25 20:13:52 +00:00
Geoffrey White
f9a617c714 Swift: Change note. 2023-09-25 20:31:00 +01:00
Geoffrey White
51ed824adf Swift: Add more SQLite.swift models. 2023-09-25 20:30:59 +01:00
Geoffrey White
6be01eac04 Swift: Add implict read steps for dictionary content. 2023-09-25 20:30:59 +01:00
Geoffrey White
4350060b0f Swift: Add SQLite.swift models. 2023-09-25 20:30:59 +01:00
Geoffrey White
839b9635b9 Swift: Effect of fixing string interpolation bug. 2023-09-25 20:30:58 +01:00
Geoffrey White
16ae637238 Swift: Add sqlite3 models. 2023-09-25 20:30:48 +01:00
Geoffrey White
4245a38de9 Swift: Add SQLite.swift and sqlite3 C API test cases for swift/cleartext-storage-database. 2023-09-25 20:30:48 +01:00
amammad
fd0d194a8a add changenote 2023-09-26 05:26:00 +10:00
amammad
b7f874d1f1 fix tests, better afero support! 2023-09-26 05:04:25 +10:00
amammad
c5faddc2a4 remove fasthttp in favor or fasthttp framework 2023-09-26 03:01:51 +10:00
amammad
9f9c9e0e5e fix issues according to codereview 2023-09-26 02:06:57 +10:00
amammad
e239d763dc Merge branch 'main' into amammad-go-NewFileSystemAccess 2023-09-26 02:04:59 +10:00
Rasmus Wriedt Larsen
05ab28f11d autoformat 2023-09-25 10:35:18 +02:00
Rasmus Wriedt Larsen
db7b1eea55 Merge branch 'main' into maikypedia/python-unsafe-deserialization 2023-09-25 10:29:18 +02:00
Rasmus Wriedt Larsen
f515559e56 Python: Sort Frameworks.qll 2023-09-25 10:25:43 +02:00
Rasmus Wriedt Larsen
a45e10d64f Python: Slight rewrite of numpy test
To use positional argument for allow_pickle
2023-09-25 10:25:11 +02:00
Rasmus Wriedt Larsen
56d99fbd8a Add numpy reference 2023-09-25 10:24:53 +02:00
Rasmus Wriedt Larsen
d1caa75053 Python: Fix format for pandas.read_pickle 2023-09-25 10:24:27 +02:00
Robert Marsh
8ce79e6be8 Swift: for-in downgrade script 2023-09-22 19:12:27 +00:00
Robert Marsh
325d6f738c Swift: add expr types to for-in upgrade script 2023-09-22 18:14:37 +00:00
Robert Marsh
5b77e7db8a Swift: for-in upgrade script passing CFG test 2023-09-22 17:44:45 +00:00
Harry Maclean
2214caef4b Ruby: Identify named graphql params as sources 2023-09-22 17:54:55 +01:00
Josh Brown
7ad2932b3f Update SymmetricEncryptionAlgorithms.ql
Changing metadata to under python namespace
2023-09-21 12:12:16 -07:00
Benjamin Rodes
c0c2ae544b Updating weak elliptic curve sample queries. 2023-09-21 12:12:16 -07:00
Benjamin Rodes
5fed923af0 Changed python inventory subdirectory structure to add old and new inventory models. Added some example old models. 2023-09-21 12:12:15 -07:00
Benjamin Rodes
50db4fd63e Moved Cpp into sub directory 'cryptography' instead of crypto. Added python models, inventory, and example alerts. 2023-09-21 12:12:15 -07:00
Benjamin Rodes
7560db66fa incorrect import path 2023-09-21 12:12:15 -07:00
Benjamin Rodes
fe22dc45b1 Moving inventory queries into a new subdirectory structure for new_models and old_models. 2023-09-21 12:12:15 -07:00
Benjamin Rodes
6d7ac8de28 Adding example alerts 2023-09-21 12:12:15 -07:00
Benjamin Rodes
4c9cc5a21f Adding inventory queries. 2023-09-21 12:12:15 -07:00
Benjamin Rodes
7256faa7eb Added modeling infrastructure 2023-09-21 12:12:15 -07:00
Robert Marsh
30b30695e4 Swift: WIP upgrade script for for-each refactor 2023-09-19 19:28:05 +00:00
amammad
da864bf7f7 fix QLDoc 2023-09-19 22:19:18 +10:00
amammad
a96b0011f0 clean tests 2023-09-19 22:12:10 +10:00
amammad
1e12a86781 Merge branch 'main' into amammad-go-JWT 2023-09-19 22:01:50 +10:00
amammad
2136929164 clean tests 2023-09-19 22:01:40 +10:00
amammad
bc6a0fc776 move to CWE-347 2023-09-19 07:15:46 +10:00
Harry Maclean
2053ee00ab Ruby: Add change note 2023-09-18 16:02:09 +01:00
Harry Maclean
18dac9ab8a Ruby: Handle GraphQL array types 2023-09-18 16:00:56 +01:00
Maiky
1764aa0caf Fixing NumpyLoadCall 2023-09-17 19:44:48 +02:00
Maiky
8254d0dd10 Naming error
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-09-17 18:53:48 +02:00
Maiky
6d0ba5f97b Add allow_pickle to tests
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-09-17 18:53:18 +02:00
Maiky
70103967ef Doc changes
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-09-17 18:47:19 +02:00
Maiky
cada523031 Remove unnecessary import
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-09-17 18:46:13 +02:00
Robert Marsh
2b54ad58b0 Swift: change note for nil-coalesing operator 2023-09-15 20:44:05 +00:00
amammad
52d1e45b05 add comments for better quality 2023-09-15 23:25:25 +10:00
Harry Maclean
5706bc6205 Ruby: Model GraphQL InputObject arguments 2023-09-14 19:02:39 +01:00
Robert Marsh
eddca7f3f6 Swift: autoformat for for-in changes 2023-09-14 16:48:19 +00:00
Robert Marsh
ab7cd5254a Swift: update dataflow test for nil coalescing 2023-09-14 16:28:00 +00:00
Robert Marsh
9a5fa42dbe Swift: CFG for nil coalescing operator 2023-09-14 16:16:30 +00:00
Robert Marsh
56b646a74c Merge branch 'main' into rdmarsh2/swift/for-in 2023-09-14 14:14:06 +00:00
Robert Marsh
dd01da4938 Swift: AST and CFG tests for nil coalescing 2023-09-14 13:26:41 +00:00
Harry Maclean
5411123b8a Ruby: Fix GraphQL test 2023-09-14 14:14:26 +01:00
Harry Maclean
57ae1ee3e9 Ruby: Add test for GraphQL remote flow sources 2023-09-14 13:46:52 +01:00
Harry Maclean
1526fff085 Ruby: Add missing doc comments 2023-09-14 13:46:37 +01:00
Harry Maclean
20f1a74202 Ruby: Restrict GraphQL remote flow sources
Previously we considered any splat parameter in a graphql resolver to be
a remote flow source. Now we limit that to reads of the parameter which
yield scalar types (e.g. String), as defined by the GraphQL schema.

This should reduce GraphQL false positives.
2023-09-14 12:14:56 +01:00
Robert Marsh
e0fae764f1 Swift: move IteratorProtocol model to its own file 2023-09-13 20:09:17 +00:00
Robert Marsh
7ca6b6f9a6 Swift: add dataflow test for async for 2023-09-12 19:05:03 +00:00
Robert Marsh
53ad559da5 Swift: fix for-try-await CFG 2023-09-12 19:04:30 +00:00
Robert Marsh
988a871999 Swift: add flow through for-in loops 2023-09-08 20:00:27 +00:00
Robert Marsh
a3e250aef5 Swift: extract iterator variable for for-in loops 2023-09-08 19:08:57 +00:00
Robert Marsh
50d23f145b merge main into for-in getnextcall branch 2023-09-08 15:51:27 +00:00
amammad
f3ea72c234 proper tests with depstubber, remove Duplicates :( 2023-09-03 04:51:05 +10:00
amammad
40ff16bdaf Merge branch 'main' into amammad-go-JWT 2023-08-29 20:02:57 +10:00
amammad
68392e7ae7 V1 2023-08-28 22:23:51 +10:00
amammad
25c60c455e v1 2023-08-27 23:53:45 +10:00
Alex Denisov
b657301d39 Swift: update test expectations 2023-08-22 18:03:19 +02:00
Alex Denisov
e9fdbfabea Swift: extract nextCall from ForEachStmt 2023-08-22 17:36:40 +02:00
Maiky
6274dfafdc typo
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-07-27 23:43:48 +02:00
Maiky
49aa3eb92b Update change note
Co-authored-by: Jorge <46056498+jorgectf@users.noreply.github.com>
2023-07-27 23:43:39 +02:00
Maiky
6d6a243776 Update Change Note 2023-07-20 12:33:26 +02:00
Maiky
1a1fee3088 Doc change 2023-07-20 03:28:13 +02:00
Maiky
a1782182dd Python: Add unsafe deserialization sinks (CWE-502) 2023-07-20 03:26:22 +02:00
1060 changed files with 64391 additions and 9634 deletions

View File

@@ -17,3 +17,10 @@ updates:
ignore:
- dependency-name: '*'
update-types: ['version-update:semver-patch', 'version-update:semver-minor']
- package-ecosystem: "gomod"
directory: "go/extractor"
schedule:
interval: "daily"
reviewers:
- "github/codeql-go"

View File

@@ -29,9 +29,9 @@ jobs:
# run with --check-only if running in a PR (github.sha != main)
if : ${{ github.event_name == 'pull_request' }}
shell: bash
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500
- name: compile queries - full
# do full compile if running on main - this populates the cache
if : ${{ github.event_name != 'pull_request' }}
shell: bash
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500

View File

@@ -91,7 +91,7 @@ jobs:
run: |
# Generate (Asp)NetCore stubs
STUBS_PATH=stubs_output
python3 ql/src/Stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger latest "$STUBS_PATH"
python3 ql/src/Stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH"
rm -rf ql/test/resources/stubs/_frameworks
# Update existing stubs in the repo with the freshly generated ones
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/

View File

@@ -498,22 +498,6 @@
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsExtensions.qll",
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsExtensions.qll"
],
"TaintedFormatStringQuery Ruby/JS": [
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll"
],
"TaintedFormatStringCustomizations Ruby/JS": [
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringCustomizations.qll",
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringCustomizations.qll"
],
"HttpToFileAccessQuery JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll",
"ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll"
],
"HttpToFileAccessCustomizations JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessCustomizations.qll",
"ruby/ql/lib/codeql/ruby/security/HttpToFileAccessCustomizations.qll"
],
"Typo database": [
"javascript/ql/src/Expressions/TypoDatabase.qll",
"ql/ql/src/codeql_ql/style/TypoDatabase.qll"

View File

@@ -1,12 +1,17 @@
package(default_visibility = ["//visibility:public"])
load("@rules_pkg//:mappings.bzl", "pkg_filegroup")
package(default_visibility = ["//visibility:public"])
alias(
name = "dbscheme",
actual = "//cpp/ql/lib:dbscheme",
)
alias(
name = "dbscheme-stats",
actual = "//cpp/ql/lib:dbscheme-stats",
)
pkg_filegroup(
name = "db-files",
srcs = [

View File

@@ -1,7 +1,7 @@
package(default_visibility = ["//cpp:__pkg__"])
load("@rules_pkg//:mappings.bzl", "pkg_files")
package(default_visibility = ["//cpp:__pkg__"])
pkg_files(
name = "dbscheme",
srcs = ["semmlecode.cpp.dbscheme"],

View File

@@ -1,3 +1,13 @@
## 0.10.0
### Minor Analysis Improvements
* Functions that do not return due to calling functions that don't return (e.g. `exit`) are now detected as
non-returning in the IR and dataflow.
* Treat functions that reach the end of the function as returning in the IR.
They used to be treated as unreachable but it is allowed in C.
* The `DataFlow::asDefiningArgument` predicate now takes its argument from the range starting at `1` instead of `2`. Queries that depend on the single-parameter version of `DataFlow::asDefiningArgument` should have their arguments updated accordingly.
## 0.9.3
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `DataFlow::asDefiningArgument` predicate now takes its argument from the range starting at `1` instead of `2`. Queries that depend on the single-parameter version of `DataFlow::asDefiningArgument` should have their arguments updated accordingly.

View File

@@ -1,5 +0,0 @@
---
category: minorAnalysis
---
* Treat functions that reach the end of the function as returning in the IR.
They used to be treated as unreachable but it is allowed in C.

View File

@@ -1,5 +0,0 @@
---
category: minorAnalysis
---
* Functions that do not return due to calling functions that don't return (e.g. `exit`) are now detected as
non-returning in the IR and dataflow.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Deleted the deprecated `AnalysedString` class, use the new name `AnalyzedString`.
* Deleted the deprecated `isBarrierGuard` predicate from the dataflow library and its uses, use `isBarrier` and the `BarrierGuard` module instead.

View File

@@ -0,0 +1,9 @@
## 0.10.0
### Minor Analysis Improvements
* Functions that do not return due to calling functions that don't return (e.g. `exit`) are now detected as
non-returning in the IR and dataflow.
* Treat functions that reach the end of the function as returning in the IR.
They used to be treated as unreachable but it is allowed in C.
* The `DataFlow::asDefiningArgument` predicate now takes its argument from the range starting at `1` instead of `2`. Queries that depend on the single-parameter version of `DataFlow::asDefiningArgument` should have their arguments updated accordingly.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.9.3
lastReleaseVersion: 0.10.0

View File

@@ -0,0 +1,3 @@
import experimental.cryptography.CryptoArtifact
import experimental.cryptography.CryptoAlgorithmNames
import experimental.cryptography.modules.OpenSSL as OpenSSL

View File

@@ -0,0 +1,239 @@
/**
* Names of known cryptographic algorithms.
* The names are standardized into upper-case, no spaces, dashes or underscores.
*/
/**
* Returns a string to represent generally unknown algorithms.
* Predicate is to be used to get a consistent string representation
* for unknown algorithms.
*/
string unknownAlgorithm() { result = "UNKNOWN" }
string getHashType() { result = "HASH" }
string getSymmetricEncryptionType() { result = "SYMMETRIC_ENCRYPTION" }
string getAsymmetricEncryptionType() { result = "ASYMMETRIC_ENCRYPTION" }
string getKeyDerivationType() { result = "KEY_DERIVATION" }
string getCipherBlockModeType() { result = "BLOCK_MODE" }
string getSymmetricPaddingType() { result = "SYMMETRIC_PADDING" }
string getAsymmetricPaddingType() { result = "ASYMMETRIC_PADDING" }
string getEllipticCurveType() { result = "ELLIPTIC_CURVE" }
string getSignatureType() { result = "SIGNATURE" }
string getKeyExchangeType() { result = "KEY_EXCHANGE" }
string getAsymmetricType() {
result in [
getAsymmetricEncryptionType(), getSignatureType(), getKeyExchangeType(),
getEllipticCurveType()
]
}
predicate isKnownType(string algType) {
algType in [
getHashType(), getSymmetricEncryptionType(), getAsymmetricEncryptionType(),
getKeyDerivationType(), getCipherBlockModeType(), getSymmetricPaddingType(),
getAsymmetricPaddingType(), getEllipticCurveType(), getSignatureType(), getKeyExchangeType()
]
}
predicate isKnownAlgorithm(string name) { isKnownAlgorithm(name, _) }
predicate isKnownAlgorithm(string name, string algType) {
isHashingAlgorithm(name) and algType = "HASH"
or
isEncryptionAlgorithm(name, algType) and
algType in ["SYMMETRIC_ENCRYPTION", "ASYMMETRIC_ENCRYPTION"]
or
isKeyDerivationAlgorithm(name) and algType = "KEY_DERIVATION"
or
isCipherBlockModeAlgorithm(name) and algType = "BLOCK_MODE"
or
isPaddingAlgorithm(name, algType) and algType in ["SYMMETRIC_PADDING", "ASYMMETRIC_PADDING"]
or
isEllipticCurveAlgorithm(name) and algType = "ELLIPTIC_CURVE"
or
isSignatureAlgorithm(name) and algType = "SIGNATURE"
or
isKeyExchangeAlgorithm(name) and algType = "KEY_EXCHANGE"
}
/**
* Holds if `name` is a known hashing algorithm in the model/library.
*/
predicate isHashingAlgorithm(string name) {
name =
[
"BLAKE2", "BLAKE2B", "BLAKE2S", "SHA2", "SHA224", "SHA256", "SHA384", "SHA512", "SHA512224",
"SHA512256", "SHA3", "SHA3224", "SHA3256", "SHA3384", "SHA3512", "SHAKE128", "SHAKE256",
"SM3", "WHIRLPOOL", "POLY1305", "HAVEL128", "MD2", "MD4", "MD5", "PANAMA", "RIPEMD",
"RIPEMD128", "RIPEMD256", "RIPEMD160", "RIPEMD320", "SHA0", "SHA1", "SHA", "MGF1", "MGF1SHA1",
"MDC2", "SIPHASH"
]
}
predicate isEncryptionAlgorithm(string name, string algType) {
isAsymmetricEncryptionAlgorithm(name) and algType = "ASYMMETRIC_ENCRYPTION"
or
isSymmetricEncryptionAlgorithm(name) and algType = "SYMMETRIC_ENCRYPTION"
}
predicate isEncryptionAlgorithm(string name) { isEncryptionAlgorithm(name, _) }
/**
* Holds if `name` corresponds to a known symmetric encryption algorithm.
*/
predicate isSymmetricEncryptionAlgorithm(string name) {
// NOTE: AES is meant to caputure all possible key lengths
name =
[
"AES", "AES128", "AES192", "AES256", "ARIA", "BLOWFISH", "BF", "ECIES", "CAST", "CAST5",
"CAMELLIA", "CAMELLIA128", "CAMELLIA192", "CAMELLIA256", "CHACHA", "CHACHA20",
"CHACHA20POLY1305", "GOST", "GOSTR34102001", "GOSTR341094", "GOSTR341194", "GOST2814789",
"GOSTR341194", "GOST2814789", "GOST28147", "GOSTR341094", "GOST89", "GOST94", "GOST34102012",
"GOST34112012", "IDEA", "RABBIT", "SEED", "SM4", "DES", "DESX", "3DES", "TDES", "2DES",
"DES3", "TRIPLEDES", "TDEA", "TRIPLEDEA", "ARC2", "RC2", "ARC4", "RC4", "ARCFOUR", "ARC5",
"RC5", "MAGMA", "KUZNYECHIK"
]
}
/**
* Holds if `name` corresponds to a known key derivation algorithm.
*/
predicate isKeyDerivationAlgorithm(string name) {
name =
[
"ARGON2", "CONCATKDF", "CONCATKDFHASH", "CONCATKDFHMAC", "KBKDFCMAC", "BCRYPT", "HKDF",
"HKDFEXPAND", "KBKDF", "KBKDFHMAC", "PBKDF1", "PBKDF2", "PBKDF2HMAC", "PKCS5", "SCRYPT",
"X963KDF", "EVPKDF"
]
}
/**
* Holds if `name` corresponds to a known cipher block mode
*/
predicate isCipherBlockModeAlgorithm(string name) {
name = ["CBC", "GCM", "CCM", "CFB", "OFB", "CFB8", "CTR", "OPENPGP", "XTS", "EAX", "SIV", "ECB"]
}
/**
* Holds if `name` corresponds to a known padding algorithm
*/
predicate isPaddingAlgorithm(string name, string algType) {
isSymmetricPaddingAlgorithm(name) and algType = "SYMMETRIC_PADDING"
or
isAsymmetricPaddingAlgorithm(name) and algType = "ASYMMETRIC_PADDING"
}
/**
* holds if `name` corresponds to a known symmetric padding algorithm
*/
predicate isSymmetricPaddingAlgorithm(string name) { name = ["PKCS7", "ANSIX923"] }
/**
* Holds if `name` corresponds to a known asymmetric padding algorithm
*/
predicate isAsymmetricPaddingAlgorithm(string name) { name = ["OAEP", "PKCS1V15", "PSS", "KEM"] }
predicate isBrainpoolCurve(string curveName, int keySize) {
// ALL BRAINPOOL CURVES
keySize in [160, 192, 224, 256, 320, 384, 512] and
(
curveName = "BRAINPOOLP" + keySize.toString() + "R1"
or
curveName = "BRAINPOOLP" + keySize.toString() + "T1"
)
}
predicate isSecCurve(string curveName, int keySize) {
// ALL SEC CURVES
keySize in [112, 113, 128, 131, 160, 163, 192, 193, 224, 233, 239, 256, 283, 384, 409, 521, 571] and
exists(string suff | suff in ["R1", "R2", "K1"] |
curveName = "SECT" + keySize.toString() + suff or
curveName = "SECP" + keySize.toString() + suff
)
}
predicate isC2Curve(string curveName, int keySize) {
// ALL C2 CURVES
keySize in [163, 176, 191, 208, 239, 272, 304, 359, 368, 431] and
exists(string pre, string suff |
pre in ["PNB", "ONB", "TNB"] and suff in ["V1", "V2", "V3", "V4", "V5", "W1", "R1"]
|
curveName = "C2" + pre + keySize.toString() + suff
)
}
predicate isPrimeCurve(string curveName, int keySize) {
// ALL PRIME CURVES
keySize in [192, 239, 256] and
exists(string suff | suff in ["V1", "V2", "V3"] | curveName = "PRIME" + keySize.toString() + suff)
}
predicate isEllipticCurveAlgorithm(string curveName) { isEllipticCurveAlgorithm(curveName, _) }
/**
* Holds if `name` corresponds to a known elliptic curve.
*/
predicate isEllipticCurveAlgorithm(string curveName, int keySize) {
isSecCurve(curveName, keySize)
or
isBrainpoolCurve(curveName, keySize)
or
isC2Curve(curveName, keySize)
or
isPrimeCurve(curveName, keySize)
or
curveName = "ES256" and keySize = 256
or
curveName = "CURVE25519" and keySize = 255
or
curveName = "X25519" and keySize = 255
or
curveName = "ED25519" and keySize = 255
or
curveName = "CURVE448" and keySize = 448 // TODO: need to check the key size
or
curveName = "ED448" and keySize = 448
or
curveName = "X448" and keySize = 448
or
curveName = "NUMSP256T1" and keySize = 256
or
curveName = "NUMSP384T1" and keySize = 384
or
curveName = "NUMSP512T1" and keySize = 512
or
curveName = "SM2" and keySize in [256, 512]
}
/**
* Holds if `name` corresponds to a known signature algorithm.
*/
predicate isSignatureAlgorithm(string name) {
name =
[
"DSA", "ECDSA", "EDDSA", "ES256", "ES256K", "ES384", "ES512", "ED25519", "ED448", "ECDSA256",
"ECDSA384", "ECDSA512"
]
}
/**
* Holds if `name` is a key exchange algorithm.
*/
predicate isKeyExchangeAlgorithm(string name) {
name = ["ECDH", "DH", "DIFFIEHELLMAN", "X25519", "X448"]
}
/**
* Holds if `name` corresponds to a known asymmetric encryption.
*/
predicate isAsymmetricEncryptionAlgorithm(string name) { name = ["RSA"] }

View File

@@ -0,0 +1,316 @@
import cpp
private import experimental.cryptography.CryptoAlgorithmNames
import semmle.code.cpp.ir.dataflow.TaintTracking
/*
* A cryptographic artifact is a DataFlow::Node associated with some
* operation, algorithm, or any other aspect of cryptography.
*/
abstract class CryptographicArtifact extends Expr { }
// /**
// * Associates a symmetric encryption algorithm with a block mode.
// * The DataFlow::Node representing this association should be the
// * point where the algorithm and block mode are combined.
// * This may be at the call to encryption or in the construction
// * of an object prior to encryption.
// */
// abstract class SymmetricCipher extends CryptographicArtifact{
// abstract SymmetricEncryptionAlgorithm getEncryptionAlgorithm();
// abstract BlockMode getBlockMode();
// final predicate hasBlockMode(){
// exists(this.getBlockMode())
// }
// }
// /**
// * A cryptographic operation is a method call that invokes a cryptographic
// * algorithm (encrypt/decrypt) or a function in support of a cryptographic algorithm
// * (key generation).
// *
// * Since operations are related to or in support of algorithms, operations must
// * provide a reference to their associated algorithm. Often operataions themselves
// * encapsulate algorithms, so operations can also extend CryptographicAlgorithm
// * and refer to themselves as the target algorithm.
// */
// abstract class CryptographicOperation extends CryptographicArtifact, Call{
// // bindingset[paramName, ind]
// // final DataFlow::Node getParameterSource(int ind, string paramName){
// // result = Utils::getUltimateSrcFromApiNode(this.(API::CallNode).getParameter(ind, paramName))
// // }
// final string getAlgorithmName(){
// if exists(this.getAlgorithm().getName())
// then result = this.getAlgorithm().getName()
// else result = unknownAlgorithm()
// }
// final predicate hasAlgorithm(){
// exists(this.getAlgorithm())
// }
// final predicate isUnknownAlgorithm(){
// this.getAlgorithmName() = unknownAlgorithm()
// or
// not this.hasAlgorithm()
// }
// // TODO: this might have to be parameterized by a configuration source for
// // situations where an operation is passed an algorithm
// abstract CryptographicAlgorithm getAlgorithm();
// }
// /** A key generation operation for asymmetric keys */
// abstract class KeyGen extends CryptographicOperation{
// int getAKeySizeInBits(){
// result = getKeySizeInBits(_)
// }
// final predicate hasKeySize(Expr configSrc){
// exists(this.getKeySizeInBits(configSrc))
// }
// final predicate hasKeySize(){
// exists(this.getAKeySizeInBits())
// }
// abstract Expr getKeyConfigSrc();
// abstract int getKeySizeInBits(Expr configSrc);
// }
abstract class CryptographicOperation extends CryptographicArtifact, Call { }
abstract class KeyGeneration extends CryptographicOperation {
// TODO: what if the algorithm is UNKNOWN?
abstract Expr getKeyConfigurationSource(CryptographicAlgorithm alg);
abstract CryptographicAlgorithm getAlgorithm();
int getKeySizeInBits(CryptographicAlgorithm alg) {
result = this.getKeyConfigurationSource(alg).(Literal).getValue().toInt()
}
predicate hasConstantKeySize(CryptographicAlgorithm alg) { exists(this.getKeySizeInBits(alg)) }
predicate hasKeyConfigurationSource(CryptographicAlgorithm alg) {
exists(this.getKeyConfigurationSource(alg))
}
Expr getAKeyConfigurationSource() { result = this.getKeyConfigurationSource(_) }
}
abstract class AsymmetricKeyGeneration extends KeyGeneration { }
abstract class SymmetricKeyGeneration extends KeyGeneration { }
/**
* A cryptographic algorithm is a `CryptographicArtifact`
* representing a cryptographic algorithm (see `CryptoAlgorithmNames.qll`).
* Cryptographic algorithms can be functions referencing common crypto algorithms (e.g., hashlib.md5)
* or strings that are used in cryptographic operation configurations (e.g., hashlib.new("md5")).
* Cryptogrpahic algorithms may also be operations that wrap or abstract one or
* more algorithms (e.g., cyrptography.fernet.Fernet and AES, CBC and PKCS7).
*
* In principle, this class should model the location where an algorithm enters the program, not
* necessarily where it is used.
*/
abstract class CryptographicAlgorithm extends CryptographicArtifact {
abstract string getName();
abstract string getAlgType();
// string getAlgType(){
// if this instanceof HashAlgorithm then result = getHashType()
// else if this instanceof KeyDerivationAlgorithm then result = getKeyDerivationType()
// else if this instanceof SymmetricEncryptionAlgorithm then result = getSymmetricEncryptionType()
// else if this instanceof AsymmetricEncryptionAlgorithm then result = getAsymmetricEncryptionType()
// else if this instanceof SymmetricEncryptionAlgorithm then result = getSymmetricPaddingType()
// else if this instanceof AsymmetricEncryptionAlgorithm then result = getAsymmetricPaddingType()
// else if this instanceof EllipticCurveAlgorithm then result = getEllipticCurveType()
// else if this instanceof BlockMode then result = getCipherBlockModeType()
// else if this instanceof KeyExchangeAlgorithm then result = getKeyExchangeType()
// else if this instanceof SigningAlgorithm then result = getSignatureType()
// else result = unknownAlgorithm()
// }
// TODO: handle case where name isn't known, not just unknown?
/**
* Normalizes a raw name into a normalized name as found in `CryptoAlgorithmNames.qll`.
* Subclassess should override for more api-specific normalization.
* By deafult, converts a raw name to upper-case with no hyphen, underscore, hash, or space.
*/
bindingset[s]
string normalizeName(string s) {
exists(string normStr | normStr = s.toUpperCase().regexpReplaceAll("[-_ ]|/", "") |
result = normStr and isKnownAlgorithm(result)
or
result = unknownAlgorithm() and not isKnownAlgorithm(normStr)
)
}
abstract Expr configurationSink();
predicate hasConfigurationSink() { exists(this.configurationSink()) }
}
abstract class HashAlgorithm extends CryptographicAlgorithm {
final string getHashName() {
if exists(string n | n = this.getName() and isHashingAlgorithm(n))
then isHashingAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getHashType() }
}
abstract class KeyDerivationAlgorithm extends CryptographicAlgorithm {
final string getKDFName() {
if exists(string n | n = this.getName() and isKeyDerivationAlgorithm(n))
then isKeyDerivationAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getKeyDerivationType() }
}
// abstract class KeyDerivationOperation extends CryptographicOperation{
// DataFlow::Node getIterationSizeSrc(){
// none()
// }
// DataFlow::Node getSaltConfigSrc(){
// none()
// }
// DataFlow::Node getHashConfigSrc(){
// none()
// }
// // TODO: get encryption algorithm for CBC-based KDF?
// DataFlow::Node getDerivedKeySizeSrc(){
// none()
// }
// DataFlow::Node getModeSrc(){
// none()
// }
// // TODO: add more to cover all the parameters of most KDF operations? Perhaps subclass for each type?
// abstract predicate requiresIteration();
// abstract predicate requiresSalt();
// abstract predicate requiresHash();
// //abstract predicate requiresKeySize(); // Going to assume all requires a size
// abstract predicate requiresMode();
// }
abstract class EncryptionAlgorithm extends CryptographicAlgorithm {
final predicate isAsymmetric() { this instanceof AsymmetricEncryptionAlgorithm }
final predicate isSymmetric() { not this.isAsymmetric() }
// NOTE: DO_NOT add getEncryptionName here, we rely on the fact the parent
// class does not have this common predicate.
}
/**
* A parent class to represent any algorithm for which
* asymmetric cryptography is involved.
* Intended to be distinct from AsymmetricEncryptionAlgorithm
* which is intended only for asymmetric algorithms that specifically encrypt.
*/
abstract class AsymmetricAlgorithm extends CryptographicAlgorithm { }
/**
* Algorithms directly or indirectly related to asymmetric encryption,
* e.g., RSA, DSA, but also RSA padding algorithms
*/
abstract class AsymmetricEncryptionAlgorithm extends AsymmetricAlgorithm, EncryptionAlgorithm {
final string getEncryptionName() {
if exists(string n | n = this.getName() and isAsymmetricEncryptionAlgorithm(n))
then isAsymmetricEncryptionAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getAsymmetricEncryptionType() }
}
/**
* Algorithms directly or indirectly related to symmetric encryption,
* e.g., AES, DES, but also block modes and padding
*/
abstract class SymmetricEncryptionAlgorithm extends EncryptionAlgorithm {
final string getEncryptionName() {
if exists(string n | n = this.getName() and isSymmetricEncryptionAlgorithm(n))
then isSymmetricEncryptionAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
// TODO: add a stream cipher predicate?
override string getAlgType() { result = getSymmetricEncryptionType() }
}
// Used only to categorize all padding into a single object,
// DO_NOT add predicates here. Only for categorization purposes.
abstract class PaddingAlgorithm extends CryptographicAlgorithm { }
abstract class SymmetricPadding extends PaddingAlgorithm {
final string getPaddingName() {
if exists(string n | n = this.getName() and isSymmetricPaddingAlgorithm(n))
then isSymmetricPaddingAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getSymmetricPaddingType() }
}
abstract class AsymmetricPadding extends PaddingAlgorithm {
final string getPaddingName() {
if exists(string n | n = this.getName() and isAsymmetricPaddingAlgorithm(n))
then isAsymmetricPaddingAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getAsymmetricPaddingType() }
}
abstract class EllipticCurveAlgorithm extends AsymmetricAlgorithm {
final string getCurveName() {
if exists(string n | n = this.getName() and isEllipticCurveAlgorithm(n))
then isEllipticCurveAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
final int getCurveBitSize() { isEllipticCurveAlgorithm(this.getCurveName(), result) }
override string getAlgType() { result = getEllipticCurveType() }
}
abstract class BlockModeAlgorithm extends CryptographicAlgorithm {
final string getBlockModeName() {
if exists(string n | n = this.getName() and isCipherBlockModeAlgorithm(n))
then isCipherBlockModeAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
/**
* Gets the source of the IV configuration.
*/
abstract Expr getIVorNonce();
final predicate hasIVorNonce() { exists(this.getIVorNonce()) }
override string getAlgType() { result = getCipherBlockModeType() }
}
// abstract class KeyWrapOperation extends CryptographicOperation{
// }
abstract class AuthenticatedEncryptionAlgorithm extends SymmetricEncryptionAlgorithm {
final string getAuthticatedEncryptionName() {
if exists(string n | n = this.getName() and isSymmetricEncryptionAlgorithm(n))
then isSymmetricEncryptionAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
}
abstract class KeyExchangeAlgorithm extends AsymmetricAlgorithm {
final string getKeyExchangeName() {
if exists(string n | n = this.getName() and isKeyExchangeAlgorithm(n))
then isKeyExchangeAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getKeyExchangeType() }
}
abstract class SigningAlgorithm extends AsymmetricAlgorithm {
final string getSigningName() {
if exists(string n | n = this.getName() and isSignatureAlgorithm(n))
then isSignatureAlgorithm(result) and result = this.getName()
else result = unknownAlgorithm()
}
override string getAlgType() { result = getSignatureType() }
}

View File

@@ -0,0 +1,718 @@
import cpp
import experimental.cryptography.CryptoAlgorithmNames
import experimental.cryptography.CryptoArtifact
import experimental.cryptography.utils.OpenSSL.CryptoFunction
import experimental.cryptography.utils.OpenSSL.AlgorithmSink
import experimental.cryptography.utils.OpenSSL.PassthroughFunction
import experimental.cryptography.utils.OpenSSL.CryptoAlgorithm
import experimental.cryptography.CryptoArtifact
// import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Problematic case in OpenSSL speed.c
* static const char *names[ALGOR_NUM] = {
* "md2", "mdc2", "md4", "md5", "sha1", "rmd160",
* "sha256", "sha512", "whirlpool", "hmac(md5)",
* "des-cbc", "des-ede3", "rc4", "idea-cbc", "seed-cbc",
* "rc2-cbc", "rc5-cbc", "blowfish", "cast-cbc",
* "aes-128-cbc", "aes-192-cbc", "aes-256-cbc",
* "camellia-128-cbc", "camellia-192-cbc", "camellia-256-cbc",
* "evp", "ghash", "rand", "cmac"
* };
*
* Every entry is considered a block mode, hash, and symmetric encryption algorithm
* getEncryptionName for example, will return unknown
*/
predicate nodeToExpr(DataFlow::Node node, Expr e) {
e = node.asExpr() or e = node.asIndirectArgument()
}
Expr getExprFromNode(DataFlow::Node node) { nodeToExpr(node, result) }
DataFlow::Node getNodeFromExpr(Expr e) { nodeToExpr(result, e) }
predicate isEVP_PKEY_CTX(Type t) { t.getUnderlyingType().stripType().getName() = "evp_pkey_ctx_st" }
/**
* An expression representing an EVP_PKEY_CTX* at the location of a
* known AlgorithmSinkArgument.
* The EVP_PKEY_CTX* represents the location where the CTX is tied to the algorithm,
* and can be used as a source for tracing EVP_PKEY_CTX to other operations.
*/
class Known_EVP_PKEY_CTX_Ptr_Source extends Expr {
Known_EVP_PKEY_CTX_Ptr_Source() {
isEVP_PKEY_CTX(this.getUnderlyingType()) and
this.getUnderlyingType() instanceof PointerType and
exists(AlgorithmSinkArgument arg, Call sinkCall |
arg.getSinkCall() = sinkCall and
sinkCall.getAnArgument() = this
or
this = sinkCall
)
}
}
// module CTXFlow implements DataFlow::ConfigSig{
// predicate isSource(DataFlow::Node source) {
// // ASSUMPTION: at a sink, an algorithm is converted into a CTX through a return of the call only
// // and is the primary source of interest for CTX tracing
// source.asExpr() instanceof AlgorithmSinkArgument
// }
// predicate isSink(DataFlow::Node sink){
// sink.asExpr() instanceof CTXSink
// }
// predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// // cls.getName() = "asn1_object_st" flow out on any EVP_PKEY_CTX which is "evp_pkey_ctx_st"
// exists(Call c |
// isEVP_PKEY_CTX(c.getUnderlyingType()) and
// node1.asExpr() = c.getAnArgument() and c = node2.asExpr())
// }
// }
// module CTXFlowConfig = DataFlow::Global<CTXFlow>;
// TODO: currently only handles tracing from literals to sinks
module LiteralAlgorithmTracerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof Literal and
// Optimization to reduce literal tracing on integers to only those that are known/relevant NIDs.
(
exists(source.asExpr().getValue().toInt())
implies
source.asExpr().getValue().toInt() < getNIDMax()
) and
// False positives observed inside OBJ_nid2* and OBJ_sn2* functions where NULL is a possible assignment.
// While this is a concern, it only occurs if the object being referenced is NULL to begin with
// Perhaps a different query should be used to find these caes if they represent a threat.
// Filter out any open ssl function source in a function namae Obj_*
// False positives in OpenSSL also observed for CRYPTO_strndup (filtering any CRYPTO_* function)
// due to setting a null byte in the string
(
isPossibleOpenSSLFunction(source.getEnclosingCallable())
implies
(
not source.getEnclosingCallable().getName().matches("OBJ_%") and
not source.getEnclosingCallable().getName().matches("CRYPTO_%")
)
)
}
predicate isSink(DataFlow::Node sink) {
// A sink is a call to a function that takes an algorithm as an argument
// must include checks for asIndirectArgument since the input may be a pointer to an object
// and the member of the object holds the algorithm on the trace.
getExprFromNode(sink) instanceof AlgorithmSinkArgument
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
knownPassThroughStep(node1, node2)
}
predicate isBarrier(DataFlow::Node node) {
// If the node is the 'next' argument of a isCallPassThrough, it is only allowed if it is an out parameter
// i.e., a defining argument. This barrier says that if the node is an expression not an out parameter, it is filtered.
// Out arguments will not be filtered.
exists(Call c | knownPassthoughCall(c, _, node.asExpr()) and c.getAnArgument() = node.asExpr())
or
// False positive reducer, don't flow out through argv
node.asVariable().hasName("argv")
or
node.asIndirectVariable().hasName("argv")
}
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
// Assume a read on crypto identifying field for any object of type asn1_object_st (i.e., ASN1_OBJECT)
exists(Class cls | cls.getName() = "asn1_object_st" |
node.getType().getUnspecifiedType().stripType() = cls and
c.(DataFlow::FieldContent).getField() = cls.getAMember() and
c.(DataFlow::FieldContent).getField().getName() in ["nid", "sn", "ln"]
)
}
}
module LiteralAlgorithmTracer = DataFlow::Global<LiteralAlgorithmTracerConfig>;
/**
* `source` is an expression that is a source of an algorithm of type `algType`.
* `algType` may be `UNKONWN`.
* See CryptoAlgorithmNames for other possible values of `algType`.
*/
bindingset[sinkAlgType]
predicate hasLiteralPathToAlgSink(DataFlow::Node source, DataFlow::Node sink, string sinkAlgType) {
LiteralAlgorithmTracer::flow(source, sink) and
getExprFromNode(sink).(AlgorithmSinkArgument).algType() = sinkAlgType
}
private predicate knownTracedAlgorithm(Literal e, string srcSinkType) {
knownTracedAlgorithm(e, srcSinkType, srcSinkType)
}
private predicate knownTracedAlgorithm(Literal e, string srcType, string sinkType) {
resolveAlgorithmFromLiteral(e, _, srcType) and
hasLiteralPathToAlgSink(DataFlow::exprNode(e), _, sinkType) and
isKnownType(sinkType) and
isKnownType(srcType)
}
private predicate unknownTracedLiteralAlgorithm(Literal e, string srcSinkType) {
// Asymmetric special case:
// Since asymmetric algorithm sinks are used for various categories of asymmetric algorithms
// an asymmetric algorithm is only unknown if there is no trace from any asymmetric type to the given srcSinkType sink
if getAsymmetricType() = srcSinkType
then forall(string t | t = getAsymmetricType() | unknownTracedLiteralAlgorithm(e, t, srcSinkType))
else unknownTracedLiteralAlgorithm(e, srcSinkType, srcSinkType)
}
private predicate unknownTracedLiteralAlgorithm(Literal e, string srcType, string sinkType) {
// the literal resolves to an algorithm, but not to the sinktype
// or generally doesn't resolve to any algorithm type
// this case covers 'nonsense' cases e.g., use RSA for symmetric encryption
not resolveAlgorithmFromLiteral(e, _, srcType) and
isValidAlgorithmLiteral(e) and
hasLiteralPathToAlgSink(DataFlow::exprNode(e), _, sinkType) and
isKnownType(sinkType) and
isKnownType(srcType)
}
private predicate unknownTracedNonLiteralAlgorithm(AlgorithmSinkArgument e, string srcSinkType) {
// Asymmetric special case:
// Since asymmetric algorithm sinks are used for various categories of asymmetric algorithms
// an asymmetric algorithm is only unknown if there is no trace from any asymmetric type to the given srcSinkType sink
if getAsymmetricType() = srcSinkType
then
forall(string t | t = getAsymmetricType() | unknownTracedNonLiteralAlgorithm(e, t, srcSinkType))
else unknownTracedNonLiteralAlgorithm(e, srcSinkType, srcSinkType)
}
private predicate unknownTracedNonLiteralAlgorithm(
AlgorithmSinkArgument e, string srcType, string sinkType
) {
not hasLiteralPathToAlgSink(_, getNodeFromExpr(e), srcType) and
LiteralAlgorithmTracerConfig::isSink(getNodeFromExpr(e)) and
e.algType() = sinkType and
isKnownType(srcType) and
isKnownType(sinkType)
}
private predicate functionAlgorithm(Call c, string algType) {
isOpenSSLCryptoFunctionCall(c, _, algType)
}
abstract class OpenSSLTracedAlgorithm extends CryptographicAlgorithm {
override string getName() { resolveAlgorithmFromLiteral(this, result, this.getAlgType()) }
override Expr configurationSink() {
exists(DataFlow::Node sink |
hasLiteralPathToAlgSink(DataFlow::exprNode(this), sink, this.getAlgType())
|
result = getExprFromNode(sink)
)
}
}
abstract class OpenSSLFunctionAlgorithm extends CryptographicAlgorithm {
override string getName() { isOpenSSLCryptoFunctionCall(this, result, this.getAlgType()) }
override Expr configurationSink() { result = this }
}
abstract class OpenSSLUnknownTracedLiteralAlgorithm extends CryptographicAlgorithm {
override string getName() { result = unknownAlgorithm() }
override Expr configurationSink() {
exists(DataFlow::Node sink |
hasLiteralPathToAlgSink(DataFlow::exprNode(this), sink, this.getAlgType())
|
result = getExprFromNode(sink)
)
}
}
abstract class OpenSSLUnknownTracedNonLiteralAlgorithm extends CryptographicAlgorithm {
override string getName() { result = unknownAlgorithm() }
override Expr configurationSink() { result = this }
}
module SymmetricEncryption {
abstract class OpenSSLSymmetricEncryptionAlgorithm extends SymmetricEncryptionAlgorithm { }
class OpenSSLSymmetricEncryptionTracedAlgorithm extends OpenSSLTracedAlgorithm,
OpenSSLSymmetricEncryptionAlgorithm
{
OpenSSLSymmetricEncryptionTracedAlgorithm() {
knownTracedAlgorithm(this, getSymmetricEncryptionType())
}
}
class OpenSSLSymmetricEncryptionFunctionAlgorithm extends OpenSSLFunctionAlgorithm,
OpenSSLSymmetricEncryptionAlgorithm
{
OpenSSLSymmetricEncryptionFunctionAlgorithm() {
functionAlgorithm(this, getSymmetricEncryptionType())
}
}
class OpenSSLSymmetricEncryptionTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
OpenSSLSymmetricEncryptionAlgorithm
{
OpenSSLSymmetricEncryptionTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getSymmetricEncryptionType())
}
}
class OpenSSLSymmetricEncryptionUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
OpenSSLSymmetricEncryptionAlgorithm
{
OpenSSLSymmetricEncryptionUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getSymmetricEncryptionType())
}
}
}
module BlockModes {
/**
* In OpenSSL, block modes are associated directly with symmetric encryption algorithms.
* As such, OpenSSLBLockModes are modeled as extensions of any openssl symmetric encryption algorithm
*/
class OpenSSLBlockModeAlgorithm extends BlockModeAlgorithm, Expr instanceof SymmetricEncryption::OpenSSLSymmetricEncryptionAlgorithm
{
OpenSSLBlockModeAlgorithm() {
//two cases, either the block mode is a literal or it is a function call
resolveAlgorithmFromLiteral(this, _, "BLOCK_MODE")
or
isOpenSSLCryptoFunctionCall(this, _, "BLOCK_MODE")
}
override string getName() {
resolveAlgorithmFromLiteral(this, result, "BLOCK_MODE")
or
isOpenSSLCryptoFunctionCall(this, result, "BLOCK_MODE")
}
override Expr configurationSink() {
result = this.(SymmetricEncryption::OpenSSLSymmetricEncryptionAlgorithm).configurationSink()
}
override Expr getIVorNonce() {
// TODO
none()
}
}
class UnknownOpenSSLBlockModeAlgorithm extends BlockModeAlgorithm, Expr instanceof SymmetricEncryption::OpenSSLSymmetricEncryptionAlgorithm
{
UnknownOpenSSLBlockModeAlgorithm() {
//two cases, either the block mode is a literal or it is a function call
not resolveAlgorithmFromLiteral(this, _, "BLOCK_MODE") and
not isOpenSSLCryptoFunctionCall(this, _, "BLOCK_MODE")
}
override string getName() { result = unknownAlgorithm() }
override Expr configurationSink() {
result = this.(SymmetricEncryption::OpenSSLSymmetricEncryptionAlgorithm).configurationSink()
}
override Expr getIVorNonce() { none() }
}
}
module Hashes {
abstract class OpenSSLHashAlgorithm extends HashAlgorithm { }
class OpenSSLHashTracedAlgorithm extends OpenSSLTracedAlgorithm, OpenSSLHashAlgorithm {
OpenSSLHashTracedAlgorithm() { knownTracedAlgorithm(this, getHashType()) }
}
class OpenSSLHashFunctionAlgorithm extends OpenSSLFunctionAlgorithm, OpenSSLHashAlgorithm {
OpenSSLHashFunctionAlgorithm() { functionAlgorithm(this, getHashType()) }
}
class OpenSSLHashTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
OpenSSLHashAlgorithm
{
OpenSSLHashTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getHashType())
}
}
class OpenSSLHashUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
OpenSSLHashAlgorithm
{
OpenSSLHashUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getHashType())
}
}
class OpenSSLNullHash extends HashAlgorithm {
OpenSSLNullHash() {
exists(Call c |
this = c and
isPossibleOpenSSLFunction(c.getTarget()) and
c.getTarget().getName() in ["EVP_md_null"]
)
}
override string getName() { result = unknownAlgorithm() }
override Expr configurationSink() { result = this }
}
}
module EllipticCurves {
// TODO: need to address EVP_PKEY_Q_keygen where the type is "EC" but the curve is UNKNOWN?
class OpenSSLEllipticCurveTracedAlgorithm extends OpenSSLTracedAlgorithm, EllipticCurveAlgorithm {
OpenSSLEllipticCurveTracedAlgorithm() { knownTracedAlgorithm(this, getEllipticCurveType()) }
}
class OpenSSLEllipticCurveFunctionAlgorithm extends OpenSSLFunctionAlgorithm,
EllipticCurveAlgorithm
{
OpenSSLEllipticCurveFunctionAlgorithm() { functionAlgorithm(this, getEllipticCurveType()) }
}
class OpenSSLEllipticCurveTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
EllipticCurveAlgorithm
{
OpenSSLEllipticCurveTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getEllipticCurveType())
}
}
class OpenSSLEllipticCurvehUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
EllipticCurveAlgorithm
{
OpenSSLEllipticCurvehUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getEllipticCurveType())
}
}
// https://www.openssl.org/docs/manmaster/man3/EC_KEY_new_ex.html
class OpenSSLNullEllipticCurve extends EllipticCurveAlgorithm {
OpenSSLNullEllipticCurve() {
exists(Call c |
this = c and
isPossibleOpenSSLFunction(c.getTarget()) and
c.getTarget().getName() in ["EC_KEY_new", "EC_KEY_new_ex"]
)
}
override string getName() { result = unknownAlgorithm() }
override Expr configurationSink() { result = this }
}
}
module AsymmetricEncryption {
class OpenSSLAsymmetricEncryptionTracedAlgorithm extends OpenSSLTracedAlgorithm,
AsymmetricEncryptionAlgorithm
{
OpenSSLAsymmetricEncryptionTracedAlgorithm() {
knownTracedAlgorithm(this, getAsymmetricEncryptionType())
}
}
class OpenSSLAsymmetricEncryptionFunctionAlgorithm extends OpenSSLFunctionAlgorithm,
AsymmetricEncryptionAlgorithm
{
OpenSSLAsymmetricEncryptionFunctionAlgorithm() {
functionAlgorithm(this, getAsymmetricEncryptionType())
}
}
class OpenSSLAsymmetricEncryptionTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
AsymmetricEncryptionAlgorithm
{
OpenSSLAsymmetricEncryptionTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getAsymmetricEncryptionType())
}
}
class OpenSSLAsymmetricEncryptionUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
AsymmetricEncryptionAlgorithm
{
OpenSSLAsymmetricEncryptionUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getAsymmetricEncryptionType())
}
}
}
module SigningAlgorithms {
class OpenSSLSignatureTracedAlgorithm extends OpenSSLTracedAlgorithm, SigningAlgorithm {
OpenSSLSignatureTracedAlgorithm() { knownTracedAlgorithm(this, getSignatureType()) }
}
class OpenSSLSignatureFunctionAlgorithm extends OpenSSLFunctionAlgorithm, SigningAlgorithm {
OpenSSLSignatureFunctionAlgorithm() { functionAlgorithm(this, getSignatureType()) }
}
class OpenSSLSignatureTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
SigningAlgorithm
{
OpenSSLSignatureTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getSignatureType())
}
}
class OpenSSLSignatureUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
SigningAlgorithm
{
OpenSSLSignatureUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getSignatureType())
}
}
}
module KeyExchange {
class OpenSSLKeyExchangeTracedAlgorithm extends OpenSSLTracedAlgorithm, KeyExchangeAlgorithm {
OpenSSLKeyExchangeTracedAlgorithm() { knownTracedAlgorithm(this, getKeyExchangeType()) }
}
class OpenSSLKeyExchangeFunctionAlgorithm extends OpenSSLFunctionAlgorithm, KeyExchangeAlgorithm {
OpenSSLKeyExchangeFunctionAlgorithm() { functionAlgorithm(this, getKeyExchangeType()) }
}
class OpenSSLKeyExchangeTracedUnknownLiteralAlgorithm extends OpenSSLUnknownTracedLiteralAlgorithm,
KeyExchangeAlgorithm
{
OpenSSLKeyExchangeTracedUnknownLiteralAlgorithm() {
unknownTracedLiteralAlgorithm(this, getKeyExchangeType())
}
}
class OpenSSLKeyExchangeUnknownNonLiteralTracedAlgorithm extends OpenSSLUnknownTracedNonLiteralAlgorithm,
KeyExchangeAlgorithm
{
OpenSSLKeyExchangeUnknownNonLiteralTracedAlgorithm() {
unknownTracedNonLiteralAlgorithm(this, getKeyExchangeType())
}
}
}
module KeyGeneration {
/**
* Functions that explicitly set key generation parameters.
* `sizeInd` is the parameter specifying the size of the key.
* `outInd` is the parameter or return value that the key is written to.
* `outInd` is -1 if the key is written to the return value.
*/
predicate isAsymmetricKeyGenExplicitAlgorithm(Function func, int sizeInd, int outInd) {
isPossibleOpenSSLFunction(func) and
exists(string name | func.hasGlobalName(name) |
name in [
"EVP_PKEY_CTX_set_dsa_paramgen_bits", "DSA_generate_parameters_ex",
"EVP_PKEY_CTX_set_rsa_keygen_bits", "RSA_generate_key_ex", "RSA_generate_key_fips",
"EVP_PKEY_CTX_set_dh_paramgen_prime_len", "DH_generate_parameters_ex"
] and
sizeInd = 1 and
outInd = 0
or
name in ["DSA_generate_parameters", "RSA_generate_key", "DH_generate_parameters"] and
sizeInd = 0 and
outInd = -1
) and
exists(Type t |
(
if sizeInd = -1
then t = func.getType().getUnderlyingType()
else t = func.getParameter(sizeInd).getUnderlyingType()
) and
t instanceof IntegralType and
not t instanceof CharType
)
}
module AsymExplicitAlgKeyLengthFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
// Optimizations to avoid tracing all integers
node.asExpr().(Literal).getValue().toInt() > 0 and // exclude sentinel values
node.asExpr().(Literal).getValue().toInt() < 8500
}
predicate isSink(DataFlow::Node node) {
exists(FunctionCall c, int sizeInd |
isAsymmetricKeyGenExplicitAlgorithm(c.getTarget(), sizeInd, _) and
c.getArgument(sizeInd) = node.asExpr()
)
}
}
module AsymExplicitAlgKeyLengthFlow = DataFlow::Global<AsymExplicitAlgKeyLengthFlowConfig>;
class OpenSSLAsymmetricKeyGenTiedToAlgorithm extends AsymmetricKeyGeneration {
OpenSSLAsymmetricKeyGenTiedToAlgorithm() {
exists(Call c |
this = c and
isPossibleOpenSSLFunction(c.getTarget()) and
isAsymmetricKeyGenExplicitAlgorithm(c.getTarget(), _, _)
)
}
override CryptographicAlgorithm getAlgorithm() { result = this }
override Expr getKeyConfigurationSource(CryptographicAlgorithm alg) {
alg = this and
exists(int sizeInd |
isAsymmetricKeyGenExplicitAlgorithm(this.getTarget(), sizeInd, _) and
AsymExplicitAlgKeyLengthFlow::flow(DataFlow::exprNode(result),
DataFlow::exprNode(this.getArgument(sizeInd)))
)
}
}
module Length_to_RSA_EVP_PKEY_Q_keygen_Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
// Optimizations to avoid tracing all integers
node.asExpr().(Literal).getValue().toInt() > 0 and // exclude sentinel values
node.asExpr().(Literal).getValue().toInt() < 5000
}
predicate isSink(DataFlow::Node node) {
exists(FunctionCall c |
c.getTarget().getName() = "EVP_PKEY_Q_keygen" and
isPossibleOpenSSLFunction(c.getTarget()) and
c.getArgument(3) = node.asExpr()
)
}
}
module Length_to_RSA_EVP_PKEY_Q_keygen_Flow =
DataFlow::Global<Length_to_RSA_EVP_PKEY_Q_keygen_Config>;
class OpenSSL_RSA_EVP_PKEY_Q_keygen extends AsymmetricKeyGeneration {
OpenSSL_RSA_EVP_PKEY_Q_keygen() {
exists(Call c |
this = c and
isPossibleOpenSSLFunction(c.getTarget()) and
this.getTarget().getName() = "EVP_PKEY_Q_keygen" and
this.getArgument(3).getUnderlyingType() instanceof IntegralType
)
}
override CryptographicAlgorithm getAlgorithm() {
result.configurationSink().(AlgorithmSinkArgument).getSinkCall() = this
}
override Expr getKeyConfigurationSource(CryptographicAlgorithm alg) {
alg = this.getAlgorithm() and
Length_to_RSA_EVP_PKEY_Q_keygen_Flow::flow(DataFlow::exprNode(result),
DataFlow::exprNode(this.getArgument(3)))
}
}
predicate isKeyGenOperationWithNoSize(Function func) {
isPossibleOpenSSLFunction(func) and
exists(string name | func.hasGlobalName(name) |
name in ["EVP_PKEY_keygen", "DSA_generate_key", "DH_generate_key", "EVP_PKEY_generate"]
)
}
module KeyGenKeySizeInitToKeyGenConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
exists(Call c, Function func, int outInd |
isAsymmetricKeyGenExplicitAlgorithm(func, _, outInd) and
c.getTarget() = func
|
if outInd = -1 then node.asExpr() = c else node.asExpr() = c.getArgument(outInd)
)
}
predicate isSink(DataFlow::Node node) {
exists(Call c |
isKeyGenOperationWithNoSize(c.getTarget()) and c.getAnArgument() = node.asExpr()
)
}
}
module KeyGenKeySizeInitToKeyGenFlow = DataFlow::Global<KeyGenKeySizeInitToKeyGenConfig>;
predicate isEVP_PKEY_CTX_Source(DataFlow::Node node, CryptographicAlgorithm alg) {
exists(Call c |
alg.configurationSink().(AlgorithmSinkArgument).getSinkCall() = c and
(
node.asExpr() = c
or
node.asExpr() = c.getAnArgument()
or
node.asDefiningArgument() = c.getAnArgument()
)
) and
(
node.asExpr() instanceof Known_EVP_PKEY_CTX_Ptr_Source
or
node.asDefiningArgument() instanceof Known_EVP_PKEY_CTX_Ptr_Source
)
}
predicate isKeyGen_EVP_PKEY_CTX_Sink(DataFlow::Node node, Call c) {
isKeyGenOperationWithNoSize(c.getTarget()) and nodeToExpr(node, c.getAnArgument())
}
/**
* Trace from EVP_PKEY_CTX* at algorithm sink to keygen,
* users can then extrapolatae the matching algorithm from the alg sink to the keygen
*/
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isEVP_PKEY_CTX_Source(source, _) }
predicate isSink(DataFlow::Node sink) { isKeyGen_EVP_PKEY_CTX_Sink(sink, _) }
}
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize_Flow =
DataFlow::Global<EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize>;
/**
* UNKNOWN key sizes to general purpose key generation functions (i.e., that take in no key size and assume
* is it set on context prior to the call). No path from a key configuration to these operations
* means the key size is UNKNOWN, or more precisely the key size is DEFAULT but
* the defaults can change with each version of OpenSSL, we simply assume the size is generally UNKNOWN.
* ASSUMPTION/TODO: we currently model all known locations where a key size is set explicitly.
* When a key is set implicitly, this usually means a key generation operation
* is called where the operation takes in no key size, and no flow to this operation
* initializes the context with a key size.
* Currently, without a definitive source (set of sources) to start tracing from, we cannot determine
* determine if a single path exists that initializes the context with a key size and another that doesn't.
* Rather than attempt to model all possible sources, we assume that if no path
* from a key config location reaches a generic key generation operation, then the key size is not set.
* NOTE: while this is true, it is possible a key size is set in one path, but not in another
* meaning this approach (and other similar approaches used in this model for UNKNOWN)
* can produce false negatives.
*/
class OpenSSLDefaultKeyGeneration extends AsymmetricKeyGeneration {
OpenSSLDefaultKeyGeneration() {
// this is a call to a function matching isKeyGenOperationWithNoSize
// and there is no flow from a key configuration source to this call
exists(Call c |
this = c and
isKeyGenOperationWithNoSize(this.getTarget()) and
not exists(DataFlow::Node src, DataFlow::Node sink |
KeyGenKeySizeInitToKeyGenFlow::flow(src, sink) and
nodeToExpr(sink, this.getAnArgument())
)
)
}
override CryptographicAlgorithm getAlgorithm() {
if this.getTarget().getName() in ["DSA_generate_key", "DH_generate_key"]
then result = this
else
// NOTE/ASSUMPTION: EVP_PKEY_keygen, EVP_PKEY_generate assume only other possibilities,
// each take in a CTX as the first arg, need to trace from an alg sink from this CTX param
// get every alg sink, get the corresponding call, trace out on any CTX type variable
// to the key gen
// NOTE: looking for any cryptographic algorithm tracing to the keygen to handle
// any odd cases we aren't awaare of where keygen can be used for other algorithm types
exists(DataFlow::Node src, DataFlow::Node sink |
EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize_Flow::flow(src, sink) and
isEVP_PKEY_CTX_Source(src, result) and
isKeyGen_EVP_PKEY_CTX_Sink(sink, this)
// TODO: what if there is no CTX source? then the keygen becomes an UNKNOWN sink
)
}
/**
* For this class, there is no known configuration source for any algorithm
*/
override Expr getKeyConfigurationSource(CryptographicAlgorithm alg) { none() }
}
}

View File

@@ -0,0 +1,296 @@
/**
* Predicates/classes for identifying algorithm sinks.
* An Algorithm Sink is a function that takes an algorithm as an argument.
* In particular, any function that takes in an algorithm that until the call
* the algorithm is not definitely known to be an algorithm (e.g., an integer used as an identifier to fetch an algorithm)
*/
//TODO: enforce a hierarchy of AlgorithmSinkArgument, e.g., so I can get all Asymmetric SinkArguments that includes all the strictly RSA etc.
import cpp
import experimental.cryptography.utils.OpenSSL.LibraryFunction
import experimental.cryptography.CryptoAlgorithmNames
predicate isAlgorithmSink(AlgorithmSinkArgument arg, string algType) { arg.algType() = algType }
abstract class AlgorithmSinkArgument extends Expr {
AlgorithmSinkArgument() {
exists(Call c | c.getAnArgument() = this and openSSLLibraryFunc(c.getTarget()))
}
/**
* Gets the function call in which the argument exists
*/
Call getSinkCall() { result.getAnArgument() = this }
abstract string algType();
}
// https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html
predicate cipherAlgorithmSink(string funcName, int argInd) {
funcName in ["EVP_get_cipherbyname", "EVP_get_cipherbynid", "EVP_get_cipherbyobj"] and argInd = 0
or
funcName = "EVP_CIPHER_fetch" and argInd = 1
}
class CipherAlgorithmSink extends AlgorithmSinkArgument {
CipherAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
cipherAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getSymmetricEncryptionType() }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_MAC_fetch
predicate macAlgorithmSink(string funcName, int argInd) {
(funcName = "EVP_MAC_fetch" and argInd = 1)
}
class MACAlgorithmSink extends AlgorithmSinkArgument {
MACAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
macAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = "TBD" }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_MD_fetch
predicate messageDigestAlgorithmSink(string funcName, int argInd) {
funcName in ["EVP_get_digestbyname", "EVP_get_digestbynid", "EVP_get_digestbyobj"] and argInd = 0
or
funcName = "EVP_MD_fetch" and argInd = 1
}
class MessageDigestAlgorithmSink extends AlgorithmSinkArgument {
MessageDigestAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
messageDigestAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getHashType() }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_KEYEXCH_fetch
// https://www.openssl.org/docs/manmaster/man3/EVP_KEM_fetch
predicate keyExchangeAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_KEYEXCH_fetch" and argInd = 1
or
funcName = "EVP_KEM_fetch" and argInd = 1
}
class KeyExchangeAlgorithmSink extends AlgorithmSinkArgument {
KeyExchangeAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
keyExchangeAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getKeyExchangeType() }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_KEYMGMT_fetch
predicate keyManagementAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_KEYMGMT_fetch" and argInd = 1
}
class KeyManagementAlgorithmSink extends AlgorithmSinkArgument {
KeyManagementAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
keyManagementAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = "TBD" }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_KDF
predicate keyDerivationAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_KDF_fetch" and argInd = 1
}
class KeyDerivationAlgorithmSink extends AlgorithmSinkArgument {
KeyDerivationAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
keyDerivationAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getKeyDerivationType() }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_ASYM_CIPHER_fetch
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_new_id
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new_CMAC_key.html
predicate asymmetricCipherAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_ASYM_CIPHER_fetch" and argInd = 1
or
funcName = "EVP_PKEY_new_CMAC_key" and argInd = 3
// NOTE: other cases are handled by AsymmetricAlgorithmSink
}
class AsymmetricCipherAlgorithmSink extends AlgorithmSinkArgument {
AsymmetricCipherAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
asymmetricCipherAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = "ASYMMETRIC_ENCRYPTION" }
}
class AsymmetricCipherAlgorithmSink_EVP_PKEY_Q_keygen extends AlgorithmSinkArgument {
AsymmetricCipherAlgorithmSink_EVP_PKEY_Q_keygen() {
exists(Call c, string funcName |
funcName = c.getTarget().getName() and
this = c.getArgument(3)
|
funcName = "EVP_PKEY_Q_keygen" and
c.getArgument(3).getType().getUnderlyingType() instanceof IntegralType
)
}
override string algType() { result = "ASYMMETRIC_ENCRYPTION" }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_RAND_fetch
predicate randomAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_RAND_fetch" and argInd = 1
}
class RandomAlgorithmSink extends AlgorithmSinkArgument {
RandomAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
randomAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = "TBD" }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_SIGNATURE_fetch
predicate signatureAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_SIGNATURE_fetch" and argInd = 1
}
class SignatureAlgorithmSink extends AlgorithmSinkArgument {
SignatureAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
signatureAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getSignatureType() }
}
// https://www.openssl.org/docs/manmaster/man3/EC_KEY_new_by_curve_name.html
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_ec_paramgen_curve_nid.html
predicate ellipticCurveAlgorithmSink(string funcName, int argInd) {
funcName in ["EC_KEY_new_by_curve_name", "EVP_EC_gen"] and argInd = 0
or
funcName = "EC_KEY_new_by_curve_name_ex" and argInd = 2
or
funcName in ["EVP_PKEY_CTX_set_ec_paramgen_curve_nid"] and argInd = 1
}
class EllipticCurveAlgorithmSink extends AlgorithmSinkArgument {
EllipticCurveAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
ellipticCurveAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getEllipticCurveType() }
}
/**
* Special cased to address the fact that arg index 3 (zero offset based) is the curve name.
* ASSUMPTION: if the arg ind 3 is a char* assume it is an elliptic curve
*/
class EllipticCurveAlgorithmSink_EVP_PKEY_Q_keygen extends AlgorithmSinkArgument {
EllipticCurveAlgorithmSink_EVP_PKEY_Q_keygen() {
exists(Call c, string funcName |
funcName = c.getTarget().getName() and
this = c.getArgument(3)
|
funcName = "EVP_PKEY_Q_keygen" and
c.getArgument(3).getType().getUnderlyingType() instanceof PointerType and
c.getArgument(3).getType().getUnderlyingType().stripType() instanceof CharType
)
}
override string algType() { result = getEllipticCurveType() }
}
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_new_id.html
// https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_new_raw_private_key.html
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_new.html
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_ctrl.html
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_Q_keygen.html
// https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_ctrl.html
predicate asymmetricAlgorithmSink(string funcName, int argInd) {
funcName = "EVP_PKEY_CTX_new_id" and argInd = 0
or
funcName = "EVP_PKEY_CTX_new_from_name" and argInd = 1
or
funcName in [
"EVP_PKEY_new_raw_private_key", "EVP_PKEY_new_raw_public_key", "EVP_PKEY_new_mac_key"
] and
argInd = 0
or
funcName in ["EVP_PKEY_new_raw_private_key_ex", "EVP_PKEY_new_raw_public_key_ex"] and argInd = 1
or
// special casing this as arg index 3 must be specified depending on if RSA or ECC, and otherwise not specified for other algs
// funcName = "EVP_PKEY_Q_keygen" and argInd = 2
funcName in ["EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_set_group_name"] and argInd = 1
// TODO consider void cases EVP_PKEY_new
}
class AsymmetricAlgorithmSink extends AlgorithmSinkArgument {
AsymmetricAlgorithmSink() {
exists(Call c, string funcName, int argInd |
funcName = c.getTarget().getName() and this = c.getArgument(argInd)
|
asymmetricAlgorithmSink(funcName, argInd)
)
}
override string algType() { result = getAsymmetricType() }
}
class AsymmetricAlgorithmSink_EVP_PKEY_Q_keygen extends AlgorithmSinkArgument {
AsymmetricAlgorithmSink_EVP_PKEY_Q_keygen() {
exists(Call c, string funcName |
funcName = c.getTarget().getName() and
this = c.getArgument(2)
|
funcName = "EVP_PKEY_Q_keygen" and
not exists(c.getArgument(3))
)
}
override string algType() { result = getAsymmetricType() }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
import cpp
import experimental.cryptography.utils.OpenSSL.LibraryFunction
import experimental.cryptography.CryptoAlgorithmNames
predicate inferredOpenSSLCryptoFunctionCall(Call c, string normalized, string algType) {
inferredOpenSSLCryptoFunction(c.getTarget(), normalized, algType)
}
predicate inferredOpenSSLCryptoFunction(Function f, string normalized, string algType) {
isPossibleOpenSSLFunction(f) and
normalizeFunctionName(f, algType) = normalized
}
predicate isOpenSSLCryptoFunction(Function f, string normalized, string algType) {
// NOTE: relying on inference as there are thousands of functions for crypto
// enumerating them all and maintaining the list seems problematic.
// For now, we will rely on dynamically inferring algorithms for function names.
// This has been seen to be reasonably efficient and accurate.
inferredOpenSSLCryptoFunction(f, normalized, algType)
}
predicate isOpenSSLCryptoFunctionCall(Call c, string normalized, string algType) {
isOpenSSLCryptoFunction(c.getTarget(), normalized, algType)
}
private string basicNormalizeFunctionName(Function f, string algType) {
isPossibleOpenSSLFunction(f) and
isKnownAlgorithm(result, algType) and
exists(string normStr | normStr = f.getName().toUpperCase().regexpReplaceAll("[-_ ]|/", "") |
normStr.matches("%" + result + "%")
)
}
/**
* Converts a raw OpenSSL algorithm to a normalized algorithm name.
*
* If more than one match occurs for a given algorithm type, normalize attempts to find the "max"
* string (max in terms of string length) e.g., matching AES128 to AES128 and not simply AES.
*
* An unknown algorithm is only identified if there exists no known algorithm found for any algorithm type.
*
* `f` is the function name to normalize.
* `algType` is a string representing the classification of the algorithm (see `CryptoAlgorithmNames`)
*/
private string privateNormalizeFunctionName(Function f, string algType) {
isPossibleOpenSSLFunction(f) and
result = basicNormalizeFunctionName(f, algType) and
not exists(string res2 |
result != res2 and
res2 = basicNormalizeFunctionName(f, algType) and
res2.length() > result.length()
)
}
/**
* Normalizes a function name to a known algorithm name, similar to `normalizeName`.
* A function is not, however, allowed to be UNKNOWN. The function either
* normalizes to a known algorithm name, or the predicate does not hold (no result).
*
* The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false postive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.
*/
private string normalizeFunctionName(Function f, string algType) {
algType != "UNKNOWN" and
isPossibleOpenSSLFunction(f) and
result = privateNormalizeFunctionName(f, algType) and
// Addressing false positives
// For algorithm names less than or equal to 4, we must see the algorithm name
// in the original function as upper case (it can't be split between tokens)
// One exception found is DES_xcbc_encrypt, this is DESX
(
(result.length() <= 4 and result != "DESX")
implies
f.getName().toUpperCase().matches("%" + result + "%")
) and
(
(result.length() <= 4 and result = "DESX")
implies
(f.getName().toUpperCase().matches("%DESX%") or f.getName().toUpperCase().matches("%DES_X%"))
) and
// (result.length() <= 3 implies (not f.getName().toUpperCase().regexpMatch(".*" + result + "[a-zA-Z0-9].*|.*[a-zA-Z0-9]" + result + ".*")))
// and
// DES specific false positives
(
result.matches("DES")
implies
not f.getName().toUpperCase().regexpMatch(".*DES[a-zA-Z0-9].*|.*[a-zA-Z0-9]DES.*")
) and
// ((result.matches("%DES%")) implies not exists(string s | s in ["DESCRIBE", "DESTROY", "DESCRIPTION", "DESCRIPTOR", "NODES"] |
// f.getName().toUpperCase().matches("%" + s + "%"))) and
// SEED specific false positives
(
result.matches("SEED")
implies
not exists(string s |
s in [
"SEED_SRC_GENERATE", "RAND", "NEW_SEED", "GEN_SEED", "SEED_GEN", "SET_SEED", "GET_SEED",
"GET0_SEED", "RESEED", "SEEDING"
]
|
f.getName().toUpperCase().matches("%" + s + "%")
)
) and
// ARIA specific false positives
(result.matches("ARIA") implies not f.getName().toUpperCase().matches("%VARIANT%")) and
// CTR false positives
(result.matches("CTR") implies not f.getName().toUpperCase().matches("%CTRL%")) and
// ES false positives (e.g., ES256 from AES256)
(result.matches("ES%") implies not f.getName().toUpperCase().matches("%AES%")) and
// RSA false positives
(result.matches("RSA") implies not f.getName().toUpperCase().matches("%UNIVERSAL%")) and
//rsaz functions deemed to be too low level, and can be ignored
not f.getLocation().getFile().getBaseName().matches("rsaz_exp.c") and
// General False positives
// Functions that 'get' do not set an algorithm, and therefore are considered ignorable
not f.getName().toLowerCase().matches("%get%")
}

View File

@@ -0,0 +1,153 @@
/**
* This file contains predicates create to build up initial data sets for OpenSSL
* predicates. E.g., These predicates were used to assist in associating all
* openSSL functions with their known crypto algorithms.
*/
import cpp
import experimental.cryptography.CryptoAlgorithmNames
import experimental.cryptography.utils.OpenSSL.CryptoFunction
private string basicNormalizeFunctionName(Function f, string algType) {
isKnownAlgorithm(result, algType) and
exists(string normStr | normStr = f.getName().toUpperCase().regexpReplaceAll("[-_ ]|/", "") |
normStr.matches("%" + result + "%")
)
}
/**
* Converts a raw OpenSSL algorithm to a normalized algorithm name.
*
* If more than one match occurs for a given algorithm type, normalize attempts to find the "max"
* string (max in terms of string length) e.g., matching AES128 to AES128 and not simply AES.
*
* An unknown algorithm is only identified if there exists no known algorithm found for any algorithm type.
*
* `f` is the function name to normalize.
* `algType` is a string representing the classification of the algorithm (see `CryptoAlgorithmNames`)
*/
private string privateNormalizeFunctionName(Function f, string algType) {
result = basicNormalizeFunctionName(f, algType) and
not exists(string res2 |
result != res2 and
res2 = basicNormalizeFunctionName(f, algType) and
res2.length() > result.length()
) and
// Addressing bad normalization case-by-case
// CASE: ES256 being identified when the algorithm is AES256
(
result.matches("ES256")
implies
not exists(string res2 | res2 = basicNormalizeFunctionName(f, _) and res2.matches("AES%"))
)
}
/**
* Normalizes a function name to a known algorithm name, similar to `normalizeName`.
* A function is not, however, allowed to be UNKNOWN. The function either
* normalizes to a known algorithm name, or the predicate does not hold (no result).
*
* The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false postive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.
*/
string normalizeFunctionName(Function f, string algType) {
algType != "UNKNOWN" and
result = privateNormalizeFunctionName(f, algType) and
openSSLLibraryFunc(f) and
// Addressing false positives
// For algorithm names less than or equal to 4, we must see the algorithm name
// in the original function as upper case (it can't be split between tokens)
// One exception found is DES_xcbc_encrypt, this is DESX
(
(result.length() <= 4 and result != "DESX")
implies
f.getName().toUpperCase().matches("%" + result + "%")
) and
(
(result.length() <= 4 and result = "DESX")
implies
(f.getName().toUpperCase().matches("%DESX%") or f.getName().toUpperCase().matches("%DES_X%"))
) and
// (result.length() <= 3 implies (not f.getName().toUpperCase().regexpMatch(".*" + result + "[a-zA-Z0-9].*|.*[a-zA-Z0-9]" + result + ".*")))
// and
// DES specific false positives
(
result.matches("DES")
implies
not f.getName().toUpperCase().regexpMatch(".*DES[a-zA-Z0-9].*|.*[a-zA-Z0-9]DES.*")
) and
// ((result.matches("%DES%")) implies not exists(string s | s in ["DESCRIBE", "DESTROY", "DESCRIPTION", "DESCRIPTOR", "NODES"] |
// f.getName().toUpperCase().matches("%" + s + "%"))) and
// SEED specific false positives
(
result.matches("%SEED%")
implies
not not exists(string s |
s in ["NEW_SEED", "GEN_SEED", "SET_SEED", "GET_SEED", "GET0_SEED", "RESEED", "SEEDING"]
|
f.getName().toUpperCase().matches("%" + s + "%")
)
) and
// ARIA specific false positives
(result.matches("%ARIA%") implies not f.getName().toUpperCase().matches("%VARIANT%"))
}
/**
* Predicate to support name normalization.
* Converts the raw name upper-case with no hyphen, slash, underscore, hash, or space.
* Looks for substrings that are known algorithms, and normalizes the name.
* If the algorithm cannot be determined or is in the ignorable list (`isIgnorableOpenSSLAlgorithm`)
* this predicate will not resolve a name.
*
* Rationale for private: For normalization, we want to get the longest string for a normalized name match
* for a given algorithm type. I found this easier to express if the public normalizeName
* checks that the name is the longest, and that UNKNOWN is reserved if there exists no
* result from this predicate that is known.
*/
bindingset[name]
string privateNormalizeName(string name, string algType) {
//not isIgnorableOpenSSLAlgorithm(name, _, _) and
// targetOpenSSLAlgorithm(name, _) and
isKnownAlgorithm(result, algType) and
exists(string normStr | normStr = name.toUpperCase().regexpReplaceAll("[-_ ]|/", "") |
normStr.matches("%" + result + "%")
)
}
/**
* Converts a raw OpenSSL algorithm to a normalized algorithm name.
*
* If more than one match occurs for a given algorithm type, normalize attempts to find the "max"
* string (max in terms of string length) e.g., matching AES128 to AES128 and not simply AES.
*
* An unknown algorithm is only identified if there exists no known algorithm found for any algorithm type.
*
* `name` is the name to normalize.
* `algType` is a string representing the classification of the algorithm (see `CryptoAlgorithmNames`)
*/
bindingset[name]
string normalizeName(string name, string algType) {
(
if exists(privateNormalizeName(name, _))
then result = privateNormalizeName(name, algType)
else (
result = unknownAlgorithm() and algType = "UNKNOWN"
)
) and
not exists(string res2 |
result != res2 and
res2 = privateNormalizeName(name, algType) and
res2.length() > result.length()
) and
// Addressing bad normalization case-by-case
// CASE: ES256 being identified when the algorithm is AES256
(
result.matches("ES256")
implies
not exists(string res2 | res2 = privateNormalizeName(name, _) and res2.matches("AES%"))
)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
import cpp
import experimental.cryptography.utils.OpenSSL.LibraryFunction
import semmle.code.cpp.ir.dataflow.DataFlow
// TODO: possible use of extensible predicates here
// NOTE: -1 for outInd represents the return value
predicate knownPassthroughFunction(Function f, int inInd, int outInd) {
// Trace through functions
// See https://www.openssl.org/docs/man1.1.1/man3/OBJ_obj2txt
// https://www.openssl.org/docs/man3.0/man3/EVP_CIPHER_get0_name
openSSLLibraryFunc(f) and
(
f.getName() in [
"OBJ_nid2obj", "OBJ_nid2ln", "OBJ_nid2sn", "OBJ_obj2nid", "OBJ_ln2nid", "OBJ_sn2nid",
"OBJ_txt2nid", "OBJ_txt2obj", "OBJ_dup", "EVP_CIPHER_get0_name"
] and
inInd = 0 and
outInd = -1
or
f.getName() in ["OBJ_obj2txt", "i2t_ASN1_OBJECT"] and
inInd = 2 and
outInd = 0
or
// Dup/copy pattern occurs in more places,
//see: https://www.openssl.org/docs/manmaster/man3/EC_KEY_copy.html and https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_dup.html
f.getName().matches("%_dup") and inInd = 0 and outInd = -1
or
f.getName().matches("%_copy") and inInd = 0 and outInd = -1
)
}
/**
* `c` is a call to a function that preserves the algorithm but changes its form.
* `onExpr` is the input argument passing through to, `outExpr` is the next expression in a dataflow step associated with `c`
*/
predicate knownPassthoughCall(Call c, Expr inExpr, Expr outExpr) {
exists(int inInd, int outInd |
knownPassthroughFunction(c.getTarget(), inInd, outInd) and
inExpr = c.getArgument(inInd) and
if outInd = -1 then outExpr = c else outExpr = c.getArgument(outInd)
)
}
/*
* Explicitly add flow through openssl functions that preserve the algorithm but alter the form (e.g., from NID to string)
*/
predicate knownPassThroughStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(Expr cur, Expr next |
(cur = node1.asExpr() or cur = node1.asIndirectArgument()) and
(
next = node2.asExpr() or
next = node2.asIndirectArgument() or
next = node2.asDefiningArgument()
)
|
exists(Call c | knownPassthoughCall(c, cur, next))
)
}

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.10.0-dev
version: 0.10.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -158,9 +158,7 @@ class NameQualifyingElement extends Element, @namequalifyingelement {
/**
* A special name-qualifying element. For example: `__super`.
*/
library class SpecialNameQualifyingElement extends NameQualifyingElement,
@specialnamequalifyingelement
{
class SpecialNameQualifyingElement extends NameQualifyingElement, @specialnamequalifyingelement {
/** Gets the name of this special qualifying element. */
override string getName() { specialnamequalifyingelements(underlyingElement(this), result) }

View File

@@ -73,6 +73,10 @@ private int isSource(Expr bufferExpr, Element why) {
)
}
/** Same as `getBufferSize`, but with the `why` column projected away to prevent large duplications. */
pragma[nomagic]
int getBufferSizeProj(Expr bufferExpr) { result = getBufferSize(bufferExpr, _) }
/**
* Get the size in bytes of the buffer pointed to by an expression (if this can be determined).
*/
@@ -87,7 +91,7 @@ int getBufferSize(Expr bufferExpr, Element why) {
why = bufferVar and
parentPtr = bufferExpr.(VariableAccess).getQualifier() and
parentPtr.getTarget().getUnspecifiedType().(PointerType).getBaseType() = parentClass and
result = getBufferSize(parentPtr, _) + bufferSize - parentClass.getSize()
result = getBufferSizeProj(parentPtr) + bufferSize - parentClass.getSize()
|
if exists(bufferVar.getType().getSize())
then bufferSize = bufferVar.getType().getSize()
@@ -95,7 +99,6 @@ int getBufferSize(Expr bufferExpr, Element why) {
)
or
// dataflow (all sources must be the same size)
result = unique(Expr def | DataFlow::localExprFlowStep(def, bufferExpr) | getBufferSize(def, _)) and
// find reason
result = unique(Expr def | DataFlow::localExprFlowStep(def, bufferExpr) | getBufferSizeProj(def)) and
exists(Expr def | DataFlow::localExprFlowStep(def, bufferExpr) | exists(getBufferSize(def, why)))
}

View File

@@ -27,9 +27,6 @@ predicate canValueFlow(Expr fromExpr, Expr toExpr) {
fromExpr = toExpr.(ConditionalExpr).getElse()
}
/** DEPRECATED: Alias for AnalyzedString */
deprecated class AnalysedString = AnalyzedString;
/**
* An analyzed null terminated string.
*/

View File

@@ -78,7 +78,7 @@ predicate parameterUsePair(Parameter p, VariableAccess va) {
/**
* Utility class: A definition or use of a stack variable.
*/
library class DefOrUse extends ControlFlowNodeBase {
class DefOrUse extends ControlFlowNodeBase {
DefOrUse() {
// Uninstantiated templates are purely syntax, and only on instantiation
// will they be complete with information about types, conversions, call
@@ -140,7 +140,7 @@ library class DefOrUse extends ControlFlowNodeBase {
}
/** A definition of a stack variable. */
library class Def extends DefOrUse {
class Def extends DefOrUse {
Def() { definition(_, this) }
override SemanticStackVariable getVariable(boolean isDef) {
@@ -155,7 +155,7 @@ private predicate parameterIsOverwritten(Function f, Parameter p) {
}
/** A definition of a parameter. */
library class ParameterDef extends DefOrUse {
class ParameterDef extends DefOrUse {
ParameterDef() {
// Optimization: parameters that are not overwritten do not require
// reachability analysis
@@ -169,7 +169,7 @@ library class ParameterDef extends DefOrUse {
}
/** A use of a stack variable. */
library class Use extends DefOrUse {
class Use extends DefOrUse {
Use() { useOfVar(_, this) }
override SemanticStackVariable getVariable(boolean isDef) {

View File

@@ -10,7 +10,7 @@ import SSAUtils
* The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA.
* This class provides the standard SSA logic.
*/
library class StandardSsa extends SsaHelper {
class StandardSsa extends SsaHelper {
StandardSsa() { this = 0 }
}

View File

@@ -114,7 +114,7 @@ private predicate live_at_exit_of_bb(StackVariable v, BasicBlock b) {
/** Common SSA logic for standard SSA and range-analysis SSA. */
cached
library class SsaHelper extends int {
class SsaHelper extends int {
/* 0 = StandardSSA, 1 = RangeSSA */
cached
SsaHelper() { this in [0 .. 1] }

View File

@@ -366,12 +366,12 @@ class CompileTimeConstantInt extends Expr {
int getIntValue() { result = val }
}
library class CompileTimeVariableExpr extends Expr {
class CompileTimeVariableExpr extends Expr {
CompileTimeVariableExpr() { not this instanceof CompileTimeConstantInt }
}
/** A helper class for evaluation of expressions. */
library class ExprEvaluator extends int {
class ExprEvaluator extends int {
/*
* 0 = ConditionEvaluator,
* 1 = SwitchEvaluator,
@@ -956,7 +956,7 @@ private predicate returnStmt(Function f, Expr value) {
}
/** A helper class for evaluation of conditions. */
library class ConditionEvaluator extends ExprEvaluator {
class ConditionEvaluator extends ExprEvaluator {
ConditionEvaluator() { this = 0 }
override predicate interesting(Expr e) {
@@ -967,7 +967,7 @@ library class ConditionEvaluator extends ExprEvaluator {
}
/** A helper class for evaluation of switch expressions. */
library class SwitchEvaluator extends ExprEvaluator {
class SwitchEvaluator extends ExprEvaluator {
SwitchEvaluator() { this = 1 }
override predicate interesting(Expr e) { e = getASwitchExpr(_, _) }
@@ -976,7 +976,7 @@ library class SwitchEvaluator extends ExprEvaluator {
private int getSwitchValue(Expr e) { exists(SwitchEvaluator x | result = x.getValue(e)) }
/** A helper class for evaluation of loop entry conditions. */
library class LoopEntryConditionEvaluator extends ExprEvaluator {
class LoopEntryConditionEvaluator extends ExprEvaluator {
LoopEntryConditionEvaluator() { this in [2 .. 3] }
abstract override predicate interesting(Expr e);
@@ -1149,7 +1149,7 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
}
/** A helper class for evaluation of while-loop entry conditions. */
library class WhileLoopEntryConditionEvaluator extends LoopEntryConditionEvaluator {
class WhileLoopEntryConditionEvaluator extends LoopEntryConditionEvaluator {
WhileLoopEntryConditionEvaluator() { this = 2 }
override predicate interesting(Expr e) { exists(WhileStmt while | e = while.getCondition()) }
@@ -1162,7 +1162,7 @@ library class WhileLoopEntryConditionEvaluator extends LoopEntryConditionEvaluat
}
/** A helper class for evaluation of for-loop entry conditions. */
library class ForLoopEntryConditionEvaluator extends LoopEntryConditionEvaluator {
class ForLoopEntryConditionEvaluator extends LoopEntryConditionEvaluator {
ForLoopEntryConditionEvaluator() { this = 3 }
override predicate interesting(Expr e) { exists(ForStmt for | e = for.getCondition()) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -874,28 +874,3 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
)
}
}
/**
* DEPRECATED: Use `BarrierGuard` module instead.
*
* A guard that validates some expression.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
* `checks` to specify what is being validated and in which branch.
*
* It is important that all extending classes in scope are disjoint.
*/
deprecated class BarrierGuard extends GuardCondition {
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
abstract predicate checks(Expr e, boolean b);
/** Gets a node guarded by this guard. */
final ExprNode getAGuardedNode() {
exists(SsaDefinition def, Variable v, boolean branch |
result.getExpr() = def.getAUse(v) and
this.checks(def.getAUse(v), branch) and
this.controls(result.getExpr().getBasicBlock(), branch)
)
}
}

View File

@@ -116,33 +116,6 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
none()
}
deprecated final override predicate isBarrierGuard(
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state)
}
/**
* Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps.
*/

View File

@@ -116,33 +116,6 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
none()
}
deprecated final override predicate isBarrierGuard(
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state)
}
/**
* Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps.
*/

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -91,21 +91,6 @@ abstract class Configuration extends string {
/** Holds if data flow out of `node` is prohibited. */
predicate isBarrierOut(Node node) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
/**
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
*
* Holds if data flow through nodes guarded by `guard` is prohibited when
* the flow state is `state`
*/
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
/**
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
*/
@@ -225,29 +210,6 @@ abstract private class ConfigurationRecursionPrevention extends Configuration {
}
}
/** A bridge class to access the deprecated `isBarrierGuard`. */
private class BarrierGuardGuardedNodeBridge extends Unit {
abstract predicate guardedNode(Node n, Configuration config);
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
}
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
deprecated override predicate guardedNode(Node n, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g) and
n = g.getAGuardedNode()
)
}
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
exists(BarrierGuard g |
config.isBarrierGuard(g, state) and
n = g.getAGuardedNode()
)
}
}
private FlowState relevantState(Configuration config) {
config.isSource(_, result) or
config.isSink(_, result) or
@@ -288,9 +250,7 @@ private module Config implements FullStateConfigSig {
predicate isBarrier(Node node, FlowState state) {
getConfig(state).isBarrier(node, getState(state)) or
getConfig(state).isBarrier(node) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getState(state), getConfig(state)) or
any(BarrierGuardGuardedNodeBridge b).guardedNode(node, getConfig(state))
getConfig(state).isBarrier(node)
}
predicate isBarrierIn(Node node) { any(Configuration config).isBarrierIn(node) }

View File

@@ -555,7 +555,7 @@ predicate instructionForFullyConvertedCall(Instruction instr, CallInstruction ca
}
/** Holds if `node` represents the output node for `call`. */
private predicate simpleOutNode(Node node, CallInstruction call) {
predicate simpleOutNode(Node node, CallInstruction call) {
operandForFullyConvertedCall(node.asOperand(), call)
or
instructionForFullyConvertedCall(node.asInstruction(), call)

View File

@@ -1696,16 +1696,7 @@ private module Cached {
// Reverse flow: data that flows from the definition node back into the indirection returned
// by a function. This allows data to flow 'in' through references returned by a modeled
// function such as `operator[]`.
exists(Operand address, int indirectionIndex |
nodeHasOperand(nodeTo.(IndirectReturnOutNode), address, indirectionIndex)
|
exists(StoreInstruction store |
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
store.getDestinationAddressOperand() = address
)
or
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
)
reverseFlow(nodeFrom, nodeTo)
}
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
@@ -1736,6 +1727,39 @@ private module Cached {
)
)
}
private predicate reverseFlow(Node nodeFrom, Node nodeTo) {
reverseFlowOperand(nodeFrom, nodeTo)
or
reverseFlowInstruction(nodeFrom, nodeTo)
}
private predicate reverseFlowOperand(Node nodeFrom, IndirectReturnOutNode nodeTo) {
exists(Operand address, int indirectionIndex |
nodeHasOperand(nodeTo, address, indirectionIndex)
|
exists(StoreInstruction store |
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
store.getDestinationAddressOperand() = address
)
or
// We also want a write coming out of an `OutNode` to flow `nodeTo`.
// This is different from `reverseFlowInstruction` since `nodeFrom` can never
// be an `OutNode` when it's defined by an instruction.
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
)
}
private predicate reverseFlowInstruction(Node nodeFrom, IndirectReturnOutNode nodeTo) {
exists(Instruction address, int indirectionIndex |
nodeHasInstruction(nodeTo, address, indirectionIndex)
|
exists(StoreInstruction store |
nodeHasInstruction(nodeFrom, store, indirectionIndex - 1) and
store.getDestinationAddress() = address
)
)
}
}
import Cached
@@ -2213,35 +2237,3 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
)
}
}
/**
* DEPRECATED: Use `BarrierGuard` module instead.
*
* A guard that validates some instruction.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
* `checks` to specify what is being validated and in which branch.
*
* It is important that all extending classes in scope are disjoint.
*/
deprecated class BarrierGuard extends IRGuardCondition {
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
predicate checksInstr(Instruction instr, boolean b) { none() }
/** Override this predicate to hold if this guard validates `expr` upon evaluating to `b`. */
predicate checks(Expr e, boolean b) { none() }
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
exists(ValueNumber value, boolean edge |
(
this.checksInstr(value.getAnInstruction(), edge)
or
this.checks(value.getAnInstruction().getConvertedResultExpression(), edge)
) and
result.asInstruction() = value.getAnInstruction() and
this.controls(result.asInstruction().getBlock(), edge)
)
}
}

View File

@@ -6,6 +6,7 @@
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import DataFlowUtil
private import DataFlowPrivate
private import SsaInternals as Ssa
/**
@@ -35,7 +36,7 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
*/
Node callOutput(CallInstruction call, FunctionOutput output) {
// The return value
result.asInstruction() = call and
simpleOutNode(result, call) and
output.isReturnValue()
or
// The side effect of a call on the value pointed to by an argument or qualifier
@@ -82,7 +83,7 @@ Node callOutput(CallInstruction call, FunctionOutput output, int d) {
// If there isn't an indirect out node for the call with indirection `d` then
// we conflate this with the underlying `CallInstruction`.
not exists(getIndirectReturnOutNode(call, d)) and
n.asInstruction() = result.asInstruction()
n = result
or
// The side effect of a call on the value pointed to by an argument or qualifier
exists(Operand operand, int indirectionIndex |

View File

@@ -374,6 +374,8 @@ module ProductFlow {
predicate isBarrier(DataFlow::Node node, FlowState state) { Config::isBarrier1(node, state) }
predicate isBarrier(DataFlow::Node node) { Config::isBarrier1(node) }
predicate isBarrierOut(DataFlow::Node node) { Config::isBarrierOut1(node) }
predicate isAdditionalFlowStep(
@@ -408,6 +410,8 @@ module ProductFlow {
predicate isBarrier(DataFlow::Node node, FlowState state) { Config::isBarrier2(node, state) }
predicate isBarrier(DataFlow::Node node) { Config::isBarrier2(node) }
predicate isBarrierOut(DataFlow::Node node) { Config::isBarrierOut2(node) }
predicate isAdditionalFlowStep(

View File

@@ -815,7 +815,7 @@ private module Cached {
) {
indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
exists(Instruction load, Operand address |
address.getDef() = instr and
address = unique( | | getAUse(instr)) and
isDereference(load, address, false) and
instrRepr = load and
indirectionIndexRepr = indirectionIndex - 1

View File

@@ -116,33 +116,6 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
none()
}
deprecated final override predicate isBarrierGuard(
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state)
}
/**
* Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps.
*/

View File

@@ -116,33 +116,6 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
none()
}
deprecated final override predicate isBarrierGuard(
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state)
}
/**
* Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps.
*/

View File

@@ -116,33 +116,6 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard)
}
/**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
none()
}
deprecated final override predicate isBarrierGuard(
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state)
}
/**
* Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow and taint steps.
*/

View File

@@ -8,6 +8,22 @@ private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
* sort keys of the block (derived from its first instruction)
*/
pragma[nomagic]
private predicate blockSortKeys(
IRFunction func, IRBlockBase block, int sortOverride, int sortKey1, int sortKey2
) {
block.getEnclosingIRFunction() = func and
block.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if block.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
}
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
@@ -37,17 +53,14 @@ class IRBlockBase extends TIRBlock {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
exists(IRFunction func |
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
blockSortKeys(func, funcBlock, sortOverride, sortKey1, sortKey2)
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
)
}
/**

View File

@@ -116,14 +116,14 @@ class Instruction extends Construction::TStageInstruction {
private int getLineRank() {
this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
exists(IRFunction enclosing, Language::File file, int line |
this =
rank[result](Instruction instr |
instr = getAnInstructionAtLine(enclosing, file, line)
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
)
}
/**

View File

@@ -8,6 +8,22 @@ private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
* sort keys of the block (derived from its first instruction)
*/
pragma[nomagic]
private predicate blockSortKeys(
IRFunction func, IRBlockBase block, int sortOverride, int sortKey1, int sortKey2
) {
block.getEnclosingIRFunction() = func and
block.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if block.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
}
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
@@ -37,17 +53,14 @@ class IRBlockBase extends TIRBlock {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
exists(IRFunction func |
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
blockSortKeys(func, funcBlock, sortOverride, sortKey1, sortKey2)
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
)
}
/**

View File

@@ -116,14 +116,14 @@ class Instruction extends Construction::TStageInstruction {
private int getLineRank() {
this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
exists(IRFunction enclosing, Language::File file, int line |
this =
rank[result](Instruction instr |
instr = getAnInstructionAtLine(enclosing, file, line)
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
)
}
/**

View File

@@ -423,7 +423,12 @@ private module CachedForDebugging {
cached
predicate instructionHasSortKeys(Instruction instruction, int key1, int key2) {
key1 = getInstructionTranslatedElement(instruction).getId() and
getInstructionTag(instruction) =
getInstructionTag(instruction) = tagByRank(key2)
}
pragma[nomagic]
private InstructionTag tagByRank(int key2) {
result =
rank[key2](InstructionTag tag, string tagId |
tagId = getInstructionTagId(tag)
|

View File

@@ -8,6 +8,22 @@ private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
* sort keys of the block (derived from its first instruction)
*/
pragma[nomagic]
private predicate blockSortKeys(
IRFunction func, IRBlockBase block, int sortOverride, int sortKey1, int sortKey2
) {
block.getEnclosingIRFunction() = func and
block.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if block.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
}
/**
* A basic block in the IR. A basic block consists of a sequence of `Instructions` with the only
* incoming edges at the beginning of the sequence and the only outgoing edges at the end of the
@@ -37,17 +53,14 @@ class IRBlockBase extends TIRBlock {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
exists(IRFunction func |
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
blockSortKeys(func, funcBlock, sortOverride, sortKey1, sortKey2)
|
funcBlock order by sortOverride, sortKey1, sortKey2
)
)
}
/**

View File

@@ -116,14 +116,14 @@ class Instruction extends Construction::TStageInstruction {
private int getLineRank() {
this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
exists(IRFunction enclosing, Language::File file, int line |
this =
rank[result](Instruction instr |
instr = getAnInstructionAtLine(enclosing, file, line)
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
)
}
/**

View File

@@ -29,7 +29,7 @@ private import RangeAnalysisUtils
* The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA.
* This class provides the range-analysis SSA logic.
*/
library class RangeSsa extends SsaHelper {
class RangeSsa extends SsaHelper {
RangeSsa() { this = 1 }
/**

View File

@@ -284,10 +284,33 @@ private module Config implements ProductFlow::StateConfigSig {
pointerAddInstructionHasBounds0(_, allocSink, sizeSink, sizeAddend)
}
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
node = SizeBarrier::getABarrierNode(state)
}
predicate isBarrier2(DataFlow::Node node) {
// Block flow from `*p` to `*(p + n)` when `n` is not `0`. This removes
// false positives
// when tracking the size of the allocation as an element of an array such
// as:
// ```
// size_t* p = new size_t[n];
// ...
// p[0] = n;
// int i = p[1];
// p[i] = ...
// ```
// In the above case, this barrier blocks flow from the indirect node
// for `p` to `p[1]`.
exists(Operand operand, PointerAddInstruction add |
node.(IndirectOperand).hasOperandAndIndirectionIndex(operand, _) and
add.getLeftOperand() = operand and
add.getRight().(ConstantInstruction).getValue() != "0"
)
}
predicate isBarrierIn1(DataFlow::Node node) { isSourcePair(node, _, _, _) }
predicate isBarrierOut2(DataFlow::Node node) {

View File

@@ -1,3 +1,16 @@
## 0.8.0
### Query Metadata Changes
* The `cpp/double-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.
* The `cpp/use-after-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.
### Minor Analysis Improvements
* The queries `cpp/double-free` and `cpp/use-after-free` find fewer false positives
in cases where a non-returning function is called.
* The number of duplicated dataflow paths reported by queries has been significantly reduced.
## 0.7.5
No user-facing changes.

View File

@@ -5,10 +5,12 @@
* it should be moved before the dereference.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id cpp/redundant-null-check-simple
* @tags reliability
* correctness
* security
* external/cwe/cwe-476
*/

View File

@@ -161,7 +161,7 @@ private predicate annotatesAtPosition(SalPosition pos, DeclarationEntry d, File
* A SAL element, that is, a SAL annotation or a declaration entry
* that may have SAL annotations.
*/
library class SalElement extends Element {
class SalElement extends Element {
SalElement() {
containsSalAnnotation(this.(DeclarationEntry).getFile()) or
this instanceof SalAnnotation

View File

@@ -13,15 +13,13 @@
import cpp
import semmle.code.cpp.commons.Environment
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.ir.IR
import Flow::PathGraph
/** A call that prints its arguments to `stdout`. */
class PrintStdoutCall extends FunctionCall {
PrintStdoutCall() {
this.getTarget().hasGlobalOrStdName("puts") or
this.getTarget().hasGlobalOrStdName("printf")
}
PrintStdoutCall() { this.getTarget().hasGlobalOrStdName(["puts", "printf"]) }
}
/** A read of the QUERY_STRING environment variable */
@@ -29,19 +27,25 @@ class QueryString extends EnvironmentRead {
QueryString() { this.getEnvironmentVariable() = "QUERY_STRING" }
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSource(Expr source) { source instanceof QueryString }
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asIndirectExpr() instanceof QueryString }
override predicate isSink(Element tainted) {
exists(PrintStdoutCall call | call.getAnArgument() = tainted)
predicate isSink(DataFlow::Node node) {
exists(PrintStdoutCall call | call.getAnArgument() = [node.asIndirectExpr(), node.asExpr()])
}
override predicate isBarrier(Expr e) {
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
predicate isBarrier(DataFlow::Node node) {
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
or
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
}
}
from QueryString query, Element printedArg, PathNode sourceNode, PathNode sinkNode
where taintedWithPath(query, printedArg, sourceNode, sinkNode)
select printedArg, sourceNode, sinkNode, "Cross-site scripting vulnerability due to $@.", query,
"this query data"
module Flow = TaintTracking::Global<Config>;
from QueryString query, Flow::PathNode sourceNode, Flow::PathNode sinkNode
where
Flow::flowPath(sourceNode, sinkNode) and
query = sourceNode.getNode().asIndirectExpr()
select sinkNode.getNode(), sourceNode, sinkNode, "Cross-site scripting vulnerability due to $@.",
query, "this query data"

View File

@@ -82,36 +82,20 @@ module ValidState {
* library will perform, and visit all the places where the size argument is modified.
* 2. Once that dataflow traversal is done, we accumulate the offsets added at each places
* where the offset is modified (see `validStateImpl`).
*
* Because we want to guarantee that each place where we modify the offset has a `PathNode`
* we "flip" a boolean flow state in each `isAdditionalFlowStep`. This ensures that the node
* has a corresponding `PathNode`.
*/
private module ValidStateConfig implements DataFlow::StateConfigSig {
class FlowState = boolean;
private module ValidStateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { hasSize(_, source, _) }
predicate isSource(DataFlow::Node source, FlowState state) {
hasSize(_, source, _) and
state = false
}
predicate isSink(DataFlow::Node sink) { isSinkPairImpl(_, _, sink, _, _) }
predicate isSink(DataFlow::Node sink, FlowState state) {
isSinkPairImpl(_, _, sink, _, _) and
state = [false, true]
}
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
isAdditionalFlowStep2(node1, node2, _) and
state1 = [false, true] and
state2 = state1.booleanNot()
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
isAdditionalFlowStep2(node1, node2, _)
}
predicate includeHiddenNodes() { any() }
}
private import DataFlow::GlobalWithState<ValidStateConfig>
private import DataFlow::Global<ValidStateConfig>
private predicate inLoop(PathNode n) { n.getASuccessor+() = n }

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The number of duplicated dataflow paths reported by queries has been significantly reduced.

View File

@@ -1,5 +0,0 @@
---
category: minorAnalysis
---
* The queries `cpp/double-free` and `cpp/use-after-free` find fewer false positives
in cases where a non-returning function is called.

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* The `cpp/double-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* The `cpp/use-after-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.

View File

@@ -0,0 +1,6 @@
---
category: newQuery
---
* The query `cpp/redundant-null-check-simple` has been promoted to Code Scanning. The query finds cases where a pointer is compared to null after it has already been dereferenced. Such comparisons likely indicate a bug at the place where the pointer is dereferenced, or where the pointer is compared to null.
Note: This query was incorrectly noted as being promoted to Code Scanning in CodeQL version 2.14.6.

View File

@@ -0,0 +1,12 @@
## 0.8.0
### Query Metadata Changes
* The `cpp/double-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.
* The `cpp/use-after-free` query has been further improved to reduce false positives and its precision has been increased from `medium` to `high`.
### Minor Analysis Improvements
* The queries `cpp/double-free` and `cpp/use-after-free` find fewer false positives
in cases where a non-returning function is called.
* The number of duplicated dataflow paths reported by queries has been significantly reduced.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.7.5
lastReleaseVersion: 0.8.0

View File

@@ -0,0 +1,19 @@
/**
* @name Unknown key generation key size
* @description
* @id cpp/unknown-asymmetric-key-gen-size
* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-326
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricKeyGeneration op, AsymmetricAlgorithm alg
where
alg = op.getAlgorithm() and
not alg instanceof EllipticCurveAlgorithm and
not exists(op.getKeySizeInBits(alg))
select op, "Use of unknown asymmetric key size for algorithm $@", alg, alg.getName().toString()

View File

@@ -0,0 +1,23 @@
/**
* @name Weak asymmetric key generation key size (< 2048 bits)
* @description
* @id cpp/weak-asymmetric-key-gen-size
* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-326
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricKeyGeneration op, AsymmetricAlgorithm alg, Expr configSrc, int size
where
alg = op.getAlgorithm() and
not alg instanceof EllipticCurveAlgorithm and
configSrc = op.getKeyConfigurationSource(alg) and
size = configSrc.getValue().toInt() and
size < 2048
select op,
"Use of weak asymmetric key size (in bits) " + size + " configured at $@ for algorithm $@",
configSrc, configSrc.toString(), alg, alg.getName().toString()

View File

@@ -0,0 +1,34 @@
/**
* @name Weak block mode
* @description Finds uses of symmetric encryption block modes that are weak, obsolete, or otherwise unaccepted.
* @id cpp/weak-block-mode
* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327
*/
import cpp
import experimental.cryptography.Concepts
from BlockModeAlgorithm alg, string name, string msg, Expr confSink
where
exists(string tmpMsg |
(
name = alg.getBlockModeName() and
name = unknownAlgorithm() and
tmpMsg = "Use of unrecognized block mode algorithm."
or
name != unknownAlgorithm() and
name = alg.getBlockModeName() and
not name = ["CBC", "CTS", "XTS"] and
tmpMsg = "Use of weak block mode algorithm " + name + "."
) and
if alg.hasConfigurationSink() and alg.configurationSink() != alg
then (
confSink = alg.configurationSink() and msg = tmpMsg + " Algorithm used at sink: $@."
) else (
confSink = alg and msg = tmpMsg
)
)
select alg, msg, confSink, confSink.toString()

View File

@@ -0,0 +1,40 @@
/**
* @name Weak elliptic curve
* @description Finds uses of weak, unknown, or otherwise unaccepted elliptic curve algorithms.
* @id cpp/weak-elliptic-curve
* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327
*/
import cpp
import experimental.cryptography.Concepts
from EllipticCurveAlgorithm alg, string name, string msg, Expr confSink
where
exists(string tmpMsg |
(
name = alg.getCurveName() and
name = unknownAlgorithm() and
tmpMsg = "Use of unrecognized curve algorithm."
or
name != unknownAlgorithm() and
name = alg.getCurveName() and
not name =
[
"SECP256R1", "PRIME256V1", //P-256
"SECP384R1", //P-384
"SECP521R1", //P-521
"ED25519", "X25519"
] and
tmpMsg = "Use of weak curve algorithm " + name + "."
) and
if alg.hasConfigurationSink() and alg.configurationSink() != alg
then (
confSink = alg.configurationSink() and msg = tmpMsg + " Algorithm used at sink: $@."
) else (
confSink = alg and msg = tmpMsg
)
)
select alg, msg, confSink, confSink.toString()

View File

@@ -0,0 +1,41 @@
/**
* @name Weak cryptography
* @description Finds explicit uses of symmetric encryption algorithms that are weak, unknown, or otherwise unaccepted.
* @kind problem
* @id cpp/weak-crypto/banned-encryption-algorithms
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327
*/
import cpp
import experimental.cryptography.Concepts
from SymmetricEncryptionAlgorithm alg, Expr confSink, string msg
where
exists(string resMsg |
(
if alg.getEncryptionName() = unknownAlgorithm()
then (
alg instanceof Literal and
resMsg =
"Use of unrecognized symmetric encryption algorithm: " +
alg.(Literal).getValueText().toString() + "."
or
not alg instanceof Literal and
resMsg = "Use of unrecognized symmetric encryption algorithm."
) else (
not alg.getEncryptionName().matches("AES%") and
resMsg = "Use of banned symmetric encryption algorithm: " + alg.getEncryptionName() + "."
)
) and
(
if alg.hasConfigurationSink() and alg.configurationSink() != alg
then (
confSink = alg.configurationSink() and msg = resMsg + " Algorithm used at sink: $@."
) else (
confSink = alg and msg = resMsg
)
)
)
select alg, msg, confSink, confSink.toString()

View File

@@ -0,0 +1,36 @@
/**
* @name Weak cryptography
* @description Finds explicit uses of cryptographic hash algorithms that are weak and obsolete.
* @kind problem
* @id cpp/weak-crypto/banned-hash-algorithms
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow as ASTDataFlow
import experimental.cryptography.Concepts
from HashAlgorithm alg, Expr confSink, string msg
where
exists(string name, string msgTmp | name = alg.getHashName() |
not name = ["SHA256", "SHA384", "SHA512"] and
(
if name = unknownAlgorithm()
then
not alg instanceof Literal and msgTmp = "Use of unrecognized hash algorithm."
or
alg instanceof Literal and
msgTmp =
"Use of unrecognized hash algorithm: " + alg.(Literal).getValueText().toString() + "."
else msgTmp = "Use of banned hash algorithm " + name + "."
) and
if alg.hasConfigurationSink() and alg.configurationSink() != alg
then (
confSink = alg.configurationSink() and msg = msgTmp + " Algorithm used at sink: $@."
) else (
confSink = alg and msg = msgTmp
)
)
select alg, msg, confSink, confSink.toString()

View File

@@ -0,0 +1,16 @@
/**
* @name All Asymmetric Algorithms
* @description Finds all potential usage of asymmeric keys (RSA & ECC) using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/all-asymmetric-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricAlgorithm alg
select alg, "Use of algorithm " + alg.getName()

View File

@@ -0,0 +1,16 @@
/**
* @name All Cryptographic Algorithms
* @description Finds all potential usage of cryptographic algorithms usage using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/all-cryptographic-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from CryptographicAlgorithm alg
select alg, "Use of algorithm " + alg.getName()

View File

@@ -0,0 +1,16 @@
/**
* @name Asymmetric Encryption Algorithms
* @description Finds all potential usage of asymmeric keys for encryption or key exchange using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/all-asymmetric-encryption-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricEncryptionAlgorithm alg
select alg, "Use of algorithm " + alg.getEncryptionName()

View File

@@ -0,0 +1,16 @@
/**
* @name Asymmetric Padding Schemes
* @description Finds all potential usage of padding schemes used with asymmeric algorithms.
* @kind problem
* @id cpp/quantum-readiness/cbom/asymmetric-padding-schemes
* @problem.severity error
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
// TODO: currently not modeled for any API
from AsymmetricPadding alg
select alg, "Use of algorithm " + alg.getPaddingName()

View File

@@ -0,0 +1,16 @@
/**
* @name Authenticated Encryption Algorithms
* @description Finds all potential usage of authenticated encryption schemes using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/authenticated-encryption-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from AuthenticatedEncryptionAlgorithm alg
select alg, "Use of algorithm " + alg.getAuthticatedEncryptionName()

View File

@@ -0,0 +1,16 @@
/**
* @name Block cipher mode of operation
* @description Finds all potential block cipher modes of operations using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/block-cipher-mode
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from BlockModeAlgorithm alg
select alg, "Use of algorithm " + alg.getBlockModeName()

View File

@@ -0,0 +1,17 @@
/**
* @name Initialization Vector (IV) or nonces
* @description Finds all potential sources for initialization vectors (IV) or nonce used in block ciphers while using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/iv-sources
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
// TODO: currently not modeled for any API
from BlockModeAlgorithm alg
select alg.getIVorNonce(), "Block mode IV/Nonce source"

View File

@@ -0,0 +1,18 @@
/**
* @name Unknown Initialization Vector (IV) or nonces
* @description Finds all potentially unknown sources for initialization vectors (IV) or nonce used in block ciphers while using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/unkown-iv-sources
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
// TODO: currently not modeled for any API
from BlockModeAlgorithm alg
where not alg.hasIVorNonce()
select alg, "Block mode with unknown IV or Nonce configuration"

View File

@@ -0,0 +1,20 @@
/**
* @name Elliptic Curve Key length
* @description Finds all potential key lengths for elliptic curve algorithms usage.
* @kind problem
* @id cpp/quantum-readiness/cbom/elliptic-curve-key-length
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from EllipticCurveAlgorithm alg, string size
where
if not exists(alg.getCurveBitSize())
then size = "UNKNOWN SIZE"
else size = alg.getCurveBitSize().toString()
select alg, "Use of algorithm " + alg.getCurveName() + " with key size (in bits) " + size

View File

@@ -0,0 +1,16 @@
/**
* @name Elliptic Curve Algorithms
* @description Finds all potential usage of elliptic curve algorithms using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/elliptic-curve-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from EllipticCurveAlgorithm alg
select alg, "Use of algorithm " + alg.getCurveName()

View File

@@ -0,0 +1,16 @@
/**
* @name Hash Algorithms
* @description Finds all potential usage of cryptographic hash algorithms using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/hash-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from HashAlgorithm alg
select alg, "Use of algorithm " + alg.getName()

View File

@@ -0,0 +1,16 @@
/**
* @name Key Exchange Algorithms
* @description Finds all potential usage of key exchange using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/key-exchange
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from KeyExchangeAlgorithm alg
select alg, "Use of algorithm " + alg.getName()

View File

@@ -0,0 +1,20 @@
/**
* @name Known asymmetric key source generation
* @description Finds all known potential sources for asymmetric key generation while using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/asymmetric-key-generation
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricKeyGeneration op, CryptographicAlgorithm alg, Expr configSrc
where
alg = op.getAlgorithm() and
configSrc = op.getKeyConfigurationSource(alg)
select op, "Key generator for algorithm $@ with key configuration $@", alg, alg.getName(),
configSrc, configSrc.toString()

View File

@@ -0,0 +1,17 @@
/**
* @name Signing Algorithms
* @description Finds all potential usage of signing algorithms using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/signing-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
// TODO: currently not modeled for any API
from SigningAlgorithm alg
select alg, "Use of algorithm " + alg.getName()

View File

@@ -0,0 +1,16 @@
/**
* @name Symmetric Encryption Algorithms
* @description Finds all potential usage of symmetric encryption algorithms using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/symmetric-encryption-algorithms
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from SymmetricEncryptionAlgorithm alg
select alg, "Use of algorithm " + alg.getEncryptionName()

View File

@@ -0,0 +1,16 @@
/**
* @name Symmetric Padding Schemes
* @description Finds all potential usage of padding schemes used with symmeric algorithms.
* @kind problem
* @id cpp/quantum-readiness/cbom/symmetric-padding-schemes
* @problem.severity error
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
// TODO: currently not modeled for any API
from SymmetricPadding alg
select alg, "Use of algorithm " + alg.getPaddingName()

View File

@@ -0,0 +1,19 @@
/**
* @name Unknown asymmetric key source generation
* @description Finds all unknown potential sources for asymmetric key generation while using the supported libraries.
* @kind problem
* @id cpp/quantum-readiness/cbom/unkwon-asymmetric-key-generation
* @problem.severity error
* @precision high
* @tags cbom
* cryptography
*/
import cpp
import experimental.cryptography.Concepts
from AsymmetricKeyGeneration op, CryptographicAlgorithm alg
where
alg = op.getAlgorithm() and
not op.hasKeyConfigurationSource(alg)
select op, "Key generator for algorithm $@ with unknown configuration source", alg, alg.getName()

View File

@@ -0,0 +1 @@
No existing 'old models' for inventories

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.8.0-dev
version: 0.8.1-dev
groups:
- cpp
- queries

View File

@@ -36,6 +36,8 @@ edges
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr |
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf |
| test.cpp:146:26:146:26 | p indirection | test.cpp:148:6:148:9 | * ... |
| test.cpp:146:26:146:26 | p indirection | test.cpp:149:6:149:9 | * ... |
| test.cpp:146:26:146:26 | p indirection | test.cpp:150:6:150:9 | * ... |
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... |
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | & ... indirection |
| test.cpp:158:17:158:18 | & ... indirection | test.cpp:146:26:146:26 | p indirection |
@@ -123,6 +125,8 @@ nodes
| test.cpp:143:18:143:21 | asdf | semmle.label | asdf |
| test.cpp:146:26:146:26 | p indirection | semmle.label | p indirection |
| test.cpp:148:6:148:9 | * ... | semmle.label | * ... |
| test.cpp:149:6:149:9 | * ... | semmle.label | * ... |
| test.cpp:150:6:150:9 | * ... | semmle.label | * ... |
| test.cpp:156:12:156:14 | buf | semmle.label | buf |
| test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... |
| test.cpp:158:17:158:18 | & ... indirection | semmle.label | & ... indirection |
@@ -176,6 +180,8 @@ subpaths
| test.cpp:128:9:128:14 | PointerAdd: access to array | test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:125:11:125:13 | arr | arr | test.cpp:128:9:128:18 | Store: ... = ... | write |
| test.cpp:136:9:136:16 | PointerAdd: ... += ... | test.cpp:143:18:143:21 | asdf | test.cpp:138:13:138:15 | arr | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:142:10:142:13 | asdf | asdf | test.cpp:138:12:138:15 | Load: * ... | read |
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:148:6:148:9 | * ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write |
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:149:6:149:9 | * ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:148:3:148:13 | Store: ... = ... | write |
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:150:6:150:9 | * ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:149:3:149:13 | Store: ... = ... | write |
| test.cpp:221:5:221:11 | PointerAdd: access to array | test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:217:19:217:24 | buffer | buffer | test.cpp:221:5:221:15 | Store: ... = ... | write |
| test.cpp:232:5:232:10 | PointerAdd: access to array | test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:228:10:228:14 | array | array | test.cpp:232:5:232:19 | Store: ... = ... | write |
| test.cpp:261:27:261:30 | PointerAdd: access to array | test.cpp:286:19:286:25 | buffer2 | test.cpp:261:27:261:30 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:285:19:285:25 | buffer2 | buffer2 | test.cpp:261:27:261:30 | Load: access to array | read |

View File

@@ -1,3 +1,3 @@
failures
astTypeBugs
irTypeBugs
failures

View File

@@ -16,18 +16,18 @@ edges
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | filename indirection |
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | path indirection |
| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument |
| test.cpp:106:20:106:25 | call to getenv | test.cpp:107:33:107:36 | path indirection |
| test.cpp:106:20:106:38 | call to getenv | test.cpp:107:33:107:36 | path indirection |
| test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:107:33:107:36 | path indirection |
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | call to c_str indirection |
| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ |
| test.cpp:113:20:113:25 | call to getenv | test.cpp:114:19:114:22 | path indirection |
| test.cpp:113:20:113:38 | call to getenv | test.cpp:114:19:114:22 | path indirection |
| test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:19:114:22 | path indirection |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | call to c_str indirection |
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | call to c_str indirection |
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ |
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:10:114:23 | call to operator+ |
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | call to operator+ |
| test.cpp:119:20:119:25 | call to getenv | test.cpp:120:19:120:22 | path indirection |
| test.cpp:119:20:119:38 | call to getenv | test.cpp:120:19:120:22 | path indirection |
| test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:19:120:22 | path indirection |
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | call to data indirection |
| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | call to operator+ |
@@ -91,12 +91,12 @@ nodes
| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument |
| test.cpp:93:17:93:24 | filename indirection | semmle.label | filename indirection |
| test.cpp:94:45:94:48 | path indirection | semmle.label | path indirection |
| test.cpp:106:20:106:25 | call to getenv | semmle.label | call to getenv |
| test.cpp:106:20:106:38 | call to getenv | semmle.label | call to getenv |
| test.cpp:106:20:106:38 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
| test.cpp:107:33:107:36 | path indirection | semmle.label | path indirection |
| test.cpp:108:18:108:22 | call to c_str indirection | semmle.label | call to c_str indirection |
| test.cpp:113:20:113:25 | call to getenv | semmle.label | call to getenv |
| test.cpp:113:20:113:38 | call to getenv | semmle.label | call to getenv |
| test.cpp:113:20:113:38 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
@@ -104,7 +104,7 @@ nodes
| test.cpp:114:19:114:22 | path indirection | semmle.label | path indirection |
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
| test.cpp:119:20:119:25 | call to getenv | semmle.label | call to getenv |
| test.cpp:119:20:119:38 | call to getenv | semmle.label | call to getenv |
| test.cpp:119:20:119:38 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:120:10:120:30 | call to data indirection | semmle.label | call to data indirection |
| test.cpp:120:17:120:17 | call to operator+ | semmle.label | call to operator+ |
@@ -158,13 +158,13 @@ subpaths
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | call to getenv indirection | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | call to getenv indirection | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument |

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