Compare commits

...

361 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
ee314a4dad remove javascript 2021-09-29 11:19:08 +02:00
Mathias Vorreiter Pedersen
8dcf7926de Merge pull request #6760 from andersfugmann/relax_memberMayBeVarSize
Increase precision to high for cpp/static-buffer-overflow
2021-09-29 10:09:11 +02:00
Benjamin Muskalla
d09c3bf863 Merge pull request #6748 from bmuskalla/fixHiddenTypesTestGenerator
Java: Avoid stubbing methods with private parameter types
2021-09-29 09:27:13 +02:00
Anders Schack-Mulligen
1a92fa5d92 Merge pull request #6772 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-29 09:25:19 +02:00
github-actions[bot]
8d2ad4ed17 Add changed framework coverage reports 2021-09-29 00:08:05 +00:00
Benjamin Muskalla
5f659f6e48 Merge branch 'main' into fixHiddenTypesTestGenerator 2021-09-28 17:42:39 +02:00
Shati Patel
ee46717c76 Merge pull request #6771 from shati-patel/mergeback-3.2-main
Merge 3.2 into main
2021-09-28 14:52:17 +01:00
Jonas Jensen
914e621d1b Merge pull request #6678 from andersfugmann/refactor_use_of_isGuardPhi
C++: Refactor code to use predicate isGuardPhi/4
2021-09-28 15:45:05 +02:00
Shati Patel
976190e84d Merge pull request #6764 from shati-patel/slides-links
Docs: Fix a few links in the training slides
2021-09-28 14:35:46 +01:00
Mathias Vorreiter Pedersen
06eb93da3f Merge pull request #6769 from github/docfix-dead-links-in-readme
Fix dead links in README.md
2021-09-28 15:21:19 +02:00
Mathias Vorreiter Pedersen
7197f41e75 Fix dead links in README.md 2021-09-28 15:12:36 +02:00
Edoardo Pirovano
5488872044 Merge pull request #6505 from edoardopirovano/trailing-comma
QL Language Spec: Trailing comma in set literal
2021-09-28 13:45:09 +01:00
Chris Smowton
413ac4e8f4 Merge pull request #6684 from owen-mc/java/model/apache-collections-subpackages
Java: model remaining subpackages of Apache Commons Collections
2021-09-28 12:28:48 +01:00
Tony Torralba
cec6cd0830 Merge pull request #6724 from atorralba/atorralba/android-contentprovider-sources
Java: Add sources for content providers in Android
2021-09-28 12:13:54 +02:00
Chris Smowton
39a12a8464 Remove models that are no longer required 2021-09-28 10:48:43 +01:00
Tony Torralba
46eb27cd01 Don't restrict inputs to be ParameterNodes
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-28 11:21:56 +02:00
Anders Fugmann
ba98c0c1cb Merge remote-tracking branch 'upstream/main' into relax_memberMayBeVarSize 2021-09-28 11:15:11 +02:00
Anders Schack-Mulligen
fc8b439263 Merge pull request #6740 from aschackmull/java/callback-dispatch
Java: Add callback dispatch to more anonymous classes.
2021-09-28 10:49:27 +02:00
Anders Peter Fugmann
a358ea8667 C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 10:38:02 +02:00
Anders Schack-Mulligen
c294b75f6c Merge pull request #6766 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-28 10:35:43 +02:00
Shati Patel
d5e17f9ebf Merge pull request #6765 from shati-patel/docs-config-fixes
Docs: Fix inconsistencies in sphinx config files
2021-09-28 09:18:02 +01:00
Anders Peter Fugmann
c7ea7ca5cd C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 09:40:25 +02:00
Anders Peter Fugmann
49c656d904 C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 09:40:07 +02:00
Anders Fugmann
79549c2285 Merge remote-tracking branch 'upstream/main' into refactor_use_of_isGuardPhi 2021-09-28 09:38:16 +02:00
Owen Mansel-Chan
787f36f056 Add a change note 2021-09-28 07:32:28 +01:00
github-actions[bot]
b7b229d59b Add changed framework coverage reports 2021-09-28 00:08:59 +00:00
shati-patel
64fcbe05c3 Docs: Fix inconsistencies in sphinx config files 2021-09-27 18:54:23 +01:00
shati-patel
31c34870ef Fix warning about "Anonymous hyperlink mismatch" 2021-09-27 18:27:57 +01:00
shati-patel
3c17ac424d Docs: Fix some broken/redirected links 2021-09-27 18:27:30 +01:00
Felicity Chapman
bb6c079e5a Merge pull request #6762 from github/felicitymay-patch-1
Update links to match those on the staging site
2021-09-27 16:49:58 +01:00
Felicity Chapman
a3c1975a84 Update links to match those on the staging site 2021-09-27 16:35:22 +01:00
Owen Mansel-Chan
bdd78d2bc7 Fix stub 2021-09-27 16:24:41 +01:00
Owen Mansel-Chan
29db42c3cd Generate stubs 2021-09-27 16:24:40 +01:00
Owen Mansel-Chan
e6df8164cf Fix up old tests for new helper functions 2021-09-27 16:24:39 +01:00
Owen Mansel-Chan
cf03bd8bd1 Merge new and old tests
# Conflicts:
#	java/ql/test/library-tests/frameworks/apache-collections/TestNew.java
2021-09-27 16:24:38 +01:00
Owen Mansel-Chan
342c14887b Fix existing models for MapUtils 2021-09-27 16:24:37 +01:00
Owen Mansel-Chan
e1101e582e Minor improvement to existing tests 2021-09-27 16:24:37 +01:00
Owen Mansel-Chan
768203bd36 Remove redundant casts 2021-09-27 16:24:36 +01:00
Owen Mansel-Chan
c51fb00082 Add tests for non-public abstract classes 2021-09-27 16:24:35 +01:00
Owen Mansel-Chan
0a92b04c8b Fix up automatically generated tests 2021-09-27 16:24:34 +01:00
Owen Mansel-Chan
15161d8867 Make concrete subclasses of abstract classes 2021-09-27 16:24:33 +01:00
Owen Mansel-Chan
53ee465726 Fix errors in generated tests that stop compilation 2021-09-27 16:24:32 +01:00
Owen Mansel-Chan
a20acfee25 Add automatically generated tests
Also update test.ql to use the new InlineFlowTest.
2021-09-27 16:24:31 +01:00
Owen Mansel-Chan
f69787afd0 Miscellaneous model fixes 2021-09-27 16:24:30 +01:00
Owen Mansel-Chan
9b12980688 Do not model some protected methods 2021-09-27 16:24:29 +01:00
Owen Mansel-Chan
cb0f82c36e Do not modelled protected static inner classes 2021-09-27 16:24:29 +01:00
Owen Mansel-Chan
3b678bfbc5 Address review comments 2021-09-27 16:24:28 +01:00
Owen Mansel-Chan
e1750adc38 Address problems highlighted by generating tests 2021-09-27 16:24:27 +01:00
Owen Mansel-Chan
fd0fb9483e Model the remaining subpackages in Apache Commons Collections 2021-09-27 16:24:26 +01:00
Owen Mansel-Chan
3d1d491e6b Model java.lang.Object.clone() better for access paths.
Model value flow for Element, MapKey and MapValue. This assumes
that clone() is a shallow copy.
2021-09-27 16:24:25 +01:00
Edoardo Pirovano
18020707b8 QL Language Spec: Trailing comma in set literal 2021-09-27 15:57:39 +01:00
Anders Schack-Mulligen
cfa0d46b73 Merge pull request #6097 from atorralba/atorralba/promote-xslt-injection
Java: Promote XSLT Injection from experimental
2021-09-27 13:14:57 +02:00
Anders Schack-Mulligen
e027d514f1 Merge pull request #6037 from atorralba/atorralba/promote-spel-injection
Java: Promote SpEL Injection query from experimental
2021-09-27 13:13:35 +02:00
Tony Torralba
d5f675c2dc Fix unbound field
Add tests for non-exported providers
2021-09-27 12:58:28 +02:00
Tony Torralba
78c12dc505 Move to lib 2021-09-27 12:04:14 +02:00
Tony Torralba
ad08ccb50b Apply suggestion from code review 2021-09-27 12:00:21 +02:00
mc
95751fcc21 Update XsltInjection.qhelp
Made a few minor tweaks during editorial review
2021-09-27 12:00:21 +02:00
Tony Torralba
13417dbf14 Remove DataFlow references from XsltInjection.qll 2021-09-27 12:00:20 +02:00
Tony Torralba
ff21662b23 Refactor XsltInjection.qll 2021-09-27 12:00:18 +02:00
Tony Torralba
6967b06dee Decouple XsltInjection.qll to reuse the taint tracking configuration 2021-09-27 11:59:51 +02:00
Tony Torralba
fc58ada92e Add change note 2021-09-27 11:58:20 +02:00
Tony Torralba
108118afa3 Use InlineExpectationsTest 2021-09-27 11:58:18 +02:00
Tony Torralba
d8bb5273e7 Refactor to use CSV sink models 2021-09-27 11:57:58 +02:00
Tony Torralba
c792567904 Move from experimental 2021-09-27 11:57:53 +02:00
Tony Torralba
6d9a88d1c8 Move to lib 2021-09-27 11:43:46 +02:00
mc
3520fed752 Update SpelInjection.qhelp 2021-09-27 11:40:51 +02:00
Tony Torralba
d10dbbdd9d Apply suggestions from code review
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-09-27 11:40:51 +02:00
Tony Torralba
6bf1e87bbe Remove CSV sinks; make imports private 2021-09-27 11:40:47 +02:00
Tony Torralba
91f46624b6 Refactor SpelInjection.qll 2021-09-27 11:40:26 +02:00
Tony Torralba
94f32d2985 Decouple SpelInjection.qll to reuse the taint tracking configuration 2021-09-27 11:39:30 +02:00
Tony Torralba
569426b04e Consider subtypes of Expression and ExpressionParser
Add parseRaw as additional taint step
2021-09-27 11:38:12 +02:00
Tony Torralba
b0852f6c16 Add change note 2021-09-27 11:37:46 +02:00
Tony Torralba
b985ddb868 Use InlineExpectationsTest 2021-09-27 11:37:41 +02:00
Tony Torralba
079769ed2e Refactored SpelInjection.qll to use CSV sink models 2021-09-27 11:36:56 +02:00
Tony Torralba
fc6af0476f Moved from experimental 2021-09-27 11:36:48 +02:00
Anders Fugmann
03bd7d7f96 C++: Update test results from OverflowStatic 2021-09-27 11:23:08 +02:00
Anders Schack-Mulligen
92ffd8c465 Merge pull request #6749 from aschackmull/java/istextblock
Java: Add StringLiteral.isTextBlock().
2021-09-27 10:54:31 +02:00
Jonas Jensen
b0836a620c Merge pull request #6757 from geoffw0/impropnulltest2
C++: Small improvement to cpp/improper-null-termination
2021-09-27 10:52:49 +02:00
Jonas Jensen
06b36f742e Merge pull request #6745 from andersfugmann/handle_overflow_for_upperbound
C++: Handle overflow for upperbound
2021-09-27 10:32:49 +02:00
James Fletcher
c977cfe40a Merge pull request #6754 from github/update-link
Update one more link in the QL training content
2021-09-27 08:33:42 +01:00
Anders Fugmann
e0921ac983 C++: Increase precision of cpp/static-buffer-overflow to high 2021-09-27 09:06:36 +02:00
Geoffrey White
7e7dfe2cc4 C++: Understand format arguments. 2021-09-24 19:25:43 +01:00
Geoffrey White
91a8b9fdd9 C++: Add suggested test (and a good variant). 2021-09-24 18:34:28 +01:00
Alexander Eyers-Taylor
8debae1a3b Merge pull request #6753 from github/aibaars/fix-typo
Fix typo in language spec
2021-09-24 17:21:14 +01:00
Rasmus Wriedt Larsen
547cbb6322 Merge pull request #6331 from porcupineyhairs/pythonXpath
Python : Improve Xpath Injection Query
2021-09-24 18:11:08 +02:00
james
1adc5c2a5b update links correctly 2021-09-24 17:00:59 +01:00
Rasmus Wriedt Larsen
d39df18544 Python: Minor test cleanup 2021-09-24 16:11:27 +02:00
james
e664711f47 make links to slide decks relative 2021-09-24 14:56:48 +01:00
Arthur Baars
7d3a219f63 Fix typo in language spec
Thanks to https://github.com/github/codeql/issues/6750
2021-09-24 15:47:09 +02:00
james
23e4ad1abb update one more link 2021-09-24 14:46:14 +01:00
Geoffrey White
3e1bc66984 Merge pull request #6733 from MathiasVP/fix-qldoc-in-initialize-dynamic-allocation-instruction
C++/C#: Fix QLDoc on `InitializeDynamicAllocationInstruction`.{`getAllocationAddressOperand` and `getAllocationAddress`}
2021-09-24 14:30:03 +01:00
Rasmus Wriedt Larsen
26d2fbd217 Python: Fix new XPath injection query
Fixes the typo `ETXpath` => `ETXPath`
2021-09-24 15:11:34 +02:00
Rasmus Wriedt Larsen
913a679ef5 Python: Replace old XPath injection query 2021-09-24 15:10:41 +02:00
Anders Peter Fugmann
aebde189f8 C++: Apply peer review suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-24 15:09:23 +02:00
Anders Schack-Mulligen
66c206cc61 Merge pull request #6747 from bmuskalla/organizeUtils
Java: Organize `utils` into separate directories
2021-09-24 15:05:51 +02:00
Rasmus Wriedt Larsen
c9640ffdbc Python: Minor adjustments to XPath Injection 2021-09-24 15:02:39 +02:00
Mathias Vorreiter Pedersen
24214002a1 C#/C++: Sync identical files. 2021-09-24 13:13:09 +01:00
Mathias Vorreiter Pedersen
eba1b0bc15 Respond to review comments. 2021-09-24 13:12:58 +01:00
Rasmus Wriedt Larsen
289660067c Merge branch 'main' into pythonXpath 2021-09-24 13:53:38 +02:00
Anders Schack-Mulligen
854f2a046a Java: Add StringLiteral.isTextBlock(). 2021-09-24 13:11:18 +02:00
Mathias Vorreiter Pedersen
69541d3628 Merge pull request #6744 from rdmarsh2/rdmarsh2/dtt-subpath
C++: add subpaths to DefaultTaintTracking
2021-09-24 11:58:31 +01:00
Benjamin Muskalla
70e1724463 Exclude methods with non-public parameter types 2021-09-24 12:41:12 +02:00
Anders Fugmann
cbdabe35de C++: Update test results to reflect changes 2021-09-24 12:29:28 +02:00
Anders Fugmann
c9c41252e3 C++: Update test results in SimpleRangeAnalysis 2021-09-24 12:23:48 +02:00
Anders Fugmann
3437cf2909 C++: only use upperbound if there are no overflows in the guard 2021-09-24 11:46:58 +02:00
Anders Fugmann
d7afd86a27 C++: Add test case exposing problem with overflows for upperBound predicate 2021-09-24 11:44:05 +02:00
Benjamin Muskalla
38ca5aba98 Move test generator into subdirectory 2021-09-24 11:13:04 +02:00
Benjamin Muskalla
4e6a8d991e Move stub generator into subdirectory 2021-09-24 11:12:41 +02:00
Benjamin Muskalla
cb0a567c03 Merge pull request #6743 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-24 09:23:35 +02:00
Anders Fugmann
032ac50034 C++: Do not warn on static buffer overflow using loop counters, if the loop counter has been widened 2021-09-24 08:31:36 +02:00
Anders Fugmann
3e5f7d0db5 C++: using buildin offsetof for an array member indexed after end is legal 2021-09-24 08:31:35 +02:00
Anders Fugmann
b08eabec68 C++: Relax predicate memberMayBeVarSize to mark all members of size 0 or 1 as variable sized 2021-09-24 08:31:35 +02:00
Anders Fugmann
a4a9e2aa96 C++: Weaken wording on overflow static alert text 2021-09-24 08:31:35 +02:00
Robert Marsh
3189c578a4 C++: Add QLDoc to subpaths in DefaultTaintTracking 2021-09-23 22:42:38 -07:00
Robert Marsh
c2b356ab08 C++: add subpaths to DefaultTaintTracking 2021-09-23 21:00:45 -07:00
github-actions[bot]
ceb9a0bd6b Add changed framework coverage reports 2021-09-24 00:08:02 +00:00
Anders Schack-Mulligen
a031b2a090 Merge pull request #6493 from atorralba/atorralba/cleartext-storage-query-refactor
Java: Refactor Cleartext Storage queries
2021-09-23 16:31:17 +02:00
Tony Torralba
b52a2cd292 Apply code review comments
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-23 15:48:15 +02:00
Anders Schack-Mulligen
6be4b3bac6 Merge pull request #6725 from emilejq/date-format
Java: Remove requirements for final and access mods from DateFormatThreadUnsafe
2021-09-23 15:02:17 +02:00
Anders Schack-Mulligen
4841c3037d Java: Add callback dispatch to more anonymous classes. 2021-09-23 14:34:56 +02:00
Rasmus Wriedt Larsen
f14e3f6007 Merge pull request #5445 from jorgectf/jorgectf/python/ldapinsecureauth
Python: Add LDAP Insecure Authentication query
2021-09-23 11:08:13 +02:00
Emile El-Qawas
83fb41e414 Add visibility constraints; Fix non-compliant code 2021-09-23 09:55:49 +01:00
Tony Torralba
d0b9920cac Fix encryption sanitizer
It now discards sensitive exprs (sources) instead of sinks for better precision
2021-09-23 10:42:30 +02:00
Tony Torralba
51d2b5225e Remove cached property from SensitiveSource::flowsTo 2021-09-23 10:42:30 +02:00
Tony Torralba
563e8a2bd6 Remove unused library 2021-09-23 10:42:30 +02:00
Tony Torralba
a30554e97c Refactored cleartext storage libraries 2021-09-23 10:42:30 +02:00
Rasmus Wriedt Larsen
ef6e502ff0 Python: Make LDAP global options test better
Before it didn't really showcase that we know it can make connections
secure.
2021-09-23 10:18:18 +02:00
Chris Smowton
93daaf5b5b Merge pull request #6174 from joefarebrother/guava-collections
Java: Model Guava collections package
2021-09-23 09:13:24 +01:00
Rasmus Wriedt Larsen
70489b2fc2 Merge branch 'main' into jorgectf/python/ldapinsecureauth 2021-09-23 10:05:56 +02:00
Tom Hvitved
27c45d8dda Merge pull request #6731 from hvitved/remove-reduced-env-var
Remove `CODEQL_REDUCE_FILES_FOLDERS_RELATIONS`
2021-09-23 09:39:17 +02:00
Chris Smowton
3123abfac3 Merge pull request #6711 from bananabr/AndroidLoggingFix
Fix Android logging signature
2021-09-22 17:23:04 +01:00
Joe Farebrother
522c6e01d2 Sort models by class and name 2021-09-22 15:23:01 +01:00
yoff
14a31a2299 Merge pull request #6732 from RasmusWL/minor-sqlalchemy-comment-fixes 2021-09-22 15:15:52 +02:00
Mathias Vorreiter Pedersen
35baff8bac C#/C++: Sync identical files. 2021-09-22 13:32:29 +01:00
Mathias Vorreiter Pedersen
5969c227ab C++: Fix QLDoc on 'getAllocationAddressOperand' and 'getAllocationAddress'. 2021-09-22 13:32:20 +01:00
Rasmus Wriedt Larsen
8badba26b8 Python: Minor SQLALchemy comment fixes 2021-09-22 13:58:29 +02:00
Chris Smowton
24e3ad4e18 Remove unnecessary type constraint 2021-09-22 10:54:24 +01:00
Mathias Vorreiter Pedersen
a66f83644b Merge pull request #6728 from rdmarsh2/rdmarsh/sql-models-followup
C++: Add additional functions to the SQL models
2021-09-22 10:19:51 +01:00
Tom Hvitved
364dab6990 Remove CODEQL_REDUCE_FILES_FOLDERS_RELATIONS 2021-09-22 09:43:56 +02:00
Edoardo Pirovano
b960857fc2 Merge pull request #6722 from edoardopirovano/update-analyze-docs
Update documentation to reflect changes to `database analyze`
2021-09-22 08:29:45 +01:00
yoff
65d3373ad3 Merge pull request #6727 from RasmusWL/fix-sqlalchemy-query
Python: Merge SQLAlchemy TextClause injection into `py/sql-injection`
2021-09-22 09:29:28 +02:00
Robert Marsh
3108817717 C++: Add additional functions to the SQL models 2021-09-21 17:34:01 -07:00
Rasmus Wriedt Larsen
d44f279339 Python: Fix .qhelp 2021-09-21 20:35:03 +02:00
Rasmus Wriedt Larsen
a83bb39d0f Python: Merge SQLAlchemy TextClause injection into py/sql-injection
As discussed in a meeting today, this will end up presenting an query
suite that's easier to use for customers.

Since https://github.com/github/codeql/pull/6589 has JUST been merged,
if we get this change in fast enough, no end-user will ever have run
`py/sqlalchemy-textclause-injection` as part of LGTM.com or Code
Scanning.
2021-09-21 20:21:42 +02:00
Robert Marsh
d62f76afa6 Merge pull request #6133 from MathiasVP/promote-sql-pqxx
C++: Promote `cpp/sql-injection-via-pqxx` out of experimental
2021-09-21 10:13:57 -07:00
Robert Marsh
97c2917c16 Merge pull request #6409 from JordyZomer/main
cpp: Add query to detect unsigned integer to signed integer conversio…
2021-09-21 09:57:44 -07:00
Joe Farebrother
3cd675bfff Manually fill in most of the remaining support method calls 2021-09-21 17:56:18 +01:00
Mathias Vorreiter Pedersen
478093aa89 Update cpp/ql/lib/semmle/code/cpp/models/interfaces/Sql.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-09-21 17:51:24 +01:00
Emile El-Qawas
dcae1c5c04 DateFormatThreadUnsafe - Remove requirements for final and access modifiers 2021-09-21 16:50:48 +01:00
Joe Farebrother
6e9bee1be7 Add missing models 2021-09-21 16:32:49 +01:00
Joe Farebrother
25d6e00b1a Implement gen methods for MapDifference 2021-09-21 16:30:12 +01:00
Joe Farebrother
a47897bdf9 Implement Table gen methods 2021-09-21 15:29:06 +01:00
Anders Schack-Mulligen
2c41de6648 Merge pull request #6720 from aschackmull/java/isunreachableincall-joinorder
Java: Fix join-order in isUnreachableInCall.
2021-09-21 16:07:42 +02:00
Anders Schack-Mulligen
dd1bed02e8 Merge pull request #6721 from aschackmull/dataflow/subpaths01-joinorder
Dataflow: Fix join-order in subpaths01
2021-09-21 16:05:41 +02:00
Mathias Vorreiter Pedersen
bd5edc7ae5 Respond to review comments. 2021-09-21 14:29:26 +01:00
Mathias Vorreiter Pedersen
dfe932d053 Add missing conjunct in PostgreSqlEscapeFunction's 'escapesSqlArgument' predicate. 2021-09-21 12:14:45 +01:00
Tony Torralba
99881db8bd Add stubs 2021-09-21 12:10:05 +02:00
Tony Torralba
0c1f3ed0b3 Add tests for ContentProvider sources 2021-09-21 12:09:47 +02:00
Tony Torralba
a811ab3aff Add ContentProvider sources 2021-09-21 12:09:28 +02:00
Edoardo Pirovano
5a28a796af Update documentation to reflect changes to database analyze 2021-09-21 10:16:12 +01:00
yoff
4adb0c75bd Merge pull request #6589 from RasmusWL/promote-sqlalchemy
Python: Promote modeling of SQLAlchemy
2021-09-21 11:08:41 +02:00
Rasmus Wriedt Larsen
4a16be2cba Merge pull request #6557 from yoff/python/port-modification-of-default-value
Python: port modification of default value
2021-09-21 10:12:12 +02:00
Rasmus Wriedt Larsen
f8e6ba633a Python: Fix .expected for new subpaths query predicate 2021-09-21 09:40:13 +02:00
Rasmus Wriedt Larsen
c7c8e2f3e3 Merge branch 'main' into promote-sqlalchemy 2021-09-21 09:36:07 +02:00
Anders Schack-Mulligen
eaf05305ff Merge pull request #6709 from aschackmull/java/local-taint-collections
Java: Add container flow to the local taint flow relation.
2021-09-20 16:04:45 +02:00
Anders Schack-Mulligen
044623a360 Dataflow: Sync. 2021-09-20 14:58:28 +02:00
Anders Schack-Mulligen
07c05528ef Dataflow: Fix join-order in subpaths01. 2021-09-20 14:58:12 +02:00
Anders Schack-Mulligen
c72e385a47 Java: Fix join-order in isUnreachableInCall. 2021-09-20 14:09:09 +02:00
Mathias Vorreiter Pedersen
797966fd3d C++: Change the names of the new classes and predicates to match the upcoming 'CommandExecutionFunction' class. 2021-09-20 11:49:09 +01:00
Tom Hvitved
82d463e86e Merge pull request #6718 from hvitved/csharp/xss-subpath
C#: Add `subpaths` predicate to XSS queries
2021-09-20 12:47:27 +02:00
Rasmus Wriedt Larsen
97c0f1c7b7 Python: Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-09-20 12:04:46 +02:00
Tom Hvitved
64507ab316 Merge pull request #6712 from hvitved/csharp/subsumption-perf-take2
C#: Speedup type subsumption calculation
2021-09-20 11:59:24 +02:00
Tom Hvitved
b9c4abe7dc C#: Fix qldoc typos 2021-09-20 10:42:01 +02:00
Tom Hvitved
6d315a5d16 C#: Add subpaths predicate to XSS queries 2021-09-20 10:40:54 +02:00
Anders Schack-Mulligen
187b7e117c Merge pull request #6715 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-20 10:19:16 +02:00
github-actions[bot]
f0e7be7d56 Add changed framework coverage reports 2021-09-20 00:08:08 +00:00
Tom Hvitved
c6c1ad1b90 C#: Update toString for nested types 2021-09-18 19:51:37 +02:00
Tom Hvitved
07fe29cc67 C#: Speedup type subsumption calculation 2021-09-18 19:51:37 +02:00
Joe Farebrother
4929c66e60 Implement gen methods for collections and maps 2021-09-17 17:37:46 +01:00
Joe Farebrother
3ef09da1df Add models for more of methods; update stubs 2021-09-17 16:57:49 +01:00
Daniel Santos
9e41f43ee2 Fix: android.util.Log is final. No inheritance handling is needed. 2021-09-17 10:15:48 -05:00
Anders Schack-Mulligen
2cbad4aed6 Merge pull request #6600 from atorralba/atorralba/fix-conditionalbypass
Java: Fix performance of the query User-controlled bypass of sensitive method
2021-09-17 16:07:39 +02:00
Tamás Vajk
3247794e2f Merge pull request #6196 from tamasvajk/feature/sql-sinks
C#: Migrate SQL sinks to CSV format
2021-09-17 14:36:57 +02:00
Joe Farebrother
e946f49b64 [Test gen] Gen methods for Set and Iterator 2021-09-17 11:22:50 +01:00
Joe Farebrother
0bff1b4afb Implement get methods 2021-09-17 11:08:09 +01:00
Tamas Vajk
8232698254 C#: Migrate SQL sinks to CSV format 2021-09-17 10:21:31 +02:00
Tamás Vajk
6a78aa7840 Merge pull request #6461 from tamasvajk/feature/service-stack
C#: Add ServiceStack support
2021-09-17 10:16:20 +02:00
Felicity Chapman
7383988988 Merge pull request #6701 from github/docs-4908-training-note-links
Update links in training notes to use CodeQL microsite
2021-09-17 09:00:36 +01:00
james
e906ded0d1 remove java class 2021-09-17 08:48:26 +01:00
Daniel Santos
032a7e71fe Update Logging.qll
Simplified using a set-literal as suggested by @intrigus-lgtm
2021-09-16 13:03:26 -05:00
Daniel Santos
af8b2b6d9c Fix Android logging signature in java/ql/src/experimental/semmle/code/java/Logging.qll 2021-09-16 11:24:06 -05:00
james
c36292bfd0 a few more links 2021-09-16 17:03:29 +01:00
Joe Farebrother
1111afc031 Update tests for new support methods; fix bad model 2021-09-16 15:23:03 +01:00
Joe Farebrother
54dbd7c0bd [Test gen] Add more support method implementations 2021-09-16 15:23:03 +01:00
Joe Farebrother
ef5bf87672 [Test gen] Distinguish default support methods 2021-09-16 15:23:03 +01:00
Joe Farebrother
eb45e67784 Generate tests for modified models 2021-09-16 15:23:02 +01:00
Joe Farebrother
1eacbd88b8 Fix up some incorrect models; simplify/remove some redundand ones 2021-09-16 15:23:02 +01:00
Joe Farebrother
a89bd32eb0 Factor out content manipulating methods from tests to a separate file 2021-09-16 15:23:02 +01:00
Joe Farebrother
56a2dc632b Move tests around and remove files used for generating tests 2021-09-16 15:23:02 +01:00
Joe Farebrother
7dded52de2 Add change note 2021-09-16 15:23:02 +01:00
Joe Farebrother
8425a94729 Mark failing tests as missing
I'm not sure why these tests don't work.
2021-09-16 15:23:02 +01:00
Joe Farebrother
7bf55fbc49 Update stubs to not include package protected members 2021-09-16 15:23:02 +01:00
Joe Farebrother
39349f3763 Fix failing test 2021-09-16 15:23:02 +01:00
Joe Farebrother
60c6158152 Fill in implementations of getters for synthetic fields 2021-09-16 15:23:01 +01:00
Joe Farebrother
225e70a8d0 Fill in implementations fo getMapKey/Value 2021-09-16 15:23:01 +01:00
Joe Farebrother
338a6f2114 Fill in implementations for getElement 2021-09-16 15:23:01 +01:00
Joe Farebrother
cd7c7c3152 Implement array getters/constructors in generated tests 2021-09-16 15:23:01 +01:00
Joe Farebrother
84748cda76 Increase field flow branch limit.
I'm a little concerned that this appears to be necassary for tests; as it may mean that results involving these flow steps may not be found in real-world projects.
2021-09-16 15:23:01 +01:00
Joe Farebrother
f94a61cc8a Remove unneeded rows 2021-09-16 15:23:01 +01:00
Joe Farebrother
b51ffadd27 Improve generated tests 2021-09-16 15:23:01 +01:00
Joe Farebrother
0f2c50f1f5 Explicitly add the of and copyOf methods for ImmutableSorted variants of certain types. 2021-09-16 15:23:01 +01:00
Joe Farebrother
c8e2b027ee Add fieldFlowBranchLimit to the tests 2021-09-16 15:23:00 +01:00
Joe Farebrother
839c9e35c8 Simplify synthetic table fields 2021-09-16 15:23:00 +01:00
Joe Farebrother
46eec3c8eb Switch to simpler synthetic field model 2021-09-16 15:23:00 +01:00
Joe Farebrother
6ae11b5b2c Generate stubs.
Some generated stubs were manually adjusted due to minor issues in the stub generator.
In particular, ambiguous references were resolved and references to private classes were removed.
2021-09-16 15:23:00 +01:00
Joe Farebrother
ff733e0334 Fix up issues in generated tests 2021-09-16 15:23:00 +01:00
Joe Farebrother
693d729ec6 Generate tests and fix broken specs 2021-09-16 15:23:00 +01:00
Joe Farebrother
2150c1d58e Remove <> from flow summaries 2021-09-16 15:23:00 +01:00
Joe Farebrother
1273b063f4 Fix test expectations 2021-09-16 15:23:00 +01:00
Joe Farebrother
a755633405 Add the remaining utility classes 2021-09-16 15:22:59 +01:00
Joe Farebrother
19579f0d9a Add more utility class models and reorder existing ones 2021-09-16 15:22:59 +01:00
Joe Farebrother
ca583bffd5 Add Lists and Collections2 utilites 2021-09-16 15:22:59 +01:00
Joe Farebrother
5fee6d2d19 Convert Sets utilities 2021-09-16 15:22:59 +01:00
Joe Farebrother
10f0f3038c Add tables, improve tests, make fixes 2021-09-16 15:22:59 +01:00
Joe Farebrother
73aba09eee Add create methods 2021-09-16 15:22:59 +01:00
Joe Farebrother
035d655e72 Update guava collection flow steps to CSV 2021-09-16 15:22:59 +01:00
Tony Torralba
f18c163408 Improve handling of the 'author' word as an exception 2021-09-16 11:57:28 +02:00
Anders Schack-Mulligen
28e5dcef52 Java: Add container flow to the local taint flow relation. 2021-09-16 11:14:30 +02:00
Tamas Vajk
f015cea590 Merge branch 'main' into feature/service-stack 2021-09-16 09:42:42 +02:00
Tamas Vajk
05dd3fa0e7 Adjust review findings 2021-09-16 09:42:38 +02:00
Felicity Chapman
05d83e487d Update all links to CodeQL microsite 2021-09-15 17:08:55 +01:00
Tony Torralba
21079a1315 Fix conditionControlsMethod predicate
Exceptions for throw and return statements were missing the appropriate condition
2021-09-15 17:51:51 +02:00
Mathias Vorreiter Pedersen
947ab8a14d Make the QLDoc on 'getAnSqlParameter' more clear. 2021-09-15 13:15:05 +01:00
Rasmus Lerchedahl Petersen
8ea7a28a77 Python: Unexpose fields as suggested. 2021-09-15 12:32:21 +02:00
yoff
758b6bd4dd Update python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-15 12:25:27 +02:00
Jordy Zomer
0f6e845418 Merge branch 'main' of https://github.com/JordyZomer/codeql into main 2021-09-15 10:41:31 +02:00
Jordy Zomer
01a06d1f5c Add filter and format the query 2021-09-15 10:37:40 +02:00
Mathias Vorreiter Pedersen
44dca68463 Merge branch 'main' into promote-sql-pqxx 2021-09-14 15:29:37 +01:00
Tony Torralba
4e93330cb9 Improved tests
Note that a FN test case was added
2021-09-14 15:51:08 +02:00
Tony Torralba
0640b41f00 Adjust tests 2021-09-14 13:44:53 +02:00
Tony Torralba
b740cf9664 Add change note 2021-09-14 13:16:47 +02:00
Tony Torralba
097927226b Improved heuristics to increase precision 2021-09-14 13:16:47 +02:00
Tony Torralba
f8d1e2ac11 Refactor tests to use InlineExpectationsTest 2021-09-14 13:16:45 +02:00
Tony Torralba
1f7990d6bb Refactor to use ConditionalBypassQuery.qll 2021-09-14 13:16:09 +02:00
Tony Torralba
a484e9fb06 Use RemoteFlowSource instead of UserInput 2021-09-14 13:16:09 +02:00
jorgectf
b505662ef9 Fix global test and update .expected 2021-09-14 10:20:50 +02:00
Anders Fugmann
3f5ab60fb4 C++: Add DEPRECATED to documentation block 2021-09-14 09:55:19 +02:00
jorgectf
2ccc6dc092 Merge branch 'main' into jorgectf/python/ldapinsecureauth 2021-09-14 09:32:19 +02:00
Anders Fugmann
8e9ac18026 C++: Deprecate RangeSSA::isGuardPhi/3 2021-09-13 15:35:05 +02:00
Felicity Chapman
1d76578202 Merge pull request #6659 from github/docs-311-update-version
Update version numbers for LGTM Enterprise 1.28
2021-09-13 10:26:52 +01:00
jorgectf
353c0a9ee7 Add missing comment 2021-09-12 20:44:04 +02:00
jorgectf
3cf28ad6ce Merge remote-tracking branch 'origin/main' into jorgectf/python/ldapinsecureauth 2021-09-12 20:36:25 +02:00
jorgectf
18b05bc56e Fix tests and add global option 2021-09-12 20:35:57 +02:00
jorgectf
54012eba23 Optimize getFullHostRegex 2021-09-12 20:13:08 +02:00
Rasmus Lerchedahl Petersen
2eb11731e2 Python: Subpaths in test output 2021-09-10 14:04:57 +02:00
Rasmus Lerchedahl Petersen
02fd63ce20 Merge branch 'main' of github.com:github/codeql into python/port-modification-of-default-value
To get the subpaths.
2021-09-10 14:03:02 +02:00
Rasmus Lerchedahl Petersen
7cfa08abc8 Python: Do not use BarrierGuards
They are simply not right for this problem.
We should not even make them available as an extension point.
2021-09-10 12:48:24 +02:00
Anders Fugmann
2c93bce9ad C++: Refactor code to use predicate isGuardPhi/4 2021-09-10 10:53:48 +02:00
Rasmus Lerchedahl Petersen
b20232db3c Python: Simplify guards as suggested 2021-09-10 10:31:48 +02:00
Felicity Chapman
3b3350e648 Correct the Qllexer path for slides 2021-09-10 08:04:07 +01:00
Felicity Chapman
32b3e416b3 Update version numbers for LGTM E 1.28 2021-09-10 06:54:36 +01:00
Tamas Vajk
abe6c90829 Update change note 2021-09-09 13:04:47 +02:00
Tamas Vajk
0a17ab9325 Merge branch 'main' into feature/service-stack 2021-09-09 13:01:43 +02:00
jorgectf
4e261c61ae Optimize concatAndCompareAgainstFullHostRegex 2021-09-07 19:05:03 +02:00
jorgectf
800801177d Fix taint tracking comment 2021-09-07 19:02:32 +02:00
jorgectf
b802d7903a Fix OPT_X_TLS_ mandatory options 2021-09-07 19:01:46 +02:00
jorgectf
ee98c0c587 Add start_tls_s() comment and use DataFlow::MethodCallNode instead 2021-09-07 19:00:14 +02:00
Jorge
1bc16fb31e Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-07 18:37:33 +02:00
yoff
43effd2b40 Update python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-07 15:08:50 +02:00
Rasmus Lerchedahl Petersen
e8644f6f2a Python: coment out discriminating test
The test case has different behaviour between py2/3.
When merging this, we should create an issue to resolve it.
2021-09-07 10:30:38 +02:00
Rasmus Lerchedahl Petersen
b48caaf465 Python: fix reference to PrintNode.qll 2021-09-07 10:19:42 +02:00
Rasmus Lerchedahl Petersen
8729701b66 Merge branch 'main' of github.com:github/codeql into python/port-modification-of-default-value
Files have moved around, specifically PrintNode.qll.
2021-09-07 10:13:51 +02:00
Rasmus Lerchedahl Petersen
29cb067769 Python: Remember to update test expectations 2021-09-07 10:13:17 +02:00
Rasmus Lerchedahl Petersen
ae8408bcab Python: Add missing qldoc 2021-09-07 10:09:02 +02:00
Rasmus Lerchedahl Petersen
4998a48f99 Python: Fix simple guards 2021-09-06 22:40:30 +02:00
Tamas Vajk
3a9cf639bd Change ServiceStack redis sinks to code injection instead of SQL injection 2021-09-06 16:59:31 +02:00
Tamas Vajk
5fa9f16c01 Adjust ServiceStack CSV rows with generic method names 2021-09-06 16:45:21 +02:00
Tamas Vajk
f6366e1e1f Merge branch 'feature/method-name' into feature/service-stack 2021-09-06 15:52:08 +02:00
Tamas Vajk
207d8f6030 Merge branch 'main' into feature/service-stack 2021-09-06 15:46:43 +02:00
Tamas Vajk
5014ef2337 C#: Add ServiceStack support with CSV data model 2021-09-06 14:06:37 +02:00
Tamas Vajk
43ccc14162 Add ServiceStack stubs and empty test referencing it 2021-09-06 14:05:41 +02:00
Tamas Vajk
e3a49f8213 C#: improve stubbing to escape more member names (not just fields) 2021-09-06 14:02:42 +02:00
Tamas Vajk
270b56af1b Extend runtime callables to interface members with default implementation 2021-09-06 14:02:42 +02:00
Tamas Vajk
39a88d2e43 Fix dispatch library to handle summarized callables with no runtime target 2021-09-06 14:02:42 +02:00
Rasmus Lerchedahl Petersen
913990bc62 Python: Add suggested comments and test case 2021-09-03 14:40:16 +02:00
yoff
c6eb795e76 Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-03 14:23:57 +02:00
Rasmus Wriedt Larsen
9f590dbf2d Python: Fix .expected
After we now model `db.text()` calls from Flask-SQLAlchemy
2021-09-02 16:04:25 +02:00
Rasmus Wriedt Larsen
414bf12f86 Python: Fix DefaultTextClauseConstruction 2021-09-02 16:03:25 +02:00
Rasmus Wriedt Larsen
88c6d4bb20 Python: Fix .qhelp 2021-09-02 16:02:04 +02:00
Rasmus Wriedt Larsen
d55f18f8e3 Python: Add modeling of Flask-SQLAlchemy 2021-09-02 10:48:24 +02:00
Rasmus Wriedt Larsen
f1744890b1 Python: Add tests for Flask-SQLAlchemy 2021-09-02 10:48:15 +02:00
Rasmus Wriedt Larsen
c34d6d1162 Python: Add query to handle SQLAlchemy TextClause Injection
instead of doing this via taint-steps. See description in code/tests.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
81dbe36e99 Python: Promote SQLAlchemy modeling
Due to the split between `src/` and `lib/`, I was not really able to do
the next step without having moved the SQLAlchemy modeling over to be in
`lib/` as well.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
ba99e21875 Python: Remove modeling of sqlescapy PyPI package
I've never seen this being used in real code, and this library doesn't
have a lot of traction, so I would rather not commit to supporting it
(which includes verifying that it actually makes things safe).

Personally I don't think this is the right approach for avoiding SQL
injection either.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
91442e100c Python: Model sessionmaker().begin() 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
feb2303e1f Python: Model the underlying DB-API connection 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
1ab04a7276 Python: Model Connection.execution_options 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
2acf518037 Python: Model exec_driver_sql 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
fe143c7dfa Python: Rewrite most of SQLAlchemy modeling 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
b39bb24fcf Python: Add more SQLAlchemy tests 2021-09-02 10:19:57 +02:00
Rasmus Lerchedahl Petersen
a855074588 Python: Try to remove py2/3 differences 2021-08-30 15:41:51 +02:00
Rasmus Lerchedahl Petersen
0de621edf9 Python: Add qldoc 2021-08-30 15:03:58 +02:00
Rasmus Lerchedahl Petersen
1903cb8f82 Python: Add change note 2021-08-30 11:27:55 +02:00
Rasmus Lerchedahl Petersen
a762373ad6 Python: Implement simple barrier guard
The one found in the original test case
2021-08-30 11:04:27 +02:00
jorgectf
64b305cf7a Add .qhelp along with its example 2021-08-26 23:29:45 +02:00
Rasmus Lerchedahl Petersen
49ae549e89 Python: Implement modifying syntax 2021-08-26 14:29:18 +02:00
Rasmus Lerchedahl Petersen
097c23e437 Python: add inline expectations test
Consider removing the original test
2021-08-26 14:08:52 +02:00
jorgectf
786edb72df Update .expected 2021-08-26 12:36:34 +02:00
Jorge
d458464e6b Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-08-26 12:20:09 +02:00
Rasmus Lerchedahl Petersen
d834cec9b9 Python: test simple sanitizer 2021-08-26 11:31:20 +02:00
Rasmus Lerchedahl Petersen
8614563b42 Python: More tests of syntactic constructs 2021-08-26 10:56:41 +02:00
Rasmus Lerchedahl Petersen
5bff5188ac Python: switch from negative to positive list
This should avoid potentially terrible performance.
Also noted the missing syntactic constructs,
as I went through the documnetation.
2021-08-25 23:52:42 +02:00
Rasmus Lerchedahl Petersen
e865a290de Python: straight port of query
The old query uses `pointsTo` to limit the sinks
to methods on lists and dictionaries.
That constraint is omitted here which could hurt performance.
2021-08-24 16:35:11 +02:00
Rasmus Lerchedahl Petersen
e3765ced78 Python: Add tests for modification of defaults 2021-08-24 16:35:11 +02:00
Tamas Vajk
2437546009 Merge branch 'main' into feature/service-stack 2021-08-10 15:16:17 +02:00
Jordy Zomer
a3bacc76f1 Update cpp/ql/src/experimental/Security/CWE/CWE-787/UnsignedToSignedPointerArith.ql
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-08-05 23:31:12 +02:00
Jordy Zomer
cf40d0ae4d Fix a typo unsiged -> unsigned 2021-08-05 16:40:49 +02:00
Jordy Zomer
489ac04f86 Remove author tag 2021-08-05 12:34:31 +02:00
Jordy Zomer
19bb8e8c17 Make requested changes 2021-08-03 21:54:04 +02:00
Jordy Zomer
e07516585a cpp: Add query to detect unsigned integer to signed integer conversions used in pointer arithmetics 2021-08-03 19:08:47 +02:00
Jorge
f02b6d60a5 Merge branch 'github:main' into jorgectf/python/ldapinsecureauth 2021-07-22 18:49:51 +02:00
jorgectf
b03e75e3d1 Extend ldap3's start_tls and fix tests 2021-07-22 18:42:41 +02:00
jorgectf
a34d6d390e Port to ApiGraphs and finish the query 2021-07-22 18:34:57 +02:00
jorgectf
edb273ace5 Merge remote-tracking branch 'origin/jorgectf/python/ldapimproperauth' into jorgectf/python/ldapinsecureauth 2021-07-22 02:51:19 +02:00
Porcuiney Hairs
c6c925d67a Python : Improve Xpath Injection Query 2021-07-20 03:31:30 +05:30
mr-sherman
04940a1105 Create 2021-07-14-service-stack-support.md 2021-07-14 15:54:28 -04:00
Mathias Vorreiter Pedersen
90633b9ce1 C++: Make the new SQL abstract classes extend 'Function' instead. This is more in line with how we model RemoteFlowFunction. 2021-06-23 11:49:51 +02:00
Mathias Vorreiter Pedersen
90fe5c5aca C++: Add change-note. 2021-06-22 17:13:07 +02:00
Mathias Vorreiter Pedersen
2e2673aff6 C++: Delete the experimental SqlPqxxTainted query. 2021-06-22 17:13:07 +02:00
Mathias Vorreiter Pedersen
440793b5ff C++: Move the example from the experimental CWE-089 query into a test. 2021-06-22 17:13:06 +02:00
Mathias Vorreiter Pedersen
222cd41aa3 C++: Use the new SQL interface in 'Security.qll' and 'SqlTainted.ql'. 2021-06-22 17:13:06 +02:00
Mathias Vorreiter Pedersen
092fbd60d9 C++: Create a new SQL interface. 2021-06-22 17:13:06 +02:00
mr-sherman
ec48d0ac29 Merge remote-tracking branch 'upstream/main' into service-stack-remote-sink
merging from main because it fell way behind.
2021-05-28 10:30:29 -04:00
mr-sherman
bf2d7b3a16 Added IRestClientAsync methods to external location sink. Removed import from
Remote.qll, as it is un-necessary now.
2021-03-29 14:37:51 -04:00
mr-sherman
13997caa32 feedback from code review 2021-03-26 16:29:14 -04:00
mr-sherman
3e889c398e updated document formatting 2021-03-23 10:09:30 -04:00
mr-sherman
858c0e67a1 added support for remote flow sinks in the form of parameters to the function
ServiceStack.IRestClient.Get()
2021-03-22 19:27:49 -04:00
jorgectf
957b3e1e85 Precision warn 2021-03-18 20:39:53 +01:00
jorgectf
3ce0a9c8c0 Move to experimental folder 2021-03-18 20:20:04 +01:00
jorgectf
7de9214c99 Upload LDAP Insecure authentication query and tests 2021-03-18 17:41:34 +01:00
yo-h
402ed04189 Merge pull request #4844 from johnlugton/servicestack
Add provisional support for ServiceStack framework to feature branch
2020-12-18 16:24:27 -05:00
John Lugton
059d6b0e0f Fix warning in ServiceStack.qll 2020-12-18 08:34:06 -08:00
John Lugton
563dc62c33 Improve qldoc for ServiceStack.qll 2020-12-18 08:23:27 -08:00
John Lugton
3f1f83f667 remove experimental 2020-12-17 16:24:52 -08:00
John Lugton
6d5f9035e6 Minor fixes to XSS:
Only want returns in request methods
Also care about non-string 1st args to HttpResult e.g. streams
2020-12-17 16:17:26 -08:00
John Lugton
7d47bffd53 Tidy up ServiceStack.qll
Use fully qualified names for classes
Make util predicate private
Make naming more consistent with rest of ql libs
2020-12-17 16:17:26 -08:00
Chelsea Boling
d4acccb13c Update sink 2020-12-17 16:17:26 -08:00
Chelsea Boling
0a7e4b6840 Update sink based on feedback 2020-12-17 16:17:26 -08:00
Chelsea Boling
4e0f3a30ee Update sink based on feedback 2020-12-17 16:17:25 -08:00
Chelsea Boling
ba46eaa143 Refactor sink 2020-12-17 16:17:25 -08:00
Chelsea Boling
3c493511e9 Update file 2020-12-17 16:17:25 -08:00
Chelsea Boling
12e8107492 Add example 2020-12-17 16:17:25 -08:00
Chelsea Boling
5c7dedffb3 Update sinks 2020-12-17 16:17:25 -08:00
Chelsea Boling
71a08c3237 Update servicestack lib 2020-12-17 16:17:25 -08:00
John Lugton
d408ae7e10 Split ServiceStack into modules and incorporate into main lib 2020-12-17 16:17:25 -08:00
John Lugton
386eb2d56b move ServiceStack out of microsoft 2020-12-17 16:17:25 -08:00
Chelsea Boling
a2615339f7 Delete ServiceStack.qll 2020-12-17 16:17:24 -08:00
Chelsea Boling
cae6f91729 Create ServiceStack.qll 2020-12-17 16:17:24 -08:00
Chelsea Boling
dbe0170249 Add files via upload 2020-12-17 16:17:24 -08:00
Chelsea Boling
188dbde2d6 Create SQLInjection.ql 2020-12-17 16:17:24 -08:00
Chelsea Boling
96d11b7966 Create ServiceStack.qll 2020-12-17 16:17:24 -08:00
7598 changed files with 65937 additions and 593194 deletions

View File

@@ -4,8 +4,8 @@ This open source repository contains the standard CodeQL libraries and queries t
## How do I learn CodeQL and run queries?
There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed.
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed.
## Contributing

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Uncontrolled data in SQL query' (cpp/sql-injection) query now supports the `libpqxx` library.

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* Increase precision to high for the "Static buffer overflow" query
(`cpp/static-buffer-overflow`). This means the query is run and displayed by default on Code Scanning and LGTM.

View File

@@ -10,44 +10,11 @@ import semmle.code.cpp.dataflow.DataFlow
* char data[1]; // v
* };
* ```
* This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`.
* In addition, if the size of the structure is taken, there must be at least one instance
* where a `c` pointer is allocated with additional space.
* For example, holds for `c` if it occurs as
* ```
* malloc(sizeof(c) + 100 * sizeof(char))
* ```
* but not if it only ever occurs as
* ```
* malloc(sizeof(c))
* ```
* This requires that `v` is an array of size 0 or 1.
*/
predicate memberMayBeVarSize(Class c, MemberVariable v) {
exists(int i |
// `v` is the last field in `c`
i = max(int j | c.getCanonicalMember(j) instanceof Field | j) and
v = c.getCanonicalMember(i) and
// v is an array of size at most 1
v.getUnspecifiedType().(ArrayType).getArraySize() <= 1 and
not c instanceof Union
) and
// If the size is taken, then arithmetic is performed on the result at least once
(
// `sizeof(c)` is not taken
not exists(SizeofOperator so |
so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
)
or
// or `sizeof(c)` is taken
exists(SizeofOperator so |
so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
|
// and arithmetic is performed on the result
so.getParent*() instanceof AddExpr
)
)
c = v.getDeclaringType() and
v.getUnspecifiedType().(ArrayType).getArraySize() <= 1
}
/**
@@ -60,10 +27,6 @@ int getBufferSize(Expr bufferExpr, Element why) {
result = bufferVar.getUnspecifiedType().(ArrayType).getSize() and
why = bufferVar and
not memberMayBeVarSize(_, bufferVar) and
not exists(Union bufferType |
bufferType.getAMemberVariable() = why and
bufferVar.getUnspecifiedType().(ArrayType).getSize() <= 1
) and
not result = 0 // zero sized arrays are likely to have special usage, for example
or
// behaving a bit like a 'union' overlapping other fields.
@@ -85,13 +48,6 @@ int getBufferSize(Expr bufferExpr, Element why) {
parentPtr.getTarget().getUnspecifiedType().(PointerType).getBaseType() = parentClass and
result = getBufferSize(parentPtr, _) + bufferVar.getType().getSize() - parentClass.getSize()
)
or
exists(Union bufferType |
bufferType.getAMemberVariable() = why and
why = bufferVar and
bufferVar.getUnspecifiedType().(ArrayType).getSize() <= 1 and
result = bufferType.getSize()
)
)
or
// buffer is a fixed size dynamic allocation

View File

@@ -93,6 +93,15 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
fc.getArgument(i) = va
)
or
// String argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
fc.(FormattingFunctionCall).getConversionArgument(n) = va and
fl = fc.(FormattingFunctionCall).getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
or
// Call to a wrapper function that requires null termination
// (not itself adding a null terminator)
exists(Function wrapper, int i, Parameter p, VariableAccess use |

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -550,6 +550,39 @@ module TaintedWithPath {
)
}
/**
* Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow
* from `par` to `ret` within it, in the graph of data flow path explanations.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner())
or
// To avoid showing trivial-looking steps, we _replace_ the last node instead
// of adding an edge out of it.
exists(WrapPathNode sinkNode |
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
)
or
// Same for the first node
exists(WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner())
)
or
// Finally, handle the case where the path goes directly from a source to a
// sink, meaning that they both need to be translated.
exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
)
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
key = "semmle.label" and val = n.toString()

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -33,3 +33,6 @@ private import implementations.Recv
private import implementations.Accept
private import implementations.Poll
private import implementations.Select
private import implementations.MySql
private import implementations.SqLite3
private import implementations.PostgreSql

View File

@@ -0,0 +1,32 @@
/**
* Provides implementation classes modeling the MySql C API.
* See `semmle.code.cpp.models.Models` for usage information.
*/
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* The `mysql_query` family of functions from the MySQL C API.
*/
private class MySqlExecutionFunction extends SqlExecutionFunction {
MySqlExecutionFunction() {
this.hasName(["mysql_query", "mysql_real_query", "mysql_real_query_nonblocking"])
}
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}
/**
* The `mysql_real_escape_string` family of functions from the MySQL C API.
*/
private class MySqlBarrierFunction extends SqlBarrierFunction {
MySqlBarrierFunction() {
this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"])
}
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(2) and
output.isParameterDeref(1)
}
}

View File

@@ -0,0 +1,94 @@
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
private predicate pqxxTransactionSqlArgument(string function, int arg) {
function = "exec" and arg = 0
or
function = "exec0" and arg = 0
or
function = "exec1" and arg = 0
or
function = "exec_n" and arg = 1
or
function = "exec_params" and arg = 0
or
function = "exec_params0" and arg = 0
or
function = "exec_params1" and arg = 0
or
function = "exec_params_n" and arg = 1
or
function = "query_value" and arg = 0
or
function = "stream" and arg = 0
}
private predicate pqxxConnectionSqlArgument(string function, int arg) {
function = "prepare" and arg = 1
}
private predicate pqxxTransationClassNames(string className, string namespace) {
namespace = "pqxx" and
className in [
"dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction",
"subtransaction", "transaction", "basic_transaction", "transaction_base", "work"
]
}
private predicate pqxxConnectionClassNames(string className, string namespace) {
namespace = "pqxx" and
className in ["connection_base", "basic_connection", "connection"]
}
private predicate pqxxEscapeArgument(string function, int arg) {
arg = 0 and
function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"]
}
private class PostgreSqlExecutionFunction extends SqlExecutionFunction {
PostgreSqlExecutionFunction() {
exists(Class c |
this.getDeclaringType() = c and
// transaction exec and connection prepare variations
(
pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) and
pqxxTransactionSqlArgument(this.getName(), _)
or
pqxxConnectionSqlArgument(this.getName(), _) and
pqxxConnectionClassNames(c.getName(), c.getNamespace().getName())
)
)
}
override predicate hasSqlArgument(FunctionInput input) {
exists(int argIndex |
pqxxTransactionSqlArgument(this.getName(), argIndex)
or
pqxxConnectionSqlArgument(this.getName(), argIndex)
|
input.isParameterDeref(argIndex)
)
}
}
private class PostgreSqlBarrierFunction extends SqlBarrierFunction {
PostgreSqlBarrierFunction() {
exists(Class c |
this.getDeclaringType() = c and
// transaction and connection escape functions
(
pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) or
pqxxConnectionClassNames(c.getName(), c.getNamespace().getName())
) and
pqxxEscapeArgument(this.getName(), _)
)
}
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
exists(int argIndex |
input.isParameterDeref(argIndex) and
output.isReturnValueDeref() and
pqxxEscapeArgument(this.getName(), argIndex)
)
}
}

View File

@@ -0,0 +1,21 @@
/**
* Provides implementation classes modeling the SQLite C API.
* See `semmle.code.cpp.models.Models` for usage information.
*/
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* The `sqlite3_exec` and `sqlite3_prepare` families of functions from the SQLite C API.
*/
private class SqLite3ExecutionFunction extends SqlExecutionFunction {
SqLite3ExecutionFunction() {
this.hasName([
"sqlite3_exec", "sqlite3_prepare", "sqlite3_prepare_v2", "sqlite3_prepare_v3",
"sqlite3_prepare16", "sqlite3_prepare16_v2", "sqlite3_prepare16_v3"
])
}
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}

View File

@@ -0,0 +1,30 @@
/**
* Provides abstract classes for modeling functions that execute and escape SQL query strings.
* To extend this QL library, create a QL class extending `SqlExecutionFunction` or `SqlEscapeFunction`
* with a characteristic predicate that selects the function or set of functions you are modeling.
* Within that class, override the predicates provided by the class to match the way a
* parameter flows into the function and, in the case of `SqlEscapeFunction`, out of the function.
*/
private import cpp
/**
* An abstract class that represents a function that executes an SQL query.
*/
abstract class SqlExecutionFunction extends Function {
/**
* Holds if `input` to this function represents SQL code to be executed.
*/
abstract predicate hasSqlArgument(FunctionInput input);
}
/**
* An abstract class that represents a function that is a barrier to an SQL query string.
*/
abstract class SqlBarrierFunction extends Function {
/**
* Holds if the `output` is a barrier to the SQL input `input` such that is it safe to pass to
* an `SqlExecutionFunction`.
*/
abstract predicate barrierSqlArgument(FunctionInput input, FunctionOutput output);
}

View File

@@ -29,8 +29,7 @@ predicate nanExcludingComparison(ComparisonOperation guard, boolean polarity) {
*/
private predicate excludesNan(RangeSsaDefinition def, VariableAccess v) {
exists(VariableAccess inCond, ComparisonOperation guard, boolean branch, StackVariable lsv |
def.isGuardPhi(inCond, guard, branch) and
inCond.getTarget() = lsv and
def.isGuardPhi(lsv, inCond, guard, branch) and
v = def.getAUse(lsv) and
guard.getAnOperand() = inCond and
nanExcludingComparison(guard, branch)

View File

@@ -94,10 +94,11 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }
/**
* DEPRECATED: Use isGuardPhi/4 instead
* If this definition is a phi node corresponding to a guard,
* then return the variable access and the guard.
*/
predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
guard_defn(va, guard, this, branch)
}
@@ -142,9 +143,8 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
// below excludes definitions which can only reach guard phi
// nodes by going through the corresponding guard.
not exists(VariableAccess access |
v = access.getTarget() and
pred.contains(access) and
this.isGuardPhi(access, _, _)
this.isGuardPhi(v, access, _, _)
)
)
}

View File

@@ -433,10 +433,7 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
private predicate phiDependsOnDef(
RangeSsaDefinition phi, StackVariable v, RangeSsaDefinition srcDef, StackVariable srcVar
) {
exists(VariableAccess access, Expr guard |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, _)
|
exists(VariableAccess access, Expr guard | phi.isGuardPhi(v, access, guard, _) |
exprDependsOnDef(guard.(ComparisonOperation).getAnOperand(), srcDef, srcVar) or
exprDependsOnDef(access, srcDef, srcVar)
)
@@ -1204,8 +1201,7 @@ private float boolConversionUpperBound(Expr expr) {
*/
private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
exists(VariableAccess access, Expr guard, boolean branch, float defLB, float guardLB |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, branch) and
phi.isGuardPhi(v, access, guard, branch) and
lowerBoundFromGuard(guard, access, guardLB, branch) and
defLB = getFullyConvertedLowerBounds(access)
|
@@ -1230,8 +1226,7 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
/** See comment for `getPhiLowerBounds`, above. */
private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) {
exists(VariableAccess access, Expr guard, boolean branch, float defUB, float guardUB |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, branch) and
phi.isGuardPhi(v, access, guard, branch) and
upperBoundFromGuard(guard, access, guardUB, branch) and
defUB = getFullyConvertedUpperBounds(access)
|
@@ -1493,8 +1488,7 @@ private predicate isNEPhi(
exists(
ComparisonOperation cmp, boolean branch, Expr linearExpr, Expr rExpr, float p, float q, float r
|
access.getTarget() = v and
phi.isGuardPhi(access, cmp, branch) and
phi.isGuardPhi(v, access, cmp, branch) and
eqOpWithSwapAndNegate(cmp, linearExpr, rExpr, false, branch) and
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!=` is too imprecise
r = getValue(rExpr).toFloat() and
@@ -1503,8 +1497,7 @@ private predicate isNEPhi(
)
or
exists(Expr op, boolean branch, Expr linearExpr, float p, float q |
access.getTarget() = v and
phi.isGuardPhi(access, op, branch) and
phi.isGuardPhi(v, access, op, branch) and
eqZeroWithNegate(op, linearExpr, false, branch) and
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!` is too imprecise
linearAccess(linearExpr, access, p, q) and
@@ -1524,8 +1517,7 @@ private predicate isUnsupportedGuardPhi(Variable v, RangeSsaDefinition phi, Vari
or
eqZeroWithNegate(cmp, _, false, branch)
|
access.getTarget() = v and
phi.isGuardPhi(access, cmp, branch) and
phi.isGuardPhi(v, access, cmp, branch) and
not isNEPhi(v, phi, access, _)
)
}
@@ -1549,7 +1541,8 @@ private float getGuardedUpperBound(VariableAccess guardedAccess) {
// that there is one predecessor, albeit somewhat conservative.
exists(unique(BasicBlock b | b = def.(BasicBlock).getAPredecessor())) and
guardedAccess = def.getAUse(v) and
result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch))
result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch)) and
not convertedExprMightOverflow(guard.getAChild+())
)
}
@@ -1593,6 +1586,15 @@ private module SimpleRangeAnalysisCached {
result = min([max(getTruncatedUpperBounds(expr)), getGuardedUpperBound(expr)])
}
/** Holds if the upper bound of `expr` may have been widened. This means the the upper bound is in practice likely to be overly wide. */
cached
predicate upperBoundMayBeWidened(Expr e) {
isRecursiveExpr(e) and
// Widening is not a problem if the post-analysis in `getGuardedUpperBound` has overridden the widening.
// Note that the RHS of `<` may be multi-valued.
not getGuardedUpperBound(e) < getTruncatedUpperBounds(e)
}
/**
* Holds if `expr` has a provably empty range. For example:
*

View File

@@ -7,6 +7,7 @@ import semmle.code.cpp.exprs.Expr
import semmle.code.cpp.commons.Environment
import semmle.code.cpp.security.SecurityOptions
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.Sql
/**
* Extend this class to customize the security queries for
@@ -34,13 +35,11 @@ class SecurityOptions extends string {
* An argument to a function that is passed to a SQL server.
*/
predicate sqlArgument(string function, int arg) {
// MySQL C API
function = "mysql_query" and arg = 1
or
function = "mysql_real_query" and arg = 1
or
// SQLite3 C API
function = "sqlite3_exec" and arg = 1
exists(FunctionInput input, SqlExecutionFunction sql |
sql.hasName(function) and
input.isParameterDeref(arg) and
sql.hasSqlArgument(input)
)
}
/**

View File

@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 9.3
* @precision medium
* @precision high
* @id cpp/static-buffer-overflow
* @tags reliability
* security
@@ -55,6 +55,8 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) {
loop.counter().getAnAccess() = bufaccess.getArrayOffset() and
// Ensure that we don't have an upper bound on the array index that's less than the buffer size.
not upperBound(bufaccess.getArrayOffset().getFullyConverted()) < bufaccess.bufferSize() and
// The upper bounds analysis must not have been widended
not upperBoundMayBeWidened(bufaccess.getArrayOffset().getFullyConverted()) and
msg =
"Potential buffer-overflow: counter '" + loop.counter().toString() + "' <= " +
loop.limit().toString() + " but '" + bufaccess.buffer().getName() + "' has " +
@@ -130,11 +132,13 @@ predicate outOfBounds(BufferAccess bufaccess, string msg) {
(
access > size
or
access = size and not exists(AddressOfExpr addof | bufaccess = addof.getOperand())
access = size and
not exists(AddressOfExpr addof | bufaccess = addof.getOperand()) and
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild() = bufaccess)
) and
msg =
"Potential buffer-overflow: '" + buf + "' has size " + size.toString() + " but '" + buf + "[" +
access.toString() + "]' is accessed here."
access.toString() + "]' may be accessed here."
)
}

View File

@@ -30,7 +30,15 @@ class Configuration extends TaintTrackingConfiguration {
}
override predicate isBarrier(Expr e) {
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
super.isBarrier(e)
or
e.getUnspecifiedType() instanceof IntegralType
or
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
e = sql.getACallToThisFunction().getArgument(arg) and
input.isParameterDeref(arg) and
sql.barrierSqlArgument(input, _)
)
}
}

View File

@@ -1,28 +0,0 @@
#include <iostream>
#include <stdexcept>
#include <pqxx/pqxx>
int main(int argc, char ** argv) {
if (argc != 2) {
throw std::runtime_error("Give me a string!");
}
pqxx::connection c;
pqxx::work w(c);
// BAD
char *userName = argv[1];
char query1[1000] = {0};
sprintf(query1, "SELECT UID FROM USERS where name = \"%s\"", userName);
pqxx::row r = w.exec1(query1);
w.commit();
std::cout << r[0].as<int>() << std::endl;
// GOOD
pqxx::result r2 = w.exec("SELECT " + w.quote(argv[1]));
w.commit();
std::cout << r2[0][0].c_str() << std::endl;
return 0;
}

View File

@@ -1,31 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The code passes user input as part of a SQL query without escaping special elements.
It generates a SQL query to Postgres using <code>sprintf</code>,
with the user-supplied data directly passed as an argument
to <code>sprintf</code>. This leaves the code vulnerable to attack by SQL Injection.</p>
</overview>
<recommendation>
<p>Use a library routine to escape characters in the user-supplied
string before converting it to SQL. Use <code>esc</code> and <code>quote</code> pqxx library functions.</p>
</recommendation>
<example>
<sample src="SqlPqxxTainted.cpp" />
</example>
<references>
<li>MSDN Library: <a href="https://docs.microsoft.com/en-us/sql/relational-databases/security/sql-injection">SQL Injection</a>.</li>
<!-- LocalWords: SQL CWE
-->
</references>
</qhelp>

View File

@@ -1,113 +0,0 @@
/**
* @name Uncontrolled data in SQL query to Postgres
* @description Including user-supplied data in a SQL query to Postgres
* without neutralizing special elements can make code
* vulnerable to SQL Injection.
* @kind path-problem
* @problem.severity error
* @precision high
* @id cpp/sql-injection-via-pqxx
* @tags security
* external/cwe/cwe-089
*/
import cpp
import semmle.code.cpp.security.Security
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph
predicate pqxxTransationClassNames(string className, string namespace) {
namespace = "pqxx" and
className in [
"dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction",
"subtransaction", "transaction", "basic_transaction", "transaction_base", "work"
]
}
predicate pqxxConnectionClassNames(string className, string namespace) {
namespace = "pqxx" and
className in ["connection_base", "basic_connection", "connection"]
}
predicate pqxxTransactionSqlArgument(string function, int arg) {
function = "exec" and arg = 0
or
function = "exec0" and arg = 0
or
function = "exec1" and arg = 0
or
function = "exec_n" and arg = 1
or
function = "exec_params" and arg = 0
or
function = "exec_params0" and arg = 0
or
function = "exec_params1" and arg = 0
or
function = "exec_params_n" and arg = 1
or
function = "query_value" and arg = 0
or
function = "stream" and arg = 0
}
predicate pqxxConnectionSqlArgument(string function, int arg) { function = "prepare" and arg = 1 }
Expr getPqxxSqlArgument() {
exists(FunctionCall fc, Expr e, int argIndex, UserType t |
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
e = fc.getQualifier() and
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
// and return pointer to a connection/transation object
e.getType().refersTo(t) and
// transaction exec and connection prepare variations
(
pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) and
pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex)
or
pqxxConnectionClassNames(t.getName(), t.getNamespace().getName()) and
pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex)
) and
result = fc.getArgument(argIndex)
)
}
predicate pqxxEscapeArgument(string function, int arg) {
arg = 0 and
function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"]
}
predicate isEscapedPqxxArgument(Expr argExpr) {
exists(FunctionCall fc, Expr e, int argIndex, UserType t |
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
e = fc.getQualifier() and
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
// and return pointer to a connection/transation object
e.getType().refersTo(t) and
// transaction and connection escape functions
(
pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) or
pqxxConnectionClassNames(t.getName(), t.getNamespace().getName())
) and
pqxxEscapeArgument(fc.getTarget().getName(), argIndex) and
// is escaped arg == argExpr
argExpr = fc.getArgument(argIndex)
)
}
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "SqlPqxxTainted" }
override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() = getPqxxSqlArgument() }
override predicate isSanitizer(DataFlow::Node node) { isEscapedPqxxArgument(node.asExpr()) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause
where
config.hasFlowPath(source, sink) and
isUserInput(source.getNode().asExpr(), taintCause)
select sink, source, sink, "This argument to a SQL query function is derived from $@", source,
"user input (" + taintCause + ")"

View File

@@ -0,0 +1,30 @@
/**
* @name unsigned to signed used in pointer arithmetic
* @description finds unsigned to signed conversions used in pointer arithmetic, potentially causing an out-of-bound access
* @id cpp/sign-conversion-pointer-arithmetic
* @kind problem
* @problem.severity warning
* @tags reliability
* security
* external/cwe/cwe-787
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.security.Overflow
from FunctionCall call, Function f, Parameter p, DataFlow::Node sink, PointerArithmeticOperation pao
where
f = call.getTarget() and
p = f.getAParameter() and
p.getUnspecifiedType().(IntegralType).isSigned() and
call.getArgument(p.getIndex()).getUnspecifiedType().(IntegralType).isUnsigned() and
pao.getAnOperand() = sink.asExpr() and
not exists(Operation a | guardedLesser(a, sink.asExpr())) and
not exists(Operation b | guardedGreater(b, call.getArgument(p.getIndex()))) and
not call.getArgument(p.getIndex()).isConstant() and
DataFlow::localFlow(DataFlow::parameterNode(p), sink) and
p.getUnspecifiedType().getSize() < 8
select call,
"This call: $@ passes an unsigned int to a function that requires a signed int: $@. And then used in pointer arithmetic: $@",
call, call.toString(), f, f.toString(), sink, sink.toString()

View File

@@ -599,6 +599,10 @@
| test.c:675:7:675:7 | y | -2147483648 |
| test.c:684:7:684:7 | x | -2147483648 |
| test.c:689:7:689:7 | x | -2147483648 |
| test.c:696:8:696:8 | x | 2147483647 |
| test.c:696:12:696:12 | y | 256 |
| test.c:697:9:697:9 | x | 2147483647 |
| test.c:698:9:698:9 | y | 256 |
| test.cpp:10:7:10:7 | b | -2147483648 |
| test.cpp:11:5:11:5 | x | -2147483648 |
| test.cpp:13:10:13:10 | x | -2147483648 |

View File

@@ -689,3 +689,12 @@ label:
out(x);
goto label;
}
void test_overflow() {
const int x = 2147483647; // 2^31-1
const int y = 256;
if ((x + y) <= 512) {
out(x);
out(y);
}
}

View File

@@ -599,6 +599,10 @@
| test.c:675:7:675:7 | y | 2147483647 |
| test.c:684:7:684:7 | x | 2147483647 |
| test.c:689:7:689:7 | x | 15 |
| test.c:696:8:696:8 | x | 2147483647 |
| test.c:696:12:696:12 | y | 256 |
| test.c:697:9:697:9 | x | 2147483647 |
| test.c:698:9:698:9 | y | 256 |
| test.cpp:10:7:10:7 | b | 2147483647 |
| test.cpp:11:5:11:5 | x | 2147483647 |
| test.cpp:13:10:13:10 | x | 2147483647 |

View File

@@ -5,14 +5,10 @@
| test2.c:33:26:33:27 | 46 | Potential buffer-overflow: 'buffer' has size 40 not 46. |
| test2.c:34:22:34:23 | 47 | Potential buffer-overflow: 'buffer' has size 40 not 47. |
| test2.c:35:23:35:24 | 48 | Potential buffer-overflow: 'buffer' has size 40 not 48. |
| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' is accessed here. |
| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' is accessed here. |
| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' is accessed here. |
| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' is accessed here. |
| test.c:47:3:47:18 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
| test.c:54:3:54:26 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
| test.c:61:3:61:18 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
| test.c:72:3:72:11 | access to array | Potential buffer-overflow: 'buf' has size 1 but 'buf[1]' is accessed here. |
| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' may be accessed here. |
| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' may be accessed here. |
| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' may be accessed here. |
| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' may be accessed here. |
| test.cpp:19:3:19:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer1' has 3 elements. |
| test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer2' has 3 elements. |
| test.cpp:24:27:24:27 | 4 | Potential buffer-overflow: 'buffer1' has size 3 not 4. |

View File

@@ -44,21 +44,21 @@ void union_test() {
union u u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
u.ptr[sizeof(u)] = 0; // BAD
u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
void test_struct_union() {
struct { union u u; } v;
v.u.ptr[0] = 0; // GOOD
v.u.ptr[sizeof(union u)-1] = 0; // GOOD
v.u.ptr[sizeof(union u)] = 0; // BAD
v.u.ptr[sizeof(union u)] = 0; // BAD [NOT DETECTED]
}
void union_test2() {
union { char ptr[1]; unsigned long value; } u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
u.ptr[sizeof(u)] = 0; // BAD
u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
typedef struct {
@@ -69,5 +69,5 @@ typedef struct {
void test_alloc() {
// Special case of taking sizeof without any addition or multiplications
var_buf *b = malloc(sizeof(var_buf));
b->buf[1] = 0; // BAD
b->buf[1] = 0; // BAD [NOT DETECTED]
}

View File

@@ -23,3 +23,5 @@
| test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 |
| test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer |
| test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer |
| test.cpp:444:10:444:15 | buffer | Variable $@ may not be null terminated. | test.cpp:442:8:442:13 | buffer | buffer |
| test.cpp:450:16:450:21 | buffer | Variable $@ may not be null terminated. | test.cpp:448:8:448:13 | buffer | buffer |

View File

@@ -433,3 +433,36 @@ void test_read_fread(int read_src, FILE *s)
strlen(buffer); // GOOD
}
}
int printf(const char *format, ...);
void test_printf(char *str)
{
{
char buffer[1024];
printf(buffer, ""); // BAD
}
{
char buffer[1024];
printf("%s", buffer); // BAD
}
{
size_t len = strlen(str);
char *copied_str = (char *)malloc(len);
memcpy(copied_str, str, len);
printf("%s", copied_str); // BAD [NOT DETECTED]
}
{
size_t len = strlen(str);
char *copied_str = (char *)malloc(len + 1);
memcpy(copied_str, str, len + 1);
printf("%s", copied_str); // GOOD
}
}

View File

@@ -5,6 +5,7 @@ edges
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection |
subpaths
nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | semmle.label | ... + ... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument |

View File

@@ -5,6 +5,7 @@ edges
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
subpaths
nodes
| test.c:9:23:9:26 | argv | semmle.label | argv |
| test.c:9:23:9:26 | argv | semmle.label | argv |

View File

@@ -24,6 +24,7 @@ edges
| search.c:55:17:55:25 | raw_query indirection | search.c:14:24:14:28 | *query |
| search.c:57:5:57:15 | raw_query | search.c:22:24:22:28 | query |
| search.c:57:17:57:25 | raw_query indirection | search.c:22:24:22:28 | *query |
subpaths
nodes
| search.c:14:24:14:28 | *query | semmle.label | *query |
| search.c:14:24:14:28 | query | semmle.label | query |

View File

@@ -5,6 +5,15 @@ edges
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection |
subpaths
nodes
| test.c:15:20:15:23 | argv | semmle.label | argv |
| test.c:15:20:15:23 | argv | semmle.label | argv |
@@ -13,5 +22,15 @@ nodes
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
#select
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) |
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)) | test.cpp:43:27:43:30 | argv | user input (argv) |

View File

@@ -0,0 +1,48 @@
int sprintf(char* str, const char* format, ...);
namespace std
{
template<class charT> struct char_traits;
template <class T> class allocator {
public:
allocator() throw();
};
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
explicit basic_string(const Allocator& a = Allocator());
basic_string(const charT* s, const Allocator& a = Allocator());
const charT* c_str() const;
};
typedef basic_string<char> string;
}
namespace pqxx {
struct connection {};
struct row {};
struct result {};
struct work {
work(connection&);
row exec1(const char*);
result exec(const std::string&);
std::string quote(const char*);
};
}
int main(int argc, char** argv) {
pqxx::connection c;
pqxx::work w(c);
pqxx::row r = w.exec1(argv[1]); // BAD
pqxx::result r2 = w.exec(w.quote(argv[1])); // GOOD
return 0;
}

View File

@@ -12,6 +12,7 @@ edges
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:17:73:22 | data | test.cpp:37:73:37:76 | data |
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | *data |
subpaths
nodes
| test.cpp:37:73:37:76 | *data | semmle.label | *data |
| test.cpp:37:73:37:76 | data | semmle.label | data |

View File

@@ -47,6 +47,7 @@ edges
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | (const char *)... |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
subpaths
nodes
| test.cpp:24:30:24:36 | *command | semmle.label | *command |
| test.cpp:24:30:24:36 | command | semmle.label | command |

View File

@@ -1,3 +1,4 @@
edges
subpaths
nodes
#select

View File

@@ -72,12 +72,9 @@
| unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer |
| unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:16:7:16:11 | large | destination buffer |
| unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:34:14:34:18 | large | destination buffer |
| var_size_struct.cpp:54:5:54:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:32:8:32:10 | str | array |
| var_size_struct.cpp:55:5:55:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:38:8:38:10 | str | array |
| var_size_struct.cpp:71:3:71:8 | call to memset | This 'memset' operation accesses 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'strncpy' operation may access 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
| var_size_struct.cpp:87:3:87:19 | access to array | This array indexing operation accesses byte offset 67 but the $@ is only 64 bytes. | var_size_struct.cpp:78:7:78:14 | elements | array |
| var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
| var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
| var_size_struct.cpp:169:3:169:8 | call to memset | This 'memset' operation accesses 100 bytes but the $@ is only 1 byte. | var_size_struct.cpp:125:17:125:19 | arr | destination buffer |

View File

@@ -3,8 +3,6 @@
| tests.cpp:163:3:163:11 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
| tests.cpp:164:8:164:16 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
| tests.cpp:245:42:245:42 | 6 | Potential buffer-overflow: 'global_array_5' has size 5 not 6. |
| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. |
| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. |
| var_size_struct.cpp:54:5:54:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. |
| var_size_struct.cpp:55:5:55:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. |
| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
| var_size_struct.cpp:103:39:103:41 | 129 | Potential buffer-overflow: 'str' has size 128 not 129. |

View File

@@ -1,3 +1,4 @@
edges
subpaths
nodes
#select

View File

@@ -51,8 +51,8 @@ void testVarString(int n) {
s1->str[1] = '?'; // GOOD
s2->str[1] = '?'; // GOOD
s3->str[1] = '?'; // GOOD
s4->str[1] = '?'; // BAD
s5->str[1] = '?'; // BAD
s4->str[1] = '?'; // BAD [NOT DETECTED]
s5->str[1] = '?'; // BAD [NOT DETECTED]
}
}
@@ -166,7 +166,7 @@ void useVarStruct34(varStruct5 *vs5) {
void testVarStruct34(varStruct3 *vs3, varStruct4 *vs4, varStruct5 *vs5, varStruct6 *vs6, varStruct7 *vs7, varStruct8 *vs8, varStruct9 *vs9) {
memset(vs3->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
memset(vs4->arr, 'x', 100); // BAD: it's not variable size, so this is a buffer overflow
memset(vs4->arr, 'x', 100); // BAD: [NOT DETECTED] it's not variable size, so this is a buffer overflow
memset(vs5->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
memset(vs6->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
memset(vs7->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag

View File

@@ -1,12 +1,17 @@
| var_size_struct.cpp:13:8:13:17 | VarString1 | var_size_struct.cpp:15:8:15:10 | str |
| var_size_struct.cpp:18:8:18:17 | VarString2 | var_size_struct.cpp:20:8:20:10 | str |
| var_size_struct.cpp:24:8:24:17 | VarString3 | var_size_struct.cpp:26:8:26:10 | str |
| var_size_struct.cpp:30:8:30:17 | VarString4 | var_size_struct.cpp:32:8:32:10 | str |
| var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:38:8:38:10 | str |
| var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:39:8:39:11 | str2 |
| var_size_struct.cpp:61:8:61:17 | varStruct1 | var_size_struct.cpp:63:8:63:11 | data |
| var_size_struct.cpp:76:8:76:17 | varStruct2 | var_size_struct.cpp:78:7:78:14 | elements |
| var_size_struct.cpp:106:8:106:20 | notVarStruct2 | var_size_struct.cpp:107:8:107:10 | str |
| var_size_struct.cpp:119:8:119:17 | varStruct3 | var_size_struct.cpp:121:17:121:19 | arr |
| var_size_struct.cpp:123:8:123:17 | varStruct4 | var_size_struct.cpp:125:17:125:19 | arr |
| var_size_struct.cpp:127:8:127:17 | varStruct5 | var_size_struct.cpp:129:17:129:19 | arr |
| var_size_struct.cpp:131:8:131:17 | varStruct6 | var_size_struct.cpp:133:17:133:19 | arr |
| var_size_struct.cpp:135:8:135:17 | varStruct7 | var_size_struct.cpp:137:17:137:19 | arr |
| var_size_struct.cpp:139:8:139:17 | varStruct8 | var_size_struct.cpp:141:9:141:11 | arr |
| var_size_struct.cpp:143:8:143:17 | varStruct9 | var_size_struct.cpp:145:17:145:19 | arr |
| var_size_struct.cpp:181:8:181:18 | PseudoUnion | var_size_struct.cpp:183:7:183:10 | data |

View File

@@ -49,6 +49,7 @@ edges
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection |
subpaths
nodes
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:25 | argv | semmle.label | argv |

View File

@@ -17,6 +17,7 @@ edges
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection |
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection |
subpaths
nodes
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument |
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | semmle.label | ... + ... |

View File

@@ -247,6 +247,13 @@ edges
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
| argvLocal.c:170:15:170:26 | i10 indirection | argvLocal.c:9:25:9:31 | *correct |
subpaths
| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument |
| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument |
| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument |
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument |
nodes
| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct |
| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct |

View File

@@ -51,6 +51,7 @@ edges
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | (const char *)... |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 indirection |
subpaths
nodes
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |

View File

@@ -46,6 +46,7 @@ edges
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... |
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 |
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection |
subpaths
nodes
| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |

View File

@@ -71,6 +71,7 @@ edges
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection |
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection |
subpaths
nodes
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
| ifs.c:61:8:61:11 | argv | semmle.label | argv |

View File

@@ -3,6 +3,7 @@ edges
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
subpaths
nodes
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |

View File

@@ -73,6 +73,7 @@ edges
| test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... |
| test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... |
| test.cpp:305:18:305:21 | get_size output argument [[]] | test.cpp:305:18:305:21 | Chi |
subpaths
nodes
| test.cpp:40:21:40:24 | argv | semmle.label | argv |
| test.cpp:40:21:40:24 | argv | semmle.label | argv |

View File

@@ -23,6 +23,7 @@ edges
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
subpaths
nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |

View File

@@ -17,6 +17,7 @@ edges
| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address |
| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address |
| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address indirection |
subpaths
nodes
| test.cpp:16:25:16:30 | call to getenv | semmle.label | call to getenv |
| test.cpp:16:25:16:42 | (const char *)... | semmle.label | (const char *)... |

View File

@@ -5,6 +5,7 @@ edges
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection |
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection |
subpaths
nodes
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
| test.cpp:54:17:54:20 | argv | semmle.label | argv |

View File

@@ -7,6 +7,7 @@ edges
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp |
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:10:41:38 | ! ... |
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp |
subpaths
nodes
| test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv |
| test.cpp:20:29:20:47 | (const char *)... | semmle.label | (const char *)... |

View File

@@ -165,7 +165,6 @@ namespace Semmle.Autobuild.Shared
{
if (environment is not null)
environment.ForEach(kvp => pi.Environment[kvp.Key] = kvp.Value);
pi.Environment["CODEQL_REDUCE_FILES_FOLDERS_RELATIONS"] = "true";
}
return pi;
}

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* added support for ServiceStack framework with support for SQL injection, XSS and external API calls

View File

@@ -10,7 +10,6 @@ extra_env_vars:
CORECLR_ENABLE_PROFILING: "1"
CORECLR_PROFILER: "{A3C70A64-7D41-4A94-A3F6-FD47D9259997}"
CORECLR_PROFILER_PATH_64: "${env.CODEQL_EXTRACTOR_CSHARP_ROOT}/tools/${env.CODEQL_PLATFORM}/clrtracer64${env.CODEQL_PLATFORM_DLL_EXTENSION}"
CODEQL_REDUCE_FILES_FOLDERS_RELATIONS: "true"
file_types:
- name: cs
display_name: C# sources

View File

@@ -1,2 +1,6 @@
package,sink,source,summary,sink:html,sink:xss,source:local,summary:taint
System,5,3,13,4,1,3,13
package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint
Dapper,55,,,,,,55,,,
Microsoft.ApplicationBlocks.Data,28,,,,,,28,,,
MySql.Data.MySqlClient,48,,,,,,48,,,
ServiceStack,194,,7,27,,75,92,,,7
System,28,3,13,,4,,23,1,3,13
1 package sink source summary sink:code sink:html sink:remote sink:sql sink:xss source:local summary:taint
2 System Dapper 5 55 3 13 4 55 1 3 13
3 Microsoft.ApplicationBlocks.Data 28 28
4 MySql.Data.MySqlClient 48 48
5 ServiceStack 194 7 27 75 92 7
6 System 28 3 13 4 23 1 3 13

View File

@@ -7,6 +7,8 @@ C# framework & library support
:widths: auto
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
System,"``System.*``, ``System``",3,13,5,5
Totals,,3,13,5,5
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",3,13,28,5
Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``MySql.Data.MySqlClient``",,,131,
Totals,,3,20,353,5

View File

@@ -1,2 +1,3 @@
Framework name,URL,Namespace prefixes
System,,System.* System
ServiceStack,https://servicestack.net/,ServiceStack.* ServiceStack
1 Framework name URL Namespace prefixes
2 System System.* System
3 ServiceStack https://servicestack.net/ ServiceStack.* ServiceStack

View File

@@ -17,7 +17,7 @@ module Gvn {
string getNameNested(Type t) {
if not t instanceof NestedType or t.(NestedType).getDeclaringType() instanceof GenericType
then result = t.getName()
else result = getNameNested(t.(NestedType).getDeclaringType()) + "." + t.getName()
else result = getNameNested(t.(NestedType).getDeclaringType()) + "+" + t.getName()
}
/**
@@ -326,79 +326,53 @@ module Gvn {
getTypeArgument(k, t, i) = TTypeParameterGvnType()
}
/**
* Hold if (non-type-parameters) `arg1` and `arg2` are unifiable, and both are
* the `i`th type argument of a compound type of kind `k`.
*/
pragma[nomagic]
private predicate unifiableNonTypeParameterTypeArguments(
CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i
) {
exists(int j |
arg1 = getNonTypeParameterTypeArgument(k, _, i) and
arg2 = getNonTypeParameterTypeArgument(k, _, j) and
i <= j and
j <= i
|
arg1 = arg2
or
unifiable(arg1, arg2)
)
}
/**
* Hold if `arg1` and `arg2` are unifiable, and both are the `i`th type argument
* of a compound type of kind `k`.
*
* `subsumes` indicates whether `arg1` in fact subsumes `arg2`.
*/
pragma[nomagic]
private predicate unifiableTypeArguments(
CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i
CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i, boolean subsumes
) {
unifiableNonTypeParameterTypeArguments(k, arg1, arg2, i)
or
exists(int j |
arg1 = TTypeParameterGvnType() and
typeArgumentIsTypeParameter(k, _, i) and
arg2 = getTypeArgument(k, _, j) and
i <= j and
j <= i
arg1 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and
arg2 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and
(
arg1 = arg2 and
subsumes = true
or
unifiable(arg1, arg2, subsumes)
)
or
exists(int j |
arg1 = getTypeArgument(k, _, i) and
typeArgumentIsTypeParameter(k, _, j) and
arg2 = TTypeParameterGvnType() and
i <= j and
j <= i
)
arg1 = TTypeParameterGvnType() and
typeArgumentIsTypeParameter(k, _, pragma[only_bind_into](i)) and
arg2 = getTypeArgument(k, _, pragma[only_bind_into](i)) and
subsumes = true
or
arg1 = getNonTypeParameterTypeArgument(k, _, pragma[only_bind_into](i)) and
typeArgumentIsTypeParameter(k, _, pragma[only_bind_into](i)) and
arg2 = TTypeParameterGvnType() and
subsumes = false
}
pragma[nomagic]
private predicate unifiableSingle0(
CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg1, GvnTypeArgument arg2
CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg1, GvnTypeArgument arg2,
boolean subsumes
) {
unifiableTypeArguments(k, arg1, arg2, 0) and
unifiableTypeArguments(k, arg1, arg2, 0, subsumes) and
arg2 = getTypeArgument(k, t2, 0) and
k.getNumberOfTypeParameters() = 1
}
/**
* Holds if the type arguments of types `t1` and `t2` are unifiable, `t1`
* and `t2` are of the same kind, and the number of type arguments is 1.
*/
private predicate unifiableSingle(ConstructedGvnType t1, ConstructedGvnType t2) {
exists(CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2 |
unifiableSingle0(k, t2, arg1, arg2) and
arg1 = getTypeArgument(k, t1, 0)
)
}
pragma[nomagic]
private predicate unifiableMultiple01Aux0(
CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg10, GvnTypeArgument arg21
CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg10, GvnTypeArgument arg21,
boolean subsumes
) {
exists(GvnTypeArgument arg20 |
unifiableTypeArguments(k, arg10, arg20, 0) and
unifiableTypeArguments(k, arg10, arg20, 0, subsumes) and
arg20 = getTypeArgument(k, t2, 0) and
arg21 = getTypeArgument(k, t2, 1)
)
@@ -406,43 +380,24 @@ module Gvn {
pragma[nomagic]
private predicate unifiableMultiple01Aux1(
CompoundTypeKind k, ConstructedGvnType t1, GvnTypeArgument arg10, GvnTypeArgument arg21
CompoundTypeKind k, ConstructedGvnType t1, GvnTypeArgument arg10, GvnTypeArgument arg21,
boolean subsumes
) {
exists(GvnTypeArgument arg11 |
unifiableTypeArguments(k, arg11, arg21, 1) and
unifiableTypeArguments(k, arg11, arg21, 1, subsumes) and
arg10 = getTypeArgument(k, t1, 0) and
arg11 = getTypeArgument(k, t1, 1)
)
}
/**
* Holds if the first two type arguments of types `t1` and `t2` are unifiable,
* and both `t1` and `t2` are of kind `k`.
*/
private predicate unifiableMultiple01(
CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2
) {
exists(GvnTypeArgument arg10, GvnTypeArgument arg21 |
unifiableMultiple01Aux0(k, t2, arg10, arg21) and
unifiableMultiple01Aux1(k, t1, arg10, arg21)
)
}
pragma[nomagic]
private predicate unifiableMultiple2Aux(
CompoundTypeKind k, ConstructedGvnType t2, int i, GvnTypeArgument arg1, GvnTypeArgument arg2
CompoundTypeKind k, ConstructedGvnType t2, int i, GvnTypeArgument arg1, boolean subsumes
) {
unifiableTypeArguments(k, arg1, arg2, i) and
arg2 = getTypeArgument(k, t2, i) and
i >= 2
}
private predicate unifiableMultiple2(
CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i
) {
exists(GvnTypeArgument arg1, GvnTypeArgument arg2 |
unifiableMultiple2Aux(k, t2, i, arg1, arg2) and
arg1 = getTypeArgument(k, t1, i)
exists(GvnTypeArgument arg2 |
unifiableTypeArguments(k, arg1, arg2, i, subsumes) and
arg2 = getTypeArgument(k, t2, i) and
i >= 2
)
}
@@ -452,43 +407,33 @@ module Gvn {
*/
pragma[nomagic]
private predicate unifiableMultiple(
CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i
CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i, boolean subsumes
) {
unifiableMultiple01(k, t1, t2) and i = 1
exists(GvnTypeArgument arg10, GvnTypeArgument arg21, boolean subsumes1, boolean subsumes2 |
unifiableMultiple01Aux0(k, t2, arg10, arg21, subsumes1) and
unifiableMultiple01Aux1(k, t1, arg10, arg21, subsumes2) and
subsumes = subsumes1.booleanAnd(subsumes2)
) and
i = 1
or
unifiableMultiple(k, t1, t2, i - 1) and
unifiableMultiple2(k, t1, t2, i)
}
private newtype TTypePath =
TTypePathNil() or
TTypePathCons(int head, TTypePath tail) { exists(getTypeAtCons(_, head, tail)) }
/**
* Gets the GVN inside GVN `t`, by following the path `path`, if any.
*/
private GvnType getTypeAt(GvnType t, TTypePath path) {
path = TTypePathNil() and
result = t
or
exists(ConstructedGvnTypeList l, int head, TTypePath tail |
t = TConstructedGvnType(l) and
path = TTypePathCons(head, tail) and
result = getTypeAtCons(l, head, tail)
exists(GvnTypeArgument arg1, boolean subsumes1, boolean subsumes2 |
unifiableMultiple(k, t1, t2, i - 1, subsumes1) and
unifiableMultiple2Aux(k, t2, i, arg1, subsumes2) and
arg1 = getTypeArgument(k, t1, i) and
subsumes = subsumes1.booleanAnd(subsumes2)
)
}
private GvnType getTypeAtCons(ConstructedGvnTypeList l, int head, TTypePath tail) {
result = getTypeAt(l.getArg(head), tail)
}
/**
* Gets the leaf GVN inside GVN `t`, by following the path `path`, if any.
*/
pragma[noinline]
private GvnType getLeafTypeAt(GvnType t, TTypePath path) {
result = getTypeAt(t, path) and
not result instanceof ConstructedGvnType
pragma[nomagic]
private predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2, boolean subsumes) {
exists(CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2 |
unifiableSingle0(k, t2, arg1, arg2, subsumes) and
arg1 = getTypeArgument(k, t1, 0)
)
or
exists(CompoundTypeKind k |
unifiableMultiple(k, t1, t2, k.getNumberOfTypeParameters() - 1, subsumes)
)
}
cached
@@ -540,33 +485,20 @@ module Gvn {
}
/**
* Holds if GVNs `t1` and `t2` can be unified. That is, is it possible to
* Holds if GVNs `t1` and `t2` can be unified. That is, it is possible to
* replace all type parameters in `t1` and `t2` with some GVNs (possibly
* type parameters themselves) to make the two substituted terms equal.
*/
cached
predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2) {
unifiableSingle(t1, t2)
or
exists(CompoundTypeKind k | unifiableMultiple(k, t1, t2, k.getNumberOfTypeParameters() - 1))
}
predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2) { unifiable(t1, t2, _) }
/**
* Holds if GVN `t1` subsumes GVN `t2`. That is, is it possible to replace all
* Holds if GVN `t1` subsumes GVN `t2`. That is, it is possible to replace all
* type parameters in `t1` with some GVNs (possibly type parameters themselves)
* to make the two substituted terms equal.
*/
cached
predicate subsumes(ConstructedGvnType t1, ConstructedGvnType t2) {
unifiable(t1, t2) and // subsumption implies unification
forall(TTypePath path, GvnType leaf1 | leaf1 = getLeafTypeAt(t1, path) |
exists(GvnType child2 | child2 = getTypeAt(t2, path) |
leaf1 = TTypeParameterGvnType()
or
leaf1 = child2
)
)
}
predicate subsumes(ConstructedGvnType t1, ConstructedGvnType t2) { unifiable(t1, t2, true) }
}
import Cached

View File

@@ -88,6 +88,9 @@ private module Frameworks {
private import semmle.code.csharp.security.dataflow.flowsinks.Html
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.security.dataflow.XSSSinks
private import semmle.code.csharp.frameworks.ServiceStack
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.frameworks.EntityFramework
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -3643,9 +3643,10 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, apout) and
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, apout, _, unbindConf(arg.getConfiguration()))
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**

View File

@@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.system.data.Entity
private import semmle.code.csharp.frameworks.system.collections.Generic
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.dataflow.FlowSummary
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate
/**
@@ -234,26 +235,29 @@ module EntityFramework {
override Expr getSql() { result = this.getArgumentForParameter(sqlParam) }
}
/** A call to `System.Data.Entity.DbSet.SqlQuery`. */
class SystemDataEntityDbSetSqlExpr extends SqlExpr, MethodCall {
SystemDataEntityDbSetSqlExpr() {
this.getTarget() = any(SystemDataEntity::DbSet dbSet).getSqlQueryMethod()
/** The sink method `System.Data.Entity.DbSet.SqlQuery`. */
private class SystemDataEntityDbSetSqlQuerySinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
["System.Data.Entity;DbSet;false;SqlQuery;(System.String,System.Object[]);;Argument[0];sql"]
}
override Expr getSql() { result = this.getArgumentForName("sql") }
}
/** A call to a method in `System.Data.Entity.Database` that executes SQL. */
class SystemDataEntityDatabaseSqlExpr extends SqlExpr, MethodCall {
SystemDataEntityDatabaseSqlExpr() {
exists(SystemDataEntity::Database db |
this.getTarget() = db.getSqlQueryMethod() or
this.getTarget() = db.getExecuteSqlCommandMethod() or
this.getTarget() = db.getExecuteSqlCommandAsyncMethod()
)
/** A sink method in `System.Data.Entity.Database` that executes SQL. */
private class SystemDataEntityDatabaseSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
"System.Data.Entity;Database;false;SqlQuery;(System.Type,System.String,System.Object[]);;Argument[1];sql",
"System.Data.Entity;Database;false;SqlQuery<>;(System.String,System.Object[]);;Argument[0];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommand;(System.String,System.Object[]);;Argument[0];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommand;(System.Data.Entity.TransactionalBehavior,System.String,System.Object[]);;Argument[1];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.Data.Entity.TransactionalBehavior,System.String,System.Threading.CancellationToken,System.Object[]);;Argument[1];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.String,System.Threading.CancellationToken,System.Object[]);;Argument[0];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.String,System.Object[]);;Argument[0];sql",
"System.Data.Entity;Database;false;ExecuteSqlCommandAsync;(System.Data.Entity.TransactionalBehavior,System.String,System.Object[]);;Argument[1];sql"
]
}
override Expr getSql() { result = this.getArgumentForName("sql") }
}
/** Holds if `t` is compatible with a DB column type. */

View File

@@ -0,0 +1,321 @@
/**
* General modelling of ServiceStack framework including separate modules for:
* - flow sources
* - SQLi sinks
* - XSS sinks
*/
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
/** A class representing a Service */
private class ServiceClass extends Class {
ServiceClass() {
this.getBaseClass+().hasQualifiedName("ServiceStack", "Service") or
this.getABaseType*().getABaseInterface().hasQualifiedName("ServiceStack", "IService")
}
/** Get a method that handles incoming requests */
Method getARequestMethod() {
exists(string name |
result = this.getAMethod(name) and
name.regexpMatch("(Get|Post|Put|Delete|Any|Option|Head|Patch)(Async|Json|Xml|Jsv|Csv|Html|Protobuf|Msgpack|Wire)?")
)
}
}
/** Top-level Request DTO types */
private class RequestDTO extends Class {
RequestDTO() {
this.getABaseType*().getABaseInterface().hasQualifiedName("ServiceStack", "IReturn")
}
}
/** Flow sources for the ServiceStack framework */
module Sources {
private import semmle.code.csharp.security.dataflow.flowsources.Remote
/**
* Remote flow sources for ServiceStack. Parameters of well-known `request` methods.
*/
private class ServiceStackSource extends RemoteFlowSource {
ServiceStackSource() {
exists(ServiceClass service |
service.getARequestMethod().getAParameter() = this.asParameter()
)
}
override string getSourceType() { result = "ServiceStack request parameter" }
}
}
private class ServiceStackRemoteSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// IRestClient
"ServiceStack;IRestClient;true;Send<>;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;IRestClient;true;Patch<>;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClient;true;Post<>;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClient;true;Put<>;(System.String,System.Object);;Argument[1];remote",
// IRestClientSync
"ServiceStack;IRestClientSync;true;CustomMethod;(System.String,ServiceStack.IReturnVoid);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;CustomMethod<>;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;CustomMethod<>;(System.String,ServiceStack.IReturn<TResponse>);;Argument[1];remote",
"ServiceStack;IRestClientSync;true;Delete;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Delete<>;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Delete<>;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get<>;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Get<>;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch<>;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Patch<>;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post<>;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Post<>;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put;(ServiceStack.IReturnVoid);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put<>;(System.Object);;Argument[0];remote",
"ServiceStack;IRestClientSync;true;Put<>;(ServiceStack.IReturn<TResponse>);;Argument[0];remote",
// IRestGateway
"ServiceStack;IRestGateway;true;Delete<>;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Get<>;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Post<>;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Put<>;(ServiceStack.IReturn<T>);;Argument[0];remote",
"ServiceStack;IRestGateway;true;Send<>;(ServiceStack.IReturn<T>);;Argument[0];remote",
// IOneWayClient
"ServiceStack;IOneWayClient;true;SendAllOneWay;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[1];remote",
"ServiceStack;IOneWayClient;true;SendOneWay;(System.String,System.Object);;Argument[1];remote",
"ServiceStack;IOneWayClient;true;SendOneWay;(System.Object);;Argument[0];remote",
// IServiceGateway
"ServiceStack;IServiceGateway;true;Publish;(System.Object);;Argument[0];remote",
"ServiceStack;IServiceGateway;true;PublishAll;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[0];remote",
"ServiceStack;IServiceGateway;true;Send<>;(System.Object);;Argument[0];remote",
"ServiceStack;IServiceGateway;true;SendAll<>;(System.Collections.Generic.IEnumerable<System.Object>);;Element of Argument[0];remote",
// IRestClientAsync
"ServiceStack;IRestClientAsync;true;CustomMethodAsync;(System.String,ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;CustomMethodAsync<>;(System.String,System.Object,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;CustomMethodAsync<>;(System.String,ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[1];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;DeleteAsync<>;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;GetAsync<>;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PatchAsync<>;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PostAsync<>;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync;(ServiceStack.IReturnVoid,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestClientAsync;true;PutAsync<>;(ServiceStack.IReturn<TResponse>,System.Threading.CancellationToken);;Argument[0];remote",
// IRestGatewayAsync
"ServiceStack;IRestGatewayAsync;true;DeleteAsync<>;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;GetAsync<>;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;PostAsync<>;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;PutAsync<>;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IRestGatewayAsync;true;SendAsync<>;(ServiceStack.IReturn<T>,System.Threading.CancellationToken);;Argument[0];remote",
// IServiceGatewayAsync
"ServiceStack;IServiceGatewayAsync;true;PublishAsync;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;PublishAllAsync;(System.Collections.Generic.IEnumerable<System.Object>,System.Threading.CancellationToken);;Element of Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;SendAsync<>;(System.Object,System.Threading.CancellationToken);;Argument[0];remote",
"ServiceStack;IServiceGatewayAsync;true;SendAllAsync<>;(System.Collections.Generic.IEnumerable<System.Object>,System.Threading.CancellationToken);;Element of Argument[0];remote",
// ServiceClientBase
"ServiceStack;ServiceClientBase;true;Publish<>;(T);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Publish<>;(ServiceStack.Messaging.IMessage<T>);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Delete;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Get;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Patch;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Post;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Put;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(System.Object);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;Head;(ServiceStack.IReturn);;Argument[0];remote",
"ServiceStack;ServiceClientBase;true;CustomMethod;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;CustomMethod<>;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;CustomMethodAsync<>;(System.String,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytes;(System.String,System.String,System.Object);;Argument[2];remote",
"ServiceStack;ServiceClientBase;true;DownloadBytesAsync;(System.String,System.String,System.Object);;Argument[2];remote"
]
}
}
private class ServiceStackSqlSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// SqlExpression<T>
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeFrom;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeGroupBy;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeHaving;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeOrderBy;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String,System.Boolean);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeSelect;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;SqlExpression<>;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql",
// IUntypedSqlExpression
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeAnd;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeFrom;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeOr;(System.String,System.Object[]);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeSelect;(System.String);;Argument[0];sql",
"ServiceStack.OrmLite;IUntypedSqlExpression;true;UnsafeWhere;(System.String,System.Object[]);;Argument[0];sql",
// OrmLiteReadApi
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ExecuteNonQuery;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Exists<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Dictionary<,>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup<,>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Lookup<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;KeyValuePairs;(System.Data.IDbConnection,System.String,System.System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Scalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.Type,System.String,System.Object);;Argument[2];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Select<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SelectLazy<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SelectNonDefaults<>;(System.Data.IDbConnection,System.String,T);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Single<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Single<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlColumn<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlList<>;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;SqlScalar<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Column<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;Column<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnDistinct<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy<>;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApi;false;ColumnLazy<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
// OrmLiteReadExpressionsApi
"ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadExpressionsApi;false;RowCount;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>);;Argument[1];sql",
// OrmLiteReadExpressionsApiAsync
"ServiceStack.OrmLite;OrmLiteReadExpressionsApiAsync;false;RowCountAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
// OrmLiteReadApiAsync
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ColumnDistinctAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;DictionaryAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExecuteNonQueryAsync;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ExistsAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;KeyValuePairsAsync<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbCommand,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;LookupAsync<,>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;ScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Threading.CancellationToken);;Argument[2];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SelectNonDefaultsAsync<>;(System.Data.IDbConnection,System.String,T,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SingleAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlColumnAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlListAsync<>;(System.Data.IDbConnection,System.String,System.Action<System.Data.IDbCommand>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Collections.Generic.IEnumerable<System.Data.IDbDataParameter>,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteReadApiAsync;false;SqlScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql",
// Write API
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Object);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApi;false;ExecuteSql;(System.Data.IDbConnection,System.String,System.Collections.Generic.Dictionary<System.String,System.Object>);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"ServiceStack.OrmLite;OrmLiteWriteApiAsync;false;ExecuteSqlAsync;(System.Data.IDbConnection,System.String,System.Object,System.Threading.CancellationToken);;Argument[1];sql"
]
}
}
private class ServiceStackCodeInjectionSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// Redis API
"ServiceStack.Redis;IRedisClient;true;Custom;(System.Object[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecCachedLua;(System.String,System.Func<System.String,T>);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[],System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLua;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[],System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsInt;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[],System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsList;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[],System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;ExecLuaAsString;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClient;true;LoadLuaScript;(System.String);;Argument[0];code",
// IRedisClientAsync
"ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;CustomAsync;(System.Object[],System.Threading.CancellationToken);;Element of Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecCachedLuaAsync;(System.String,System.Func<System.String,System.Threading.Tasks.ValueTask<T>>,System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsync;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsIntAsync;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsStringAsync;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[],System.Threading.CancellationToken);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;ExecLuaAsListAsync;(System.String,System.String[]);;Argument[0];code",
"ServiceStack.Redis;IRedisClientAsync;true;LoadLuaScriptAsync;(System.String,System.Threading.CancellationToken);;Argument[0];code"
]
}
}
private class ServiceStackXssSummaryModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"ServiceStack;HttpResult;false;HttpResult;(System.String,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object,System.Net.HttpStatusCode);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Object);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.IO.Stream,System.String);;Argument[0];ReturnValue;taint",
"ServiceStack;HttpResult;false;HttpResult;(System.Byte[],System.String);;Argument[0];ReturnValue;taint"
]
}
}
/** XSS support for ServiceStack framework */
module XSS {
private import semmle.code.csharp.security.dataflow.XSSSinks
/** XSS sinks for ServiceStack */
class XssSink extends Sink {
XssSink() {
exists(ServiceClass service, Method m, Expr e |
service.getARequestMethod() = m and
this.asExpr() = e and
m.canReturn(e) and
(
e.getType() instanceof StringType or
e.getType().hasQualifiedName("ServiceStack", "HttpResult")
)
)
}
}
}

View File

@@ -7,6 +7,7 @@ private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.NHibernate
private import semmle.code.csharp.frameworks.Dapper
private import semmle.code.csharp.dataflow.DataFlow4
private import semmle.code.csharp.dataflow.ExternalFlow
/** An expression containing a SQL command. */
abstract class SqlExpr extends Expr {
@@ -28,71 +29,236 @@ class CommandTextAssignmentSqlExpr extends SqlExpr, AssignExpr {
override Expr getSql() { result = this.getRValue() }
}
/** A construction of an `IDbCommand` object. */
/** A construction of an unknown `IDbCommand` object. */
class IDbCommandConstructionSqlExpr extends SqlExpr, ObjectCreation {
IDbCommandConstructionSqlExpr() {
exists(InstanceConstructor ic | ic = this.getTarget() |
ic.getDeclaringType().getABaseType*() instanceof SystemDataIDbCommandInterface and
ic.getParameter(0).getType() instanceof StringType
ic.getParameter(0).getType() instanceof StringType and
not ic.getDeclaringType()
.hasQualifiedName([
// Known sealed classes:
"System.Data.SqlClient.SqlCommand", "System.Data.Odbc.OdbcCommand",
"System.Data.OleDb.OleDbCommand", "System.Data.EntityClient.EntityCommand"
])
)
}
override Expr getSql() { result = this.getArgument(0) }
}
/** A construction of a known `IDbCommand` object. */
private class IDbCommandConstructionSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// SqlCommand
"System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String);;Argument[0];sql",
"System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String,System.Data.SqlClient.SqlConnection);;Argument[0];sql",
"System.Data.SqlClient;SqlCommand;false;SqlCommand;(System.String,System.Data.SqlClient.SqlConnection,System.Data.SqlClient.SqlTransaction);;Argument[0];sql",
// OdbcCommand
"System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String);;Argument[0];sql",
"System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String,System.Data.Odbc.OdbcConnection);;Argument[0];sql",
"System.Data.Odbc;OdbcCommand;false;OdbcCommand;(System.String,System.Data.Odbc.OdbcConnection,System.Data.Odbc.OdbcTransaction);;Argument[0];sql",
// OleDbCommand
"System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String);;Argument[0];sql",
"System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String,System.Data.OleDb.OleDbConnection);;Argument[0];sql",
"System.Data.OleDb;OleDbCommand;false;OleDbCommand;(System.String,System.Data.OleDb.OleDbConnection,System.Data.OleDb.OleDbTransaction);;Argument[0];sql",
// EntityCommand
"System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String);;Argument[0];sql",
"System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String,System.Data.EntityClient.EntityConnection);;Argument[0];sql",
"System.Data.EntityClient;EntityCommand;false;EntityCommand;(System.String,System.Data.EntityClient.EntityConnection,System.Data.EntityClient.EntityTransaction);;Argument[0];sql"
]
}
}
/** A construction of an `SqlDataAdapter` object. */
class SqlDataAdapterConstructionSqlExpr extends SqlExpr, ObjectCreation {
SqlDataAdapterConstructionSqlExpr() {
exists(InstanceConstructor ic |
ic = this.getTarget() and
ic.getDeclaringType() instanceof SystemDataSqlClientSqlDataAdapterClass and
ic.getParameter(0).getType() instanceof StringType
)
private class SqlDataAdapterConstructionSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
"System.Data.SqlClient;SqlDataAdapter;false;SqlDataAdapter;(System.String,System.String);;Argument[0];sql",
"System.Data.SqlClient;SqlDataAdapter;false;SqlDataAdapter;(System.String,System.Data.SqlClient.SqlConnection);;Argument[0];sql"
]
}
override Expr getSql() { result = this.getArgument(0) }
}
/** A `MySql.Data.MySqlClient.MySqlHelper` method. */
class MySqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall {
MySqlHelperMethodCallSqlExpr() {
this.getQualifier().getType().(Class).hasQualifiedName("MySql.Data.MySqlClient", "MySqlHelper")
}
override Expr getSql() {
exists(int i |
result = getArgument(i) and
this.getTarget().getParameter(i).hasName("commandText") and
this.getTarget().getParameter(i).getType() instanceof StringType
)
private class MySqlHelperMethodCallSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// ExecuteDataRow/Async
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRow;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRowAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataRowAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteDataset
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDataset;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteDatasetAsync
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteDatasetAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteNonQuery
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQuery;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQuery;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteNonQueryAsync
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteNonQueryAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteReader
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReader;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteReaderAsync
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteReaderAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteScalar
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalar;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// ExecuteScalarAsync
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(System.String,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;ExecuteScalarAsync;(MySql.Data.MySqlClient.MySqlConnection,System.String,System.Threading.CancellationToken,MySql.Data.MySqlClient.MySqlParameter[]);;Argument[1];sql",
// UpdateDataset/Async
"MySql.Data.MySqlClient;MySqlHelper;false;UpdateDataset;(System.String,System.String,System.Data.DataSet,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;UpdateDatasetAsync;(System.String,System.String,System.Data.DataSet,System.String);;Argument[1];sql",
"MySql.Data.MySqlClient;MySqlHelper;false;UpdateDatasetAsync;(System.String,System.String,System.Data.DataSet,System.String,System.Threading.CancellationToken);;Argument[1];sql"
]
}
}
/** A `Microsoft.ApplicationBlocks.Data.SqlHelper` method. */
class MicrosoftSqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall {
MicrosoftSqlHelperMethodCallSqlExpr() {
this.getQualifier()
.getType()
.(Class)
.hasQualifiedName("Microsoft.ApplicationBlocks.Data", "SqlHelper")
}
override Expr getSql() {
exists(int i |
result = getArgument(i) and
this.getTarget().getParameter(i).hasName("commandText") and
this.getTarget().getParameter(i).getType() instanceof StringType
)
private class MicrosoftSqlHelperSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// ExecuteNonQuery
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.String,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteNonQuery;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
// ExecuteDataset
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.String,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteDataset;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
// ExecuteReader
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.String,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
// ExecuteScalar
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.String,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.String,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteScalar;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
// ExecuteXmlReader
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlConnection,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String);;Argument[2];sql",
"Microsoft.ApplicationBlocks.Data;SqlHelper;false;ExecuteXmlReader;(System.Data.SqlClient.SqlTransaction,System.Data.CommandType,System.String,System.Data.SqlClient.SqlParameter[]);;Argument[2];sql"
]
}
}
/** A `Dapper.SqlMapper` method that is taking a SQL string argument. */
class DapperSqlMethodCallSqlExpr extends SqlExpr, MethodCall {
DapperSqlMethodCallSqlExpr() {
this.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod()
private class DapperSqlMapperSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
// Execute*
"Dapper;SqlMapper;false;Execute;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteScalar;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteScalarAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteScalar<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteScalarAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteReader;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.DbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
// Query*
"Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryMultiple;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryMultipleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirst<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefault<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefaultAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingle<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefault<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefaultAsync<>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
// Query* with System.Type parameter
"Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
"Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];sql",
// Query with multiple type parameters
"Dapper;SqlMapper;false;Query<,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<,,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;Query<,,,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<,,,,,,,>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
// Query with System.Type[] parameter
"Dapper;SqlMapper;false;Query<>;(System.Data.IDbConnection,System.String,System.Type[],System.Func<System.Object[],TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql",
"Dapper;SqlMapper;false;QueryAsync<>;(System.Data.IDbConnection,System.String,System.Type[],System.Func<System.Object[],TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[1];sql"
]
}
override Expr getSql() { result = this.getArgumentForName("sql") }
}
/** A `Dapper.CommandDefinition` creation that is taking a SQL string argument and is passed to a `Dapper.SqlMapper` method. */

View File

@@ -7,6 +7,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote
private import semmle.code.csharp.security.dataflow.flowsources.Local
private import semmle.code.csharp.frameworks.system.codedom.Compiler
private import semmle.code.csharp.security.Sanitizers
private import semmle.code.csharp.dataflow.ExternalFlow
/**
* A data flow source for user input treated as code vulnerabilities.
@@ -79,3 +80,8 @@ class RoslynCSharpScriptSink extends Sink {
)
}
}
/** Code injection sinks defined through CSV models. */
private class ExternalCodeInjectionExprSink extends Sink {
ExternalCodeInjectionExprSink() { sinkNode(this, "code") }
}

View File

@@ -7,6 +7,7 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote
private import semmle.code.csharp.security.dataflow.flowsources.Local
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.security.Sanitizers
private import semmle.code.csharp.dataflow.ExternalFlow
/**
* A source specific to SQL injection vulnerabilities.
@@ -51,6 +52,11 @@ class SqlInjectionExprSink extends Sink {
SqlInjectionExprSink() { exists(SqlExpr s | this.getExpr() = s.getSql()) }
}
/** SQL sinks defined through CSV models. */
private class ExternalSqlInjectionExprSink extends Sink {
ExternalSqlInjectionExprSink() { sinkNode(this, "sql") }
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }
private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { }

View File

@@ -62,6 +62,16 @@ module PathGraph {
key = "semmle.label" and
val = n.(XssAspNode).toString()
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(XssNode arg, XssNode par, XssNode ret, XssNode out) {
DataFlow2::PathGraph::subpaths(arg.asDataFlowNode(), par.asDataFlowNode(), ret.asDataFlowNode(),
out.asDataFlowNode())
}
}
private newtype TXssNode =

View File

@@ -10,6 +10,7 @@ private import semmle.code.csharp.frameworks.system.web.UI
private import semmle.code.csharp.security.dataflow.flowsinks.Html
private import semmle.code.csharp.security.dataflow.flowsinks.Remote
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.frameworks.ServiceStack::XSS
/**
* A data flow sink for cross-site scripting (XSS) vulnerabilities.

View File

@@ -6,6 +6,7 @@ import csharp
private import Remote
private import semmle.code.csharp.commons.Loggers
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.dataflow.ExternalFlow
/**
* An external location sink.
@@ -16,6 +17,10 @@ private import semmle.code.csharp.frameworks.system.Web
*/
abstract class ExternalLocationSink extends DataFlow::ExprNode { }
private class ExternalModelSink extends ExternalLocationSink {
ExternalModelSink() { sinkNode(this, "remote") }
}
/**
* An argument to a call to a method on a logger class.
*/

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -32,21 +32,21 @@ edges
| Types.cs:74:9:74:9 | access to local variable d : D | Types.cs:16:30:16:30 | this : D |
| Types.cs:77:22:77:22 | a : C | Types.cs:79:18:79:25 | SSA def(b) : C |
| Types.cs:79:18:79:25 | SSA def(b) : C | Types.cs:80:18:80:18 | access to local variable b |
| Types.cs:90:22:90:22 | e : Types.E<D>.E2 | Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E<D>.E2 | Types.cs:93:13:93:16 | this access [field Field] : Types.E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 | Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E<D>.E2 |
| Types.cs:93:13:93:16 | this access [field Field] : Types.E<D>.E2 | Types.cs:113:34:113:34 | this [field Field] : Types.E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | Types.cs:90:22:90:22 | e : Types.E<D>.E2 |
| Types.cs:113:34:113:34 | this [field Field] : Types.E<D>.E2 | Types.cs:115:22:115:25 | this access [field Field] : Types.E<D>.E2 |
| Types.cs:115:22:115:25 | this access [field Field] : Types.E<D>.E2 | Types.cs:115:22:115:31 | access to field Field |
| Types.cs:90:22:90:22 | e : Types+E<D>.E2 | Types.cs:92:26:92:26 | access to parameter e : Types+E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E<D>.E2 | Types.cs:93:13:93:16 | this access [field Field] : Types+E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types+E<D>.E2 | Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E<D>.E2 |
| Types.cs:93:13:93:16 | this access [field Field] : Types+E<D>.E2 | Types.cs:113:34:113:34 | this [field Field] : Types+E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types+E<D>.E2 | Types.cs:90:22:90:22 | e : Types+E<D>.E2 |
| Types.cs:113:34:113:34 | this [field Field] : Types+E<D>.E2 | Types.cs:115:22:115:25 | this access [field Field] : Types+E<D>.E2 |
| Types.cs:115:22:115:25 | this access [field Field] : Types+E<D>.E2 | Types.cs:115:22:115:31 | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:30:122:30 | access to local variable a : A |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 |
| Types.cs:121:26:121:33 | object creation of type E2 : Types+E<D>.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types+E<D>.E2 |
| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:122:22:122:31 | call to method Through |
| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:130:34:130:34 | x : A |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | Types.cs:123:22:123:32 | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | Types.cs:130:34:130:34 | x : Types.E<D>.E2 |
| Types.cs:123:30:123:31 | access to local variable e2 : Types+E<D>.E2 | Types.cs:123:22:123:32 | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : Types+E<D>.E2 | Types.cs:130:34:130:34 | x : Types+E<D>.E2 |
| Types.cs:130:34:130:34 | x : A | Types.cs:130:40:130:40 | access to parameter x : A |
| Types.cs:130:34:130:34 | x : Types.E<D>.E2 | Types.cs:130:40:130:40 | access to parameter x : Types.E<D>.E2 |
| Types.cs:130:34:130:34 | x : Types+E<D>.E2 | Types.cs:130:40:130:40 | access to parameter x : Types+E<D>.E2 |
| Types.cs:138:21:138:25 | this [field Field] : Object | Types.cs:138:32:138:35 | this access [field Field] : Object |
| Types.cs:138:32:138:35 | this access [field Field] : Object | Types.cs:153:30:153:30 | this [field Field] : Object |
| Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | Types.cs:145:13:145:13 | access to parameter c [field Field] : Object |
@@ -97,24 +97,24 @@ nodes
| Types.cs:77:22:77:22 | a : C | semmle.label | a : C |
| Types.cs:79:18:79:25 | SSA def(b) : C | semmle.label | SSA def(b) : C |
| Types.cs:80:18:80:18 | access to local variable b | semmle.label | access to local variable b |
| Types.cs:90:22:90:22 | e : Types.E<D>.E2 | semmle.label | e : Types.E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E<D>.E2 | semmle.label | [post] this access [field Field] : Types.E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types.E<D>.E2 | semmle.label | access to parameter e : Types.E<D>.E2 |
| Types.cs:93:13:93:16 | this access [field Field] : Types.E<D>.E2 | semmle.label | this access [field Field] : Types.E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | semmle.label | object creation of type E2 : Types.E<D>.E2 |
| Types.cs:113:34:113:34 | this [field Field] : Types.E<D>.E2 | semmle.label | this [field Field] : Types.E<D>.E2 |
| Types.cs:115:22:115:25 | this access [field Field] : Types.E<D>.E2 | semmle.label | this access [field Field] : Types.E<D>.E2 |
| Types.cs:90:22:90:22 | e : Types+E<D>.E2 | semmle.label | e : Types+E<D>.E2 |
| Types.cs:92:13:92:16 | [post] this access [field Field] : Types+E<D>.E2 | semmle.label | [post] this access [field Field] : Types+E<D>.E2 |
| Types.cs:92:26:92:26 | access to parameter e : Types+E<D>.E2 | semmle.label | access to parameter e : Types+E<D>.E2 |
| Types.cs:93:13:93:16 | this access [field Field] : Types+E<D>.E2 | semmle.label | this access [field Field] : Types+E<D>.E2 |
| Types.cs:110:25:110:32 | object creation of type E2 : Types+E<D>.E2 | semmle.label | object creation of type E2 : Types+E<D>.E2 |
| Types.cs:113:34:113:34 | this [field Field] : Types+E<D>.E2 | semmle.label | this [field Field] : Types+E<D>.E2 |
| Types.cs:115:22:115:25 | this access [field Field] : Types+E<D>.E2 | semmle.label | this access [field Field] : Types+E<D>.E2 |
| Types.cs:115:22:115:31 | access to field Field | semmle.label | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | semmle.label | object creation of type A : A |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | semmle.label | object creation of type E2 : Types.E<D>.E2 |
| Types.cs:121:26:121:33 | object creation of type E2 : Types+E<D>.E2 | semmle.label | object creation of type E2 : Types+E<D>.E2 |
| Types.cs:122:22:122:31 | call to method Through | semmle.label | call to method Through |
| Types.cs:122:30:122:30 | access to local variable a : A | semmle.label | access to local variable a : A |
| Types.cs:123:22:123:32 | call to method Through | semmle.label | call to method Through |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | semmle.label | access to local variable e2 : Types.E<D>.E2 |
| Types.cs:123:30:123:31 | access to local variable e2 : Types+E<D>.E2 | semmle.label | access to local variable e2 : Types+E<D>.E2 |
| Types.cs:130:34:130:34 | x : A | semmle.label | x : A |
| Types.cs:130:34:130:34 | x : Types.E<D>.E2 | semmle.label | x : Types.E<D>.E2 |
| Types.cs:130:34:130:34 | x : Types+E<D>.E2 | semmle.label | x : Types+E<D>.E2 |
| Types.cs:130:40:130:40 | access to parameter x : A | semmle.label | access to parameter x : A |
| Types.cs:130:40:130:40 | access to parameter x : Types.E<D>.E2 | semmle.label | access to parameter x : Types.E<D>.E2 |
| Types.cs:130:40:130:40 | access to parameter x : Types+E<D>.E2 | semmle.label | access to parameter x : Types+E<D>.E2 |
| Types.cs:138:21:138:25 | this [field Field] : Object | semmle.label | this [field Field] : Object |
| Types.cs:138:32:138:35 | this access [field Field] : Object | semmle.label | this access [field Field] : Object |
| Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | semmle.label | [post] access to parameter c [field Field] : Object |
@@ -125,7 +125,7 @@ nodes
| Types.cs:153:42:153:51 | access to field Field | semmle.label | access to field Field |
subpaths
| Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:130:34:130:34 | x : A | Types.cs:130:40:130:40 | access to parameter x : A | Types.cs:122:22:122:31 | call to method Through : A |
| Types.cs:123:30:123:31 | access to local variable e2 : Types.E<D>.E2 | Types.cs:130:34:130:34 | x : Types.E<D>.E2 | Types.cs:130:40:130:40 | access to parameter x : Types.E<D>.E2 | Types.cs:123:22:123:32 | call to method Through : Types.E<D>.E2 |
| Types.cs:123:30:123:31 | access to local variable e2 : Types+E<D>.E2 | Types.cs:130:34:130:34 | x : Types+E<D>.E2 | Types.cs:130:40:130:40 | access to parameter x : Types+E<D>.E2 | Types.cs:123:22:123:32 | call to method Through : Types+E<D>.E2 |
#select
| Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:50:18:50:18 | access to local variable c | $@ | Types.cs:50:18:50:18 | access to local variable c | access to local variable c |
| Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:25:12:25:18 | object creation of type C : C | Types.cs:63:33:63:36 | (...) ... | $@ | Types.cs:63:33:63:36 | (...) ... | (...) ... |
@@ -141,7 +141,7 @@ subpaths
| Types.cs:39:12:39:18 | object creation of type D : D | Types.cs:39:12:39:18 | object creation of type D : D | Types.cs:69:52:69:52 | access to parameter x | $@ | Types.cs:69:52:69:52 | access to parameter x | access to parameter x |
| Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:40:12:40:18 | object creation of type D : D | Types.cs:16:42:16:45 | this access | $@ | Types.cs:16:42:16:45 | this access | this access |
| Types.cs:43:20:43:23 | null : null | Types.cs:43:20:43:23 | null : null | Types.cs:44:14:44:14 | access to local variable o | $@ | Types.cs:44:14:44:14 | access to local variable o | access to local variable o |
| Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | Types.cs:110:25:110:32 | object creation of type E2 : Types.E<D>.E2 | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field |
| Types.cs:110:25:110:32 | object creation of type E2 : Types+E<D>.E2 | Types.cs:110:25:110:32 | object creation of type E2 : Types+E<D>.E2 | Types.cs:115:22:115:31 | access to field Field | $@ | Types.cs:115:22:115:31 | access to field Field | access to field Field |
| Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:22:122:31 | call to method Through | $@ | Types.cs:122:22:122:31 | call to method Through | call to method Through |
| Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | Types.cs:121:26:121:33 | object creation of type E2 : Types.E<D>.E2 | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through |
| Types.cs:121:26:121:33 | object creation of type E2 : Types+E<D>.E2 | Types.cs:121:26:121:33 | object creation of type E2 : Types+E<D>.E2 | Types.cs:123:22:123:32 | call to method Through | $@ | Types.cs:123:22:123:32 | call to method Through | call to method Through |
| Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:153:42:153:51 | access to field Field | $@ | Types.cs:153:42:153:51 | access to field Field | access to field Field |

View File

@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.ObjectPool;
using System.IO;
namespace ServiceStackTest
{
public class ResponseDto { }
public class ReqDto1 : IReturn<ResponseDto> { }
public class ReqDto2 : IReturnVoid { }
public class C
{
public async Task M()
{
var client = new JsonServiceClient("");
client.DeserializeFromStream<object>(new MemoryStream()); // not a sink
client.Get(new ReqDto1());
client.Get(new ReqDto2());
client.Get<ResponseDto>("relativeOrAbsoluteUrl"); // not a sink
client.Get<ResponseDto>(new object());
client.Get("relativeOrAbsoluteUrl"); // not a sink
client.Get(new object());
await client.GetAsync<ResponseDto>("relativeOrAbsoluteUrl"); // not a sink
await client.GetAsync<ResponseDto>(new object());
await client.GetAsync(new ReqDto1());
await client.GetAsync(new ReqDto2());
client.CustomMethod("GET", new ReqDto2());
client.CustomMethod<ResponseDto>("GET", "relativeOrAbsoluteUrl", new ReqDto1());
client.CustomMethod<ResponseDto>("GET", new ReqDto1());
client.CustomMethod<ResponseDto>("GET", new object());
client.CustomMethod("GET", "relativeOrAbsoluteUrl", new object());
client.CustomMethod("GET", (IReturnVoid)null);
await client.CustomMethodAsync("GET", new ReqDto2());
await client.CustomMethodAsync<ResponseDto>("GET", "relativeOrAbsoluteUrl", new ReqDto1());
await client.CustomMethodAsync<ResponseDto>("GET", new ReqDto1());
await client.CustomMethodAsync<ResponseDto>("GET", new object());
client.DownloadBytes("GET", "requestUri", new object());
await client.DownloadBytesAsync("GET", "relativeOrAbsoluteUrl", new object());
client.Head(new object());
client.Patch(new object());
client.Post(new object());
client.Put(new object());
client.Send<ResponseDto>(new object());
client.Publish(new ReqDto1());
client.SendOneWay(new object());
}
}
}

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Components.Forms;
using ServiceStack.OrmLite;
namespace ServiceStackTest
{
public class Table
{
public int Column { get; set; }
}
public class Sql
{
public static async Task M()
{
ServiceStack.OrmLite.SqlExpression<int> expr = null;
expr = expr.Select<Table>(t => t.Column); // ok
expr = expr
.UnsafeAnd("SQL")
.UnsafeFrom("SQL")
.UnsafeGroupBy("SQL")
.UnsafeHaving("SQL")
.UnsafeOr("SQL")
.UnsafeOrderBy("SQL")
.UnsafeSelect("SQL")
.UnsafeWhere("SQL");
var untyped = expr.GetUntypedSqlExpression();
untyped
.UnsafeAnd("SQL")
.UnsafeFrom("SQL")
.UnsafeOr("SQL")
.UnsafeSelect("SQL")
.UnsafeWhere("SQL")
.Where("SQL"); // safe
System.Data.IDbConnection conn = null;
var row = conn.SingleById<Table>(1); // ok
var rows = conn.Select<Table>(typeof(Table), "SQL", null);
rows = await conn.SelectAsync<Table>(typeof(Table), "SQL", null);
var count = conn.RowCount("SQL");
count = await conn.RowCountAsync("SQL");
conn.ExecuteSql("SQL", null);
await conn.ExecuteSqlAsync("SQL", null);
}
public static async Task Redis()
{
ServiceStack.Redis.IRedisClient client = null;
client.SetValue("key", "value"); // ok
var s = client.LoadLuaScript("script");
client.ExecLua("script", new[] { "" }, new[] { "" });
client.ExecLuaSha("SHA", new[] { "" }, new[] { "" }); // ok
client.Custom("command", "arg"); // false negative, params sinks doesn't work
ServiceStack.Redis.IRedisClientAsync asyncClient = null;
s = await asyncClient.LoadLuaScriptAsync("script");
asyncClient.ExecLuaAsync("script", new[] { "" }, new[] { "" });
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
namespace ServiceStackTest
{
public class XssServices : Service
{
public object Get(Request1 request)
{
return "<script>";
}
public object Post(Request1 request) => "<script>";
private void SomeMethod()
{
var s = new HttpResult("", ""); // not a sink
}
public object Delete(Request1 req) => req; // not a sink
public object Put(Request1 req) => new HttpResult("", "");
}
}

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.Linq;
using ServiceStack;
using System.Threading.Tasks;
using System;
namespace ServiceStackTest
{
public class MyServices1 : Service
{
public object Get(string request) => throw null; // this might not be a remote source
public object Get(Request1 request) => throw null;
public object Get(Request2 request) => throw null;
public object Get(Request3 request) => throw null; // might be a remote source if routes are looked up with Routes.AddFromAssembly
public object Get(Request4 request)
{
Console.WriteLine(request.Nested.Prop1);
Console.WriteLine(request.Nested.Prop2[0].Prop1);
throw null;
}
public object Post(Request1 request) => throw null;
public Task<object> PostAsync(Request1 request) => throw null;
public object Method1(Request1 request) // Not a request method
{
Console.WriteLine(request.Field1);
throw null;
}
public object GetJson(Request1 request) => throw null;
}
public class MyServices2 : IService
{
public object Get(Request1 request) => throw null;
}
public class Request1 : IReturn<Response1>
{
public string Field1;
}
public class Response1
{
public string Result { get; set; }
}
[Route("/req2/{Prop1}")]
public class Request2
{
public string Prop1 { get; set; }
}
public class Request3
{
public string Prop1 { get; set; }
}
[Route("/req4")]
public class Request4 : IReturnVoid
{
public string Prop1 { get; set; }
public Nested Nested { get; set; }
}
public class Nested
{
public string Prop1 { get; set; }
public List<Element> Prop2 { get; set; }
}
public class Element
{
public string Prop1 { get; set; }
}
}

View File

@@ -0,0 +1,4 @@
| SinksInjection.cs:64:42:64:49 | "script" | SinksInjection.cs:64:42:64:49 | "script" |
| SinksInjection.cs:65:28:65:35 | "script" | SinksInjection.cs:65:28:65:35 | "script" |
| SinksInjection.cs:70:54:70:61 | "script" | SinksInjection.cs:70:54:70:61 | "script" |
| SinksInjection.cs:71:38:71:45 | "script" | SinksInjection.cs:71:38:71:45 | "script" |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.CodeInjectionQuery
from Sink sink
where
sink.getLocation().getFile().fromSource() and
not sink.getLocation().getFile().getAbsolutePath().matches("%/resources/stubs/%")
select sink, sink.getExpr()

View File

@@ -0,0 +1,26 @@
| SinksExternal.cs:24:24:24:36 | object creation of type ReqDto1 | SinksExternal.cs:24:24:24:36 | object creation of type ReqDto1 |
| SinksExternal.cs:25:24:25:36 | object creation of type ReqDto2 | SinksExternal.cs:25:24:25:36 | object creation of type ReqDto2 |
| SinksExternal.cs:27:37:27:48 | object creation of type Object | SinksExternal.cs:27:37:27:48 | object creation of type Object |
| SinksExternal.cs:29:24:29:35 | object creation of type Object | SinksExternal.cs:29:24:29:35 | object creation of type Object |
| SinksExternal.cs:32:48:32:59 | object creation of type Object | SinksExternal.cs:32:48:32:59 | object creation of type Object |
| SinksExternal.cs:33:35:33:47 | object creation of type ReqDto1 | SinksExternal.cs:33:35:33:47 | object creation of type ReqDto1 |
| SinksExternal.cs:34:35:34:47 | object creation of type ReqDto2 | SinksExternal.cs:34:35:34:47 | object creation of type ReqDto2 |
| SinksExternal.cs:37:40:37:52 | object creation of type ReqDto2 | SinksExternal.cs:37:40:37:52 | object creation of type ReqDto2 |
| SinksExternal.cs:38:78:38:90 | object creation of type ReqDto1 | SinksExternal.cs:38:78:38:90 | object creation of type ReqDto1 |
| SinksExternal.cs:39:53:39:65 | object creation of type ReqDto1 | SinksExternal.cs:39:53:39:65 | object creation of type ReqDto1 |
| SinksExternal.cs:40:53:40:64 | object creation of type Object | SinksExternal.cs:40:53:40:64 | object creation of type Object |
| SinksExternal.cs:41:65:41:76 | object creation of type Object | SinksExternal.cs:41:65:41:76 | object creation of type Object |
| SinksExternal.cs:42:40:42:56 | (...) ... | SinksExternal.cs:42:40:42:56 | (...) ... |
| SinksExternal.cs:43:51:43:63 | object creation of type ReqDto2 | SinksExternal.cs:43:51:43:63 | object creation of type ReqDto2 |
| SinksExternal.cs:44:89:44:101 | object creation of type ReqDto1 | SinksExternal.cs:44:89:44:101 | object creation of type ReqDto1 |
| SinksExternal.cs:45:64:45:76 | object creation of type ReqDto1 | SinksExternal.cs:45:64:45:76 | object creation of type ReqDto1 |
| SinksExternal.cs:46:64:46:75 | object creation of type Object | SinksExternal.cs:46:64:46:75 | object creation of type Object |
| SinksExternal.cs:48:55:48:66 | object creation of type Object | SinksExternal.cs:48:55:48:66 | object creation of type Object |
| SinksExternal.cs:49:77:49:88 | object creation of type Object | SinksExternal.cs:49:77:49:88 | object creation of type Object |
| SinksExternal.cs:51:25:51:36 | object creation of type Object | SinksExternal.cs:51:25:51:36 | object creation of type Object |
| SinksExternal.cs:52:26:52:37 | object creation of type Object | SinksExternal.cs:52:26:52:37 | object creation of type Object |
| SinksExternal.cs:53:25:53:36 | object creation of type Object | SinksExternal.cs:53:25:53:36 | object creation of type Object |
| SinksExternal.cs:54:24:54:35 | object creation of type Object | SinksExternal.cs:54:24:54:35 | object creation of type Object |
| SinksExternal.cs:56:38:56:49 | object creation of type Object | SinksExternal.cs:56:38:56:49 | object creation of type Object |
| SinksExternal.cs:57:28:57:40 | object creation of type ReqDto1 | SinksExternal.cs:57:28:57:40 | object creation of type ReqDto1 |
| SinksExternal.cs:58:31:58:42 | object creation of type Object | SinksExternal.cs:58:31:58:42 | object creation of type Object |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
from ExternalLocationSink sink
where
sink.getLocation().getFile().fromSource() and
not sink.getLocation().getFile().getAbsolutePath().matches("%/resources/stubs/%")
select sink, sink.getExpr()

View File

@@ -0,0 +1,3 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/ServiceStack/5.11.0/ServiceStack.csproj
semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/ServiceStack.OrmLite.SqlServer/5.11.0/ServiceStack.OrmLite.SqlServer.csproj

View File

@@ -0,0 +1,13 @@
| SinksXss.cs:11:36:11:42 | request | ServiceStack request parameter |
| SinksXss.cs:16:37:16:43 | request | ServiceStack request parameter |
| SinksXss.cs:23:39:23:41 | req | ServiceStack request parameter |
| SinksXss.cs:25:36:25:38 | req | ServiceStack request parameter |
| Sources.cs:11:34:11:40 | request | ServiceStack request parameter |
| Sources.cs:12:36:12:42 | request | ServiceStack request parameter |
| Sources.cs:13:36:13:42 | request | ServiceStack request parameter |
| Sources.cs:14:36:14:42 | request | ServiceStack request parameter |
| Sources.cs:15:36:15:42 | request | ServiceStack request parameter |
| Sources.cs:22:37:22:43 | request | ServiceStack request parameter |
| Sources.cs:23:48:23:54 | request | ServiceStack request parameter |
| Sources.cs:30:40:30:46 | request | ServiceStack request parameter |
| Sources.cs:35:36:35:42 | request | ServiceStack request parameter |

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