mirror of
https://github.com/github/codeql.git
synced 2026-05-18 05:07:06 +02:00
Compare commits
467 Commits
codeql-cli
...
esbena/imp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6505ad1724 | ||
|
|
e53ba21387 | ||
|
|
ec1dc985ef | ||
|
|
008024b3bb | ||
|
|
5c4043dacb | ||
|
|
874da9d81c | ||
|
|
8e0781d78a | ||
|
|
937d6b1f3e | ||
|
|
7d4125010c | ||
|
|
a8dd55fe0f | ||
|
|
57c88d5fd6 | ||
|
|
026dfaec97 | ||
|
|
c523c4f96e | ||
|
|
ef5148bb80 | ||
|
|
13264e1119 | ||
|
|
1e299e9bb8 | ||
|
|
f322aaf344 | ||
|
|
3c9e70341b | ||
|
|
cfe20810bf | ||
|
|
065002ad18 | ||
|
|
7778aa59ea | ||
|
|
8ef6f59737 | ||
|
|
b4339e8ac5 | ||
|
|
caf1d45bc6 | ||
|
|
7c5a4909c6 | ||
|
|
bdae353d4d | ||
|
|
ae472f32de | ||
|
|
d8edc83ea2 | ||
|
|
72ea5973af | ||
|
|
ae288332cc | ||
|
|
32ef535ad7 | ||
|
|
28d2fd7a22 | ||
|
|
9d7afab185 | ||
|
|
e1c7de98e8 | ||
|
|
669c1faf29 | ||
|
|
6055aaf048 | ||
|
|
8b52bb0c31 | ||
|
|
5c9fea2283 | ||
|
|
33e11b3014 | ||
|
|
763f869e3f | ||
|
|
a0acb19b68 | ||
|
|
01e1c13c29 | ||
|
|
4a025053cc | ||
|
|
07c22a857f | ||
|
|
aa78ce3c75 | ||
|
|
cceeaef6bf | ||
|
|
0a484aadf1 | ||
|
|
ba5cf5b1b2 | ||
|
|
0a861ff616 | ||
|
|
14384b7696 | ||
|
|
87234938ef | ||
|
|
04422eeaee | ||
|
|
d5ac7190cc | ||
|
|
e54b29a846 | ||
|
|
602495df4c | ||
|
|
70c74bfcc0 | ||
|
|
43907b6a30 | ||
|
|
b48a07e7b8 | ||
|
|
3155771abe | ||
|
|
bfbc1d48b7 | ||
|
|
3d63cec1e8 | ||
|
|
361b7037c6 | ||
|
|
ede6bd8ffe | ||
|
|
2187bf5dde | ||
|
|
0b486ade9b | ||
|
|
aadf7aefb0 | ||
|
|
c9d109ddd3 | ||
|
|
3f857e113c | ||
|
|
86caf747f3 | ||
|
|
ebb52adba6 | ||
|
|
8b1605a617 | ||
|
|
efc534abe7 | ||
|
|
1ef42a11ad | ||
|
|
a3c4a2c3e0 | ||
|
|
c1592cb1dc | ||
|
|
910bb51094 | ||
|
|
b646195d14 | ||
|
|
d7b06aa2ba | ||
|
|
7214990762 | ||
|
|
927aceb420 | ||
|
|
3b57d4830b | ||
|
|
c52d19d821 | ||
|
|
6419af39f3 | ||
|
|
1dab01a31c | ||
|
|
ab4b7d8509 | ||
|
|
536d226a6b | ||
|
|
dc7d07ff46 | ||
|
|
37fce6ace9 | ||
|
|
0df8a9883a | ||
|
|
77f7fe8dbc | ||
|
|
4b2b6fae88 | ||
|
|
7d962ac62b | ||
|
|
cb7be4f8ba | ||
|
|
eabb5c7137 | ||
|
|
3414028b1b | ||
|
|
db0498e38c | ||
|
|
ecce7f1f10 | ||
|
|
6b90b2b05f | ||
|
|
a4f97dd67a | ||
|
|
bc0a32c26e | ||
|
|
3597efb728 | ||
|
|
a894ba64c4 | ||
|
|
a86d0fc8a7 | ||
|
|
946e1f498a | ||
|
|
6f9e9e889b | ||
|
|
ef4f09cf52 | ||
|
|
67c4850c61 | ||
|
|
e0d9317889 | ||
|
|
703ced3fe9 | ||
|
|
db0ac7b3b3 | ||
|
|
729cf79be7 | ||
|
|
9abd2259d3 | ||
|
|
4f3751dfea | ||
|
|
9cc10e4511 | ||
|
|
42ec6350eb | ||
|
|
6be4afcf36 | ||
|
|
ae2bc1b410 | ||
|
|
21d69ae819 | ||
|
|
e2ddfcd437 | ||
|
|
bd095abea4 | ||
|
|
f417c12c5e | ||
|
|
6386daf44c | ||
|
|
78fd0385fc | ||
|
|
5f9d03f7c6 | ||
|
|
9b7597bcdb | ||
|
|
f598b26b03 | ||
|
|
547cecf143 | ||
|
|
a175f49759 | ||
|
|
b5d229d4d8 | ||
|
|
01091ae1b9 | ||
|
|
f70f769bb6 | ||
|
|
1d120486b4 | ||
|
|
9af31bab2a | ||
|
|
7f5dcfaf0f | ||
|
|
e0f74a51ac | ||
|
|
d4f9c75315 | ||
|
|
cea909f03e | ||
|
|
9dd20f113d | ||
|
|
8b32eaf05c | ||
|
|
ce3488b1b5 | ||
|
|
ed2f3409bc | ||
|
|
de1fdd3bc9 | ||
|
|
9212886767 | ||
|
|
ed9e798a81 | ||
|
|
27968b60a5 | ||
|
|
6cfd790cda | ||
|
|
e36c59b285 | ||
|
|
e016feeb5c | ||
|
|
ce26124c01 | ||
|
|
e3046fb05b | ||
|
|
90fdd7eaf9 | ||
|
|
95fae8155e | ||
|
|
5c5e978d30 | ||
|
|
89ffefd45e | ||
|
|
bb93179c45 | ||
|
|
bd1ddc177e | ||
|
|
ae2cc378e5 | ||
|
|
a661a0cc7e | ||
|
|
76375f8d73 | ||
|
|
6a6a63e1aa | ||
|
|
b1faba9880 | ||
|
|
1708719fdf | ||
|
|
b88fe1b2b4 | ||
|
|
eed42a4e14 | ||
|
|
cd1800ec7e | ||
|
|
99e6d2a925 | ||
|
|
ca764576be | ||
|
|
e544a9b94b | ||
|
|
18c5474431 | ||
|
|
c5dd8aa703 | ||
|
|
9175354bbd | ||
|
|
52f0b0d8d8 | ||
|
|
21527f66e1 | ||
|
|
a833e77c30 | ||
|
|
38be04461e | ||
|
|
b6cc438390 | ||
|
|
d8916568b6 | ||
|
|
9b17493b3b | ||
|
|
c188aa87c7 | ||
|
|
7ca01443e8 | ||
|
|
420dea0792 | ||
|
|
08e64ea1b4 | ||
|
|
2492744a9b | ||
|
|
a8b4b6a374 | ||
|
|
a5dc4f430c | ||
|
|
ef31aec29e | ||
|
|
61151d8980 | ||
|
|
425d66e454 | ||
|
|
2106d48785 | ||
|
|
0d8a9458c6 | ||
|
|
cd46f31cba | ||
|
|
72dd1a6ec9 | ||
|
|
7a6646dcaf | ||
|
|
a0ae8b3a97 | ||
|
|
5f42866de3 | ||
|
|
b700972e6f | ||
|
|
820dfac48c | ||
|
|
ea70aaff57 | ||
|
|
47e425a184 | ||
|
|
adb40f9360 | ||
|
|
ab28b0a690 | ||
|
|
e557d8839b | ||
|
|
c7a8008897 | ||
|
|
63e637503d | ||
|
|
49d9d8e7d6 | ||
|
|
2f436c800b | ||
|
|
cc42f2f824 | ||
|
|
815dff338d | ||
|
|
6a4a4cbbe4 | ||
|
|
48da8dde6f | ||
|
|
ad4d8304ed | ||
|
|
7e5dd7a065 | ||
|
|
0f33c3188c | ||
|
|
71bcae068e | ||
|
|
ff928bbb45 | ||
|
|
7d171f86ea | ||
|
|
31c91a6faa | ||
|
|
6ea87cd718 | ||
|
|
c734646099 | ||
|
|
6d5504412a | ||
|
|
013b4c8768 | ||
|
|
ce2bf8477c | ||
|
|
a82fea59e9 | ||
|
|
7ab3a418be | ||
|
|
b9809b4219 | ||
|
|
02c73d3c1c | ||
|
|
9ea139566d | ||
|
|
6eb2935469 | ||
|
|
62fd3fd90f | ||
|
|
7e76e9a23b | ||
|
|
468a4df215 | ||
|
|
9c62b349ec | ||
|
|
8c12a7289f | ||
|
|
2dcd7e16b1 | ||
|
|
a204c742d8 | ||
|
|
a0d5d414b4 | ||
|
|
6815e731d2 | ||
|
|
45bbd24355 | ||
|
|
5d4473bb2a | ||
|
|
da02bcc4c6 | ||
|
|
5830db786e | ||
|
|
4091ba758d | ||
|
|
919555d168 | ||
|
|
55513e0dbb | ||
|
|
5924e88a86 | ||
|
|
a63378308d | ||
|
|
0925cf5c22 | ||
|
|
7d36bc1c73 | ||
|
|
73c189957d | ||
|
|
e3ef258b0e | ||
|
|
4383aef1d2 | ||
|
|
795c0110e5 | ||
|
|
fef87db739 | ||
|
|
52a10c826a | ||
|
|
57b9e6ee40 | ||
|
|
f7d9238cda | ||
|
|
32e4c496f6 | ||
|
|
30f24697b4 | ||
|
|
507fdef028 | ||
|
|
b456334472 | ||
|
|
5a1663efd3 | ||
|
|
434259b296 | ||
|
|
81ac648065 | ||
|
|
4e0e4f9b5b | ||
|
|
fd8f1dc88f | ||
|
|
ae6d16a40f | ||
|
|
25c8b8141c | ||
|
|
4cf3467ad7 | ||
|
|
2bcf7e17c8 | ||
|
|
202d2e037d | ||
|
|
e3ea7751d1 | ||
|
|
3213549a73 | ||
|
|
1f2248c1c8 | ||
|
|
3bd581a052 | ||
|
|
ae1f5bbe25 | ||
|
|
c7cc8d2592 | ||
|
|
da90440ea3 | ||
|
|
aa77ea6bef | ||
|
|
9f64622f31 | ||
|
|
d326b3a91c | ||
|
|
bba3564187 | ||
|
|
91b34d5e8f | ||
|
|
765e1e1115 | ||
|
|
cf22ade9f3 | ||
|
|
117a1ad2f4 | ||
|
|
b3ce2d4a2b | ||
|
|
47051ec8c9 | ||
|
|
d5c8188625 | ||
|
|
d199173923 | ||
|
|
385e442f7f | ||
|
|
fafdb016fa | ||
|
|
f17afa8a11 | ||
|
|
dc2ba5b410 | ||
|
|
0b6e35a2a9 | ||
|
|
361b2aa6bb | ||
|
|
033df767ef | ||
|
|
af428a1ac2 | ||
|
|
b0a97f9b01 | ||
|
|
a60caced98 | ||
|
|
79fb9e8fd2 | ||
|
|
5964be4463 | ||
|
|
893f4ab8fb | ||
|
|
ce4959287a | ||
|
|
80fad348bb | ||
|
|
67cc1b503b | ||
|
|
1f4924f978 | ||
|
|
ab268514a1 | ||
|
|
4f95abc4f6 | ||
|
|
bcdef98392 | ||
|
|
a4023b8a1d | ||
|
|
ed907f6f63 | ||
|
|
a726340bb3 | ||
|
|
a7b39ebeca | ||
|
|
efa895e912 | ||
|
|
f38d1f9a4e | ||
|
|
134cf4e0e1 | ||
|
|
67572bb770 | ||
|
|
aadfa8eacd | ||
|
|
e9d371c650 | ||
|
|
8b131adeb1 | ||
|
|
877a9d8bcc | ||
|
|
4913a7a911 | ||
|
|
9cab92b16f | ||
|
|
5b405bb4cf | ||
|
|
ba7238d6e2 | ||
|
|
75532432af | ||
|
|
c8ede58704 | ||
|
|
4d6d1c8376 | ||
|
|
ee027f845c | ||
|
|
268230ef19 | ||
|
|
e2d6cd20c7 | ||
|
|
9b8636aa23 | ||
|
|
d9c7ba471d | ||
|
|
f8e729025f | ||
|
|
3b62b45ea8 | ||
|
|
2da001ebd7 | ||
|
|
91fa17a05e | ||
|
|
7e32614c25 | ||
|
|
33964383d7 | ||
|
|
ced1d21405 | ||
|
|
039a7ba828 | ||
|
|
a5f2c949d3 | ||
|
|
ec55c84abf | ||
|
|
d7e3e9e5db | ||
|
|
665fa2af59 | ||
|
|
c8bb0e2117 | ||
|
|
987a830029 | ||
|
|
2e858db848 | ||
|
|
74af9067a1 | ||
|
|
a955bd3695 | ||
|
|
7d4a191a32 | ||
|
|
db4b6d620a | ||
|
|
82c6c22d50 | ||
|
|
2a97dd9f6f | ||
|
|
b688aabd19 | ||
|
|
1717d17fb3 | ||
|
|
1fa2fd73f2 | ||
|
|
fc25d14af7 | ||
|
|
572f247fd9 | ||
|
|
53a25c8c42 | ||
|
|
1287925676 | ||
|
|
171fe98084 | ||
|
|
e519304268 | ||
|
|
87cbf7b216 | ||
|
|
631527fe49 | ||
|
|
bc601261ed | ||
|
|
f80f8b6630 | ||
|
|
18dc39484d | ||
|
|
1e96b1e559 | ||
|
|
777d344dde | ||
|
|
e2858b7b64 | ||
|
|
8da96ed403 | ||
|
|
1ae97d9d54 | ||
|
|
9fad4b883b | ||
|
|
76ba78294f | ||
|
|
ce9c3b3eb5 | ||
|
|
19a5db9f89 | ||
|
|
4c6192670e | ||
|
|
a7b73f44b2 | ||
|
|
73baa49c5d | ||
|
|
82c35e6f65 | ||
|
|
6a12864dab | ||
|
|
fa09078976 | ||
|
|
8e8da66325 | ||
|
|
528f6f73c5 | ||
|
|
4ea892f2d2 | ||
|
|
f8281b43b1 | ||
|
|
b6a4f43737 | ||
|
|
cdceb66b07 | ||
|
|
d6abb2e6bd | ||
|
|
cb4b2e983b | ||
|
|
813fbf27de | ||
|
|
204e01fc24 | ||
|
|
a5b11e88b4 | ||
|
|
67697e1066 | ||
|
|
0f3448dc24 | ||
|
|
b928ca518f | ||
|
|
d5f0446940 | ||
|
|
03da62713c | ||
|
|
bb289e29b9 | ||
|
|
818975dc56 | ||
|
|
5d1c41c269 | ||
|
|
2868eb61ea | ||
|
|
f273ccf73b | ||
|
|
ce21d7e5a8 | ||
|
|
aef592fec8 | ||
|
|
55ffdb4aa1 | ||
|
|
1f8e7c39f4 | ||
|
|
fb077bec66 | ||
|
|
dea5596289 | ||
|
|
31e9876de7 | ||
|
|
196c68b0bd | ||
|
|
a114050a6e | ||
|
|
fc1ab06c1c | ||
|
|
4844e4f454 | ||
|
|
bedb1d4584 | ||
|
|
961f867bed | ||
|
|
1e3ab52e1f | ||
|
|
08fa397877 | ||
|
|
efe306733e | ||
|
|
2292dc5a45 | ||
|
|
dfe99b0b51 | ||
|
|
0a589bed4e | ||
|
|
6ae5ef9f3b | ||
|
|
1af5c680fa | ||
|
|
687602b6f1 | ||
|
|
4210973ade | ||
|
|
4b9c9b0c8d | ||
|
|
a812d4dd34 | ||
|
|
571fc3e73b | ||
|
|
1062aae21c | ||
|
|
ead978187d | ||
|
|
8ffc05c84b | ||
|
|
c0eca0d09a | ||
|
|
6c67e51ec3 | ||
|
|
9c3d45a16a | ||
|
|
894252dfa7 | ||
|
|
0f1e070d82 | ||
|
|
649df1dd31 | ||
|
|
a8790412dd | ||
|
|
b1fa7f86a8 | ||
|
|
413d182bcf | ||
|
|
c1d3738fb8 | ||
|
|
547047ef19 | ||
|
|
dc38aa8a96 | ||
|
|
ea01bcf5ec | ||
|
|
46acce0ad4 | ||
|
|
a02e812de8 | ||
|
|
682cab3737 | ||
|
|
48408ca45d | ||
|
|
8d60336396 | ||
|
|
20992af037 | ||
|
|
35b143a1a5 | ||
|
|
86a9bc6aca | ||
|
|
d4b882519a | ||
|
|
1c2c9159a9 | ||
|
|
b956616a56 | ||
|
|
869d827768 | ||
|
|
de35bd987a | ||
|
|
ad3a9b19e4 | ||
|
|
e03ce8f9f2 | ||
|
|
e3e02c98ea | ||
|
|
1e6893e230 | ||
|
|
8f2013c32e | ||
|
|
bf8c7a2ea7 | ||
|
|
e11c74c580 | ||
|
|
4195eef9ba |
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"provide": [
|
||||
"*/ql/src/qlpack.yml",
|
||||
"*/ql/lib/qlpack.yml",
|
||||
"*/ql/test/qlpack.yml",
|
||||
"*/ql/examples/qlpack.yml",
|
||||
"*/ql/consistency-queries/qlpack.yml",
|
||||
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
||||
"go/ql/config/legacy-support/qlpack.yml",
|
||||
"go/build/codeql-extractor-go/codeql-extractor.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
|
||||
"csharp/ql/campaigns/Solorigate/lib/qlpack.yml",
|
||||
"csharp/ql/campaigns/Solorigate/src/qlpack.yml",
|
||||
"csharp/ql/campaigns/Solorigate/test/qlpack.yml",
|
||||
"misc/legacy-support/*/qlpack.yml",
|
||||
"misc/suite-helpers/qlpack.yml",
|
||||
"ruby/extractor-pack/codeql-extractor.yml",
|
||||
"swift/extractor-pack/codeql-extractor.yml",
|
||||
"ql/extractor-pack/codeql-extractor.yml"
|
||||
],
|
||||
"versionPolicies": {
|
||||
"default": {
|
||||
"requireChangeNotes": true,
|
||||
"committedPrereleaseSuffix": "dev",
|
||||
"committedVersion": "nextPatchRelease"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
.github/labeler.yml
vendored
15
.github/labeler.yml
vendored
@@ -6,14 +6,23 @@
|
||||
- csharp/**/*
|
||||
- change-notes/**/*csharp*
|
||||
|
||||
Go:
|
||||
- go/**/*
|
||||
- change-notes/**/*go.*
|
||||
|
||||
Java:
|
||||
- java/**/*
|
||||
- any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/kotlin-explorer/**/*', '!java/ql/test/kotlin/**/*' ]
|
||||
- change-notes/**/*java.*
|
||||
|
||||
JS:
|
||||
- any: [ 'javascript/**/*', '!javascript/ql/experimental/adaptivethreatmodeling/**/*' ]
|
||||
- change-notes/**/*javascript*
|
||||
|
||||
Kotlin:
|
||||
- java/kotlin-extractor/**/*
|
||||
- java/kotlin-explorer/**/*
|
||||
- java/ql/test/kotlin/**/*
|
||||
|
||||
Python:
|
||||
- python/**/*
|
||||
- change-notes/**/*python*
|
||||
@@ -21,7 +30,7 @@ Python:
|
||||
Ruby:
|
||||
- ruby/**/*
|
||||
- change-notes/**/*ruby*
|
||||
|
||||
|
||||
Swift:
|
||||
- swift/**/*
|
||||
- change-notes/**/*swift*
|
||||
@@ -31,5 +40,5 @@ documentation:
|
||||
- "**/*.md"
|
||||
- docs/**/*
|
||||
|
||||
"QL-for-QL":
|
||||
"QL-for-QL":
|
||||
- ql/**/*
|
||||
|
||||
1
.github/workflows/go-tests.yml
vendored
1
.github/workflows/go-tests.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
paths:
|
||||
- "go/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- codeql-workspace.yml
|
||||
jobs:
|
||||
|
||||
test-linux:
|
||||
|
||||
3
.github/workflows/js-ml-tests.yml
vendored
3
.github/workflows/js-ml-tests.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
||||
- .github/workflows/js-ml-tests.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
@@ -12,6 +13,8 @@ on:
|
||||
paths:
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
||||
- .github/workflows/js-ml-tests.yml
|
||||
- codeql-workspace.yml
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
|
||||
3
.github/workflows/labeler.yml
vendored
3
.github/workflows/labeler.yml
vendored
@@ -4,6 +4,9 @@ on:
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
|
||||
2
.github/workflows/mad_modelDiff.yml
vendored
2
.github/workflows/mad_modelDiff.yml
vendored
@@ -61,7 +61,7 @@ jobs:
|
||||
DATABASE=$2
|
||||
cd codeql-$QL_VARIANT
|
||||
SHORTNAME=`basename $DATABASE`
|
||||
python java/ql/src/utils/model-generator/GenerateFlowModel.py $DATABASE $MODELS/${SHORTNAME}.qll
|
||||
python java/ql/src/utils/model-generator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE $MODELS/${SHORTNAME}.qll
|
||||
mv $MODELS/${SHORTNAME}.qll $MODELS/${SHORTNAME}Generated_${QL_VARIANT}.qll
|
||||
cd ..
|
||||
}
|
||||
|
||||
2
.github/workflows/mad_regenerate-models.yml
vendored
2
.github/workflows/mad_regenerate-models.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
ref: ["placeholder"]
|
||||
include:
|
||||
- slug: "apache/commons-io"
|
||||
ref: "8985de8fe74f6622a419b37a6eed0dbc484dc128"
|
||||
ref: "13258ce2d07aa0e764bbaa8020af4dcd3a02a620"
|
||||
exclude:
|
||||
- slug: "placeholder"
|
||||
ref: "placeholder"
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -5,10 +5,12 @@ on:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "ql/**"
|
||||
- codeql-workspace.yml
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "ql/**"
|
||||
- codeql-workspace.yml
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
2
.github/workflows/query-list.yml
vendored
2
.github/workflows/query-list.yml
vendored
@@ -5,6 +5,8 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- 'rc/**'
|
||||
tags:
|
||||
- 'codeql-cli/*'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/query-list.yml'
|
||||
|
||||
2
.github/workflows/ruby-build.yml
vendored
2
.github/workflows/ruby-build.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-build.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
@@ -12,6 +13,7 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-build.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
|
||||
2
.github/workflows/ruby-qltest.yml
vendored
2
.github/workflows/ruby-qltest.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-qltest.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
@@ -12,6 +13,7 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-qltest.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
|
||||
2
.github/workflows/swift-codegen.yml
vendored
2
.github/workflows/swift-codegen.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
git diff --exit-code --stat HEAD
|
||||
- name: Generate C++ files
|
||||
run: |
|
||||
bazel run //swift/codegen:cppcodegen -- --cpp-output=$PWD/swift-generated-headers
|
||||
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-headers
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: swift-generated-headers
|
||||
|
||||
1
.github/workflows/swift-qltest.yml
vendored
1
.github/workflows/swift-qltest.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-qltest.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
defaults:
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -55,3 +55,6 @@ go/tools/win64
|
||||
go/tools/tokenizer.jar
|
||||
go/main
|
||||
|
||||
# node_modules folders except in the JS test suite
|
||||
node_modules/
|
||||
!/javascript/ql/test/**/node_modules/
|
||||
|
||||
@@ -25,7 +25,7 @@ repos:
|
||||
|
||||
- id: sync-files
|
||||
name: Fix files required to be identical
|
||||
files: \.(qll?|qhelp)$
|
||||
files: \.(qll?|qhelp|swift)$
|
||||
language: system
|
||||
entry: python3 config/sync-files.py --latest
|
||||
pass_filenames: false
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
# QL for QL reviewers
|
||||
/ql/ @github/codeql-ql-for-ql-reviewers
|
||||
|
||||
# Bazel
|
||||
**/*.bazel @github/codeql-ci-reviewers
|
||||
# Bazel (excluding BUILD.bazel files)
|
||||
WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
**/*.bzl @github/codeql-ci-reviewers
|
||||
|
||||
# Documentation etc
|
||||
|
||||
32
codeql-workspace.yml
Normal file
32
codeql-workspace.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
provide:
|
||||
- "*/ql/src/qlpack.yml"
|
||||
- "*/ql/lib/qlpack.yml"
|
||||
- "*/ql/test/qlpack.yml"
|
||||
- "*/ql/examples/qlpack.yml"
|
||||
- "*/ql/consistency-queries/qlpack.yml"
|
||||
- "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml"
|
||||
- "go/ql/config/legacy-support/qlpack.yml"
|
||||
- "go/build/codeql-extractor-go/codeql-extractor.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml"
|
||||
# This pack is explicitly excluded from the workspace since most users
|
||||
# will want to use a version of this pack from the package cache. Internal
|
||||
# users can uncomment the following line and place a custom ML model
|
||||
# in the corresponding pack to test a custom ML model within their local
|
||||
# checkout.
|
||||
# - "javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml"
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/lib/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/src/qlpack.yml"
|
||||
- "csharp/ql/campaigns/Solorigate/test/qlpack.yml"
|
||||
- "misc/legacy-support/*/qlpack.yml"
|
||||
- "misc/suite-helpers/qlpack.yml"
|
||||
- "ruby/extractor-pack/codeql-extractor.yml"
|
||||
- "swift/extractor-pack/codeql-extractor.yml"
|
||||
- "ql/extractor-pack/codeql-extractor.ym"
|
||||
|
||||
versionPolicies:
|
||||
default:
|
||||
requireChangeNotes: true
|
||||
committedPrereleaseSuffix: dev
|
||||
committedVersion: nextPatchRelease
|
||||
@@ -390,7 +390,8 @@
|
||||
"java/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"python/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"ruby/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"ql/ql/test/TestUtilities/InlineExpectationsTest.qll"
|
||||
"ql/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"go/ql/test/TestUtilities/InlineExpectationsTest.qll"
|
||||
],
|
||||
"C++ ExternalAPIs": [
|
||||
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
|
||||
@@ -525,7 +526,8 @@
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll",
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll"
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
|
||||
"python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll"
|
||||
],
|
||||
"IncompleteUrlSubstringSanitization": [
|
||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||
@@ -543,7 +545,8 @@
|
||||
],
|
||||
"ApiGraphModels": [
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll"
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
|
||||
"python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll"
|
||||
],
|
||||
"TaintedFormatStringQuery Ruby/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",
|
||||
@@ -564,5 +567,21 @@
|
||||
"Typo database": [
|
||||
"javascript/ql/src/Expressions/TypoDatabase.qll",
|
||||
"ql/ql/src/codeql_ql/style/TypoDatabase.qll"
|
||||
],
|
||||
"Swift declarations test file": [
|
||||
"swift/ql/test/extractor-tests/declarations/declarations.swift",
|
||||
"swift/ql/test/library-tests/parent/declarations.swift"
|
||||
],
|
||||
"Swift statements test file": [
|
||||
"swift/ql/test/extractor-tests/statements/statements.swift",
|
||||
"swift/ql/test/library-tests/parent/statements.swift"
|
||||
],
|
||||
"Swift expressions test file": [
|
||||
"swift/ql/test/extractor-tests/expressions/expressions.swift",
|
||||
"swift/ql/test/library-tests/parent/expressions.swift"
|
||||
],
|
||||
"Swift patterns test file": [
|
||||
"swift/ql/test/extractor-tests/patterns/patterns.swift",
|
||||
"swift/ql/test/library-tests/parent/patterns.swift"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
2115
cpp/downgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme
Normal file
2115
cpp/downgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Add relation for tracking C++ braced initializers
|
||||
compatibility: full
|
||||
braced_initialisers.rel: delete
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.2.2
|
||||
version: 0.2.3-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -51,4 +51,7 @@ class Initializer extends ControlFlowNode, @initialiser {
|
||||
override Function getControlFlowScope() { result = this.getExpr().getEnclosingFunction() }
|
||||
|
||||
override Stmt getEnclosingStmt() { result = this.getExpr().getEnclosingStmt() }
|
||||
|
||||
/** Holds if the initializer used the C++ braced initializer notation. */
|
||||
predicate isBraced() { braced_initialisers(underlyingElement(this)) }
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1436,6 +1436,10 @@ initialisers(
|
||||
int location: @location_expr ref
|
||||
);
|
||||
|
||||
braced_initialisers(
|
||||
int init: @initialiser ref
|
||||
);
|
||||
|
||||
/**
|
||||
* An ancestor for the expression, for cases in which we cannot
|
||||
* otherwise find the expression's parent.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add relation for tracking C++ braced initializers
|
||||
compatibility: backwards
|
||||
@@ -17,6 +17,36 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
|
||||
/**
|
||||
* A Linux system call.
|
||||
*/
|
||||
class SystemCallFunction extends Function {
|
||||
SystemCallFunction() {
|
||||
exists(MacroInvocation m |
|
||||
m.getMacro().getName().matches("SYSCALL\\_DEFINE%") and
|
||||
this = m.getEnclosingFunction()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A value that comes from a Linux system call (sources).
|
||||
*/
|
||||
class SystemCallSource extends DataFlow::Node {
|
||||
SystemCallSource() {
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget() instanceof SystemCallFunction and
|
||||
(
|
||||
this.asDefiningArgument() = fc.getAnArgument().getAChild*() or
|
||||
this.asExpr() = fc
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Macros used to check the value (barriers).
|
||||
*/
|
||||
class WriteAccessCheckMacro extends Macro {
|
||||
VariableAccess va;
|
||||
|
||||
@@ -28,6 +58,9 @@ class WriteAccessCheckMacro extends Macro {
|
||||
VariableAccess getArgument() { result = va }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `unsafe_put_user` macro and its uses (sinks).
|
||||
*/
|
||||
class UnSafePutUserMacro extends Macro {
|
||||
PointerDereferenceExpr writeUserPtr;
|
||||
|
||||
@@ -42,15 +75,13 @@ class UnSafePutUserMacro extends Macro {
|
||||
}
|
||||
}
|
||||
|
||||
class ExploitableUserModePtrParam extends Parameter {
|
||||
class ExploitableUserModePtrParam extends SystemCallSource {
|
||||
ExploitableUserModePtrParam() {
|
||||
not exists(WriteAccessCheckMacro writeAccessCheck |
|
||||
DataFlow::localFlow(DataFlow::parameterNode(this),
|
||||
DataFlow::exprNode(writeAccessCheck.getArgument()))
|
||||
) and
|
||||
exists(UnSafePutUserMacro unsafePutUser |
|
||||
DataFlow::localFlow(DataFlow::parameterNode(this),
|
||||
DataFlow::exprNode(unsafePutUser.getUserModePtr()))
|
||||
DataFlow::localFlow(this, DataFlow::exprNode(unsafePutUser.getUserModePtr()))
|
||||
) and
|
||||
not exists(WriteAccessCheckMacro writeAccessCheck |
|
||||
DataFlow::localFlow(this, DataFlow::exprNode(writeAccessCheck.getArgument()))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.1.3
|
||||
version: 0.1.4-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
| test.cpp:14:16:14:16 | p | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:14:16:14:16 | p | p |
|
||||
| test.cpp:20:21:20:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:20:21:20:22 | ref arg & ... | ref arg & ... |
|
||||
| test.cpp:41:21:41:22 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:41:21:41:22 | ref arg & ... | ref arg & ... |
|
||||
| test.cpp:69:21:69:27 | ref arg & ... | unsafe_put_user write user-mode pointer $@ without check. | test.cpp:69:21:69:27 | ref arg & ... | ref arg & ... |
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
void SYSC_SOMESYSTEMCALL(void *param);
|
||||
#define SYSCALL_DEFINE(name, ...) \
|
||||
void do_sys_##name(); \
|
||||
void sys_##name(...) { do_sys_##name(); } \
|
||||
void do_sys_##name()
|
||||
SYSCALL_DEFINE(somesystemcall, void *param) {};
|
||||
|
||||
bool user_access_begin_impl(const void *where, size_t sz);
|
||||
void user_access_end_impl();
|
||||
@@ -13,14 +17,14 @@ void unsafe_put_user_impl(int what, const void *where, size_t sz);
|
||||
|
||||
void test1(int p)
|
||||
{
|
||||
SYSC_SOMESYSTEMCALL(&p);
|
||||
sys_somesystemcall(&p);
|
||||
|
||||
unsafe_put_user(123, &p); // BAD
|
||||
}
|
||||
|
||||
void test2(int p)
|
||||
{
|
||||
SYSC_SOMESYSTEMCALL(&p);
|
||||
sys_somesystemcall(&p);
|
||||
|
||||
if (user_access_begin(&p, sizeof(p)))
|
||||
{
|
||||
@@ -34,16 +38,16 @@ void test3()
|
||||
{
|
||||
int v;
|
||||
|
||||
SYSC_SOMESYSTEMCALL(&v);
|
||||
sys_somesystemcall(&v);
|
||||
|
||||
unsafe_put_user(123, &v); // BAD [NOT DETECTED]
|
||||
unsafe_put_user(123, &v); // BAD
|
||||
}
|
||||
|
||||
void test4()
|
||||
{
|
||||
int v;
|
||||
|
||||
SYSC_SOMESYSTEMCALL(&v);
|
||||
sys_somesystemcall(&v);
|
||||
|
||||
if (user_access_begin(&v, sizeof(v)))
|
||||
{
|
||||
@@ -62,16 +66,16 @@ void test5()
|
||||
{
|
||||
data myData;
|
||||
|
||||
SYSC_SOMESYSTEMCALL(&myData);
|
||||
sys_somesystemcall(&myData);
|
||||
|
||||
unsafe_put_user(123, &(myData.x)); // BAD [NOT DETECTED]
|
||||
unsafe_put_user(123, &(myData.x)); // BAD
|
||||
}
|
||||
|
||||
void test6()
|
||||
{
|
||||
data myData;
|
||||
|
||||
SYSC_SOMESYSTEMCALL(&myData);
|
||||
sys_somesystemcall(&myData);
|
||||
|
||||
if (user_access_begin(&myData, sizeof(myData)))
|
||||
{
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint,summary:value
|
||||
Dapper,55,,,,,,55,,,,
|
||||
JsonToItemsTaskFactory,,,7,,,,,,,7,
|
||||
Microsoft.ApplicationBlocks.Data,28,,,,,,28,,,,
|
||||
Microsoft.CSharp,,,24,,,,,,,24,
|
||||
Microsoft.EntityFrameworkCore,6,,,,,,6,,,,
|
||||
Microsoft.Extensions.Primitives,,,54,,,,,,,54,
|
||||
Microsoft.VisualBasic,,,4,,,,,,,,4
|
||||
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,15,
|
||||
Microsoft.Extensions.Caching.Memory,,,46,,,,,,,45,1
|
||||
Microsoft.Extensions.Configuration,,,83,,,,,,,80,3
|
||||
Microsoft.Extensions.DependencyInjection,,,62,,,,,,,62,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,12,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,15,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,13,2
|
||||
Microsoft.Extensions.Hosting,,,17,,,,,,,16,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,10,
|
||||
Microsoft.Extensions.Logging,,,37,,,,,,,37,
|
||||
Microsoft.Extensions.Options,,,8,,,,,,,8,
|
||||
Microsoft.Extensions.Primitives,,,63,,,,,,,63,
|
||||
Microsoft.Interop,,,27,,,,,,,27,
|
||||
Microsoft.NET.Build.Tasks,,,1,,,,,,,1,
|
||||
Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,4,
|
||||
Microsoft.VisualBasic,,,9,,,,,,,5,4
|
||||
Microsoft.Win32,,,8,,,,,,,8,
|
||||
MySql.Data.MySqlClient,48,,,,,,48,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,75,92,,,7,
|
||||
System,28,3,2336,,4,,23,1,3,611,1725
|
||||
System,28,3,12038,,4,,23,1,3,10096,1942
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",3,2336,28,5
|
||||
Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Primitives``, ``Microsoft.VisualBasic``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``",,149,137,
|
||||
Totals,,3,2492,359,5
|
||||
System,"``System.*``, ``System``",3,12038,28,5
|
||||
Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``",,554,137,
|
||||
Totals,,3,12599,359,5
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.1.3
|
||||
version: 1.1.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.1.3
|
||||
version: 1.1.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.2.2
|
||||
version: 0.2.3-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -86,6 +86,7 @@ private import internal.FlowSummaryImplSpecific
|
||||
*/
|
||||
private module Frameworks {
|
||||
private import semmle.code.csharp.frameworks.EntityFramework
|
||||
private import semmle.code.csharp.frameworks.Generated
|
||||
private import semmle.code.csharp.frameworks.JsonNET
|
||||
private import semmle.code.csharp.frameworks.microsoft.extensions.Primitives
|
||||
private import semmle.code.csharp.frameworks.microsoft.VisualBasic
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3854,16 +3854,11 @@ class PathNode extends TPathNode {
|
||||
/** Gets the associated configuration. */
|
||||
Configuration getConfiguration() { none() }
|
||||
|
||||
private PathNode getASuccessorIfHidden() {
|
||||
this.(PathNodeImpl).isHidden() and
|
||||
result = this.(PathNodeImpl).getASuccessorImpl()
|
||||
}
|
||||
|
||||
/** Gets a successor of this node, if any. */
|
||||
final PathNode getASuccessor() {
|
||||
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.(PathNodeImpl).isHidden() and
|
||||
not result.(PathNodeImpl).isHidden()
|
||||
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
|
||||
reach(this) and
|
||||
reach(result)
|
||||
}
|
||||
|
||||
/** Holds if this node is a source. */
|
||||
@@ -3871,7 +3866,18 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
|
||||
abstract private class PathNodeImpl extends PathNode {
|
||||
abstract PathNode getASuccessorImpl();
|
||||
abstract PathNodeImpl getASuccessorImpl();
|
||||
|
||||
private PathNodeImpl getASuccessorIfHidden() {
|
||||
this.isHidden() and
|
||||
result = this.getASuccessorImpl()
|
||||
}
|
||||
|
||||
final PathNodeImpl getANonHiddenSuccessor() {
|
||||
result = this.getASuccessorImpl().getASuccessorIfHidden*() and
|
||||
not this.isHidden() and
|
||||
not result.isHidden()
|
||||
}
|
||||
|
||||
abstract NodeEx getNodeEx();
|
||||
|
||||
@@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink. */
|
||||
private predicate directReach(PathNode n) {
|
||||
n instanceof PathNodeSink or directReach(n.getASuccessor())
|
||||
private predicate directReach(PathNodeImpl n) {
|
||||
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
|
||||
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
|
||||
|
||||
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
|
||||
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
|
||||
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
|
||||
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
|
||||
}
|
||||
|
||||
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
|
||||
|
||||
@@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
|
||||
*/
|
||||
module PathGraph {
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) }
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
@@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
||||
|
||||
override Configuration getConfiguration() { result = config }
|
||||
|
||||
override PathNode getASuccessorImpl() { none() }
|
||||
override PathNodeImpl getASuccessorImpl() { none() }
|
||||
|
||||
override predicate isSource() { sourceNode(node, state, config) }
|
||||
}
|
||||
@@ -4365,8 +4373,8 @@ private module Subpaths {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getASuccessor() and
|
||||
private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) {
|
||||
succ = pred.getANonHiddenSuccessor() and
|
||||
succNode = succ.getNodeEx()
|
||||
}
|
||||
|
||||
@@ -4375,9 +4383,9 @@ private module Subpaths {
|
||||
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
|
||||
* `ret -> out` is summarized as the edge `arg -> out`.
|
||||
*/
|
||||
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
|
||||
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
|
||||
pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and
|
||||
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
|
||||
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
|
||||
hasSuccessor(pragma[only_bind_into](arg), par, p) and
|
||||
not ret.isHidden() and
|
||||
@@ -4390,12 +4398,12 @@ private module Subpaths {
|
||||
/**
|
||||
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
|
||||
*/
|
||||
predicate retReach(PathNode n) {
|
||||
predicate retReach(PathNodeImpl n) {
|
||||
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
|
||||
or
|
||||
exists(PathNode mid |
|
||||
exists(PathNodeImpl mid |
|
||||
retReach(mid) and
|
||||
n.getASuccessor() = mid and
|
||||
n.getANonHiddenSuccessor() = mid and
|
||||
not subpaths(_, mid, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* A module importing all generated Models as Data models.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
private module GeneratedFrameworks {
|
||||
private import generated.dotnet.Runtime
|
||||
}
|
||||
10122
csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll
Normal file
10122
csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll
Normal file
File diff suppressed because it is too large
Load Diff
@@ -28,13 +28,6 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
exists(Expr exceptionExpr |
|
||||
// Writing an exception directly is bad
|
||||
source.asExpr() = exceptionExpr
|
||||
or
|
||||
// Writing an exception property is bad
|
||||
source.asExpr().(PropertyAccess).getQualifier() = exceptionExpr
|
||||
or
|
||||
// Writing the result of ToString is bad
|
||||
source.asExpr() =
|
||||
any(MethodCall mc | mc.getQualifier() = exceptionExpr and mc.getTarget().hasName("ToString"))
|
||||
|
|
||||
// Expr has type `System.Exception`.
|
||||
exceptionExpr.getType().(RefType).getABaseType*() instanceof SystemExceptionClass and
|
||||
@@ -47,12 +40,26 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node source, DataFlow::Node sink) {
|
||||
sink.asExpr() =
|
||||
any(MethodCall mc |
|
||||
source.asExpr() = mc.getQualifier() and
|
||||
mc.getTarget().hasName("ToString") and
|
||||
mc.getQualifier().getType().(RefType).getABaseType*() instanceof SystemExceptionClass
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof RemoteFlowSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) {
|
||||
// Do not flow through Message
|
||||
sanitizer.asExpr() = any(SystemExceptionClass se).getProperty("Message").getAnAccess()
|
||||
}
|
||||
|
||||
override predicate isSanitizerIn(DataFlow::Node sanitizer) {
|
||||
// Do not flow through Message
|
||||
sanitizer.asExpr().getType().(RefType).getABaseType*() instanceof SystemExceptionClass
|
||||
}
|
||||
}
|
||||
|
||||
from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 0.1.3
|
||||
version: 0.1.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -206,7 +206,9 @@
|
||||
| CSharp7.cs:283:13:283:62 | SSA def(list) | CSharp7.cs:285:39:285:42 | access to local variable list |
|
||||
| CSharp7.cs:283:20:283:62 | call to method Select<KeyValuePair<Int32,String>,(Int32,String)> | CSharp7.cs:283:13:283:62 | SSA def(list) |
|
||||
| CSharp7.cs:283:32:283:35 | item | CSharp7.cs:283:41:283:44 | access to parameter item |
|
||||
| CSharp7.cs:283:41:283:44 | access to parameter item | CSharp7.cs:283:41:283:48 | access to property Key |
|
||||
| CSharp7.cs:283:41:283:44 | access to parameter item | CSharp7.cs:283:51:283:54 | access to parameter item |
|
||||
| CSharp7.cs:283:51:283:54 | access to parameter item | CSharp7.cs:283:51:283:60 | access to property Value |
|
||||
| CSharp7.cs:285:39:285:42 | access to local variable list | CSharp7.cs:287:36:287:39 | access to local variable list |
|
||||
| CSharp7.cs:287:36:287:39 | access to local variable list | CSharp7.cs:289:32:289:35 | access to local variable list |
|
||||
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,2 @@
|
||||
| System.Collections.Specialized.NameValueCollection.get_Item(string) [qualifier] | 1 | 1 |
|
||||
| System.Web.HttpRequest.get_QueryString() [qualifier] | 1 | 1 |
|
||||
| System.Web.HttpResponse.Write(string) [param 0] | 1 | 1 |
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
edges
|
||||
| UntrustedData.cs:9:20:9:42 | access to property QueryString : NameValueCollection | UntrustedData.cs:9:20:9:50 | access to indexer : String |
|
||||
| UntrustedData.cs:9:20:9:42 | access to property QueryString : NameValueCollection | UntrustedData.cs:13:28:13:31 | access to local variable name |
|
||||
| UntrustedData.cs:9:20:9:50 | access to indexer : String | UntrustedData.cs:13:28:13:31 | access to local variable name |
|
||||
nodes
|
||||
| UntrustedData.cs:9:20:9:30 | access to property Request | semmle.label | access to property Request |
|
||||
| UntrustedData.cs:9:20:9:42 | access to property QueryString | semmle.label | access to property QueryString |
|
||||
| UntrustedData.cs:9:20:9:42 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UntrustedData.cs:9:20:9:50 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| UntrustedData.cs:13:28:13:31 | access to local variable name | semmle.label | access to local variable name |
|
||||
subpaths
|
||||
#select
|
||||
| UntrustedData.cs:9:20:9:30 | access to property Request | UntrustedData.cs:9:20:9:30 | access to property Request | UntrustedData.cs:9:20:9:30 | access to property Request | Call to System.Web.HttpRequest.get_QueryString with untrusted data from $@. | UntrustedData.cs:9:20:9:30 | access to property Request | access to property Request |
|
||||
| UntrustedData.cs:9:20:9:42 | access to property QueryString | UntrustedData.cs:9:20:9:42 | access to property QueryString | UntrustedData.cs:9:20:9:42 | access to property QueryString | Call to System.Collections.Specialized.NameValueCollection.get_Item with untrusted data from $@. | UntrustedData.cs:9:20:9:42 | access to property QueryString | access to property QueryString |
|
||||
| UntrustedData.cs:13:28:13:31 | access to local variable name | UntrustedData.cs:9:20:9:42 | access to property QueryString : NameValueCollection | UntrustedData.cs:13:28:13:31 | access to local variable name | Call to System.Web.HttpResponse.Write with untrusted data from $@. | UntrustedData.cs:9:20:9:42 | access to property QueryString : NameValueCollection | access to property QueryString : NameValueCollection |
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
edges
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:10:23:10:53 | access to indexer : String |
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:12:50:12:53 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:17:51:17:54 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:25:30:25:33 | access to local variable path |
|
||||
@@ -6,8 +7,16 @@ edges
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:36:25:36:31 | access to local variable badPath |
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:38:49:38:55 | access to local variable badPath |
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | TaintedPath.cs:51:26:51:29 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:12:50:12:53 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:17:51:17:54 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:25:30:25:33 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:31:30:31:33 | access to local variable path |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:36:25:36:31 | access to local variable badPath |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:38:49:38:55 | access to local variable badPath |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | TaintedPath.cs:51:26:51:29 | access to local variable path |
|
||||
nodes
|
||||
| TaintedPath.cs:10:23:10:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| TaintedPath.cs:10:23:10:53 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| TaintedPath.cs:12:50:12:53 | access to local variable path | semmle.label | access to local variable path |
|
||||
| TaintedPath.cs:17:51:17:54 | access to local variable path | semmle.label | access to local variable path |
|
||||
| TaintedPath.cs:25:30:25:33 | access to local variable path | semmle.label | access to local variable path |
|
||||
|
||||
@@ -3,26 +3,53 @@ edges
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:26:27:26:47 | ... + ... |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:26:50:26:66 | ... + ... |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:28:63:28:71 | access to local variable userInput |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:28:63:28:71 | access to local variable userInput : String |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:28:74:28:82 | access to local variable userInput |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:28:74:28:82 | access to local variable userInput : String |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:32:39:32:47 | access to local variable userInput |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:32:39:32:47 | access to local variable userInput : String |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:33:40:33:48 | access to local variable userInput |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:33:40:33:48 | access to local variable userInput : String |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:34:47:34:55 | access to local variable userInput |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | CommandInjection.cs:34:47:34:55 | access to local variable userInput : String |
|
||||
| CommandInjection.cs:28:42:28:83 | object creation of type ProcessStartInfo : ProcessStartInfo | CommandInjection.cs:29:27:29:35 | access to local variable startInfo |
|
||||
| CommandInjection.cs:28:63:28:71 | access to local variable userInput : String | CommandInjection.cs:28:42:28:83 | object creation of type ProcessStartInfo : ProcessStartInfo |
|
||||
| CommandInjection.cs:28:74:28:82 | access to local variable userInput : String | CommandInjection.cs:28:42:28:83 | object creation of type ProcessStartInfo : ProcessStartInfo |
|
||||
| CommandInjection.cs:32:13:32:26 | [post] access to local variable startInfoProps : ProcessStartInfo | CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps |
|
||||
| CommandInjection.cs:32:39:32:47 | access to local variable userInput : String | CommandInjection.cs:32:13:32:26 | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
| CommandInjection.cs:33:13:33:26 | [post] access to local variable startInfoProps : ProcessStartInfo | CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps |
|
||||
| CommandInjection.cs:33:40:33:48 | access to local variable userInput : String | CommandInjection.cs:33:13:33:26 | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
| CommandInjection.cs:34:13:34:26 | [post] access to local variable startInfoProps : ProcessStartInfo | CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps |
|
||||
| CommandInjection.cs:34:47:34:55 | access to local variable userInput : String | CommandInjection.cs:34:13:34:26 | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
nodes
|
||||
| CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox |
|
||||
| CommandInjection.cs:25:32:25:51 | access to property Text : String | semmle.label | access to property Text : String |
|
||||
| CommandInjection.cs:26:27:26:47 | ... + ... | semmle.label | ... + ... |
|
||||
| CommandInjection.cs:26:50:26:66 | ... + ... | semmle.label | ... + ... |
|
||||
| CommandInjection.cs:28:42:28:83 | object creation of type ProcessStartInfo : ProcessStartInfo | semmle.label | object creation of type ProcessStartInfo : ProcessStartInfo |
|
||||
| CommandInjection.cs:28:63:28:71 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| CommandInjection.cs:28:63:28:71 | access to local variable userInput : String | semmle.label | access to local variable userInput : String |
|
||||
| CommandInjection.cs:28:74:28:82 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| CommandInjection.cs:28:74:28:82 | access to local variable userInput : String | semmle.label | access to local variable userInput : String |
|
||||
| CommandInjection.cs:29:27:29:35 | access to local variable startInfo | semmle.label | access to local variable startInfo |
|
||||
| CommandInjection.cs:32:13:32:26 | [post] access to local variable startInfoProps : ProcessStartInfo | semmle.label | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
| CommandInjection.cs:32:39:32:47 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| CommandInjection.cs:32:39:32:47 | access to local variable userInput : String | semmle.label | access to local variable userInput : String |
|
||||
| CommandInjection.cs:33:13:33:26 | [post] access to local variable startInfoProps : ProcessStartInfo | semmle.label | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
| CommandInjection.cs:33:40:33:48 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| CommandInjection.cs:33:40:33:48 | access to local variable userInput : String | semmle.label | access to local variable userInput : String |
|
||||
| CommandInjection.cs:34:13:34:26 | [post] access to local variable startInfoProps : ProcessStartInfo | semmle.label | [post] access to local variable startInfoProps : ProcessStartInfo |
|
||||
| CommandInjection.cs:34:47:34:55 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| CommandInjection.cs:34:47:34:55 | access to local variable userInput : String | semmle.label | access to local variable userInput : String |
|
||||
| CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps | semmle.label | access to local variable startInfoProps |
|
||||
subpaths
|
||||
#select
|
||||
| CommandInjection.cs:26:27:26:47 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:26:27:26:47 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:26:50:26:66 | ... + ... | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:26:50:26:66 | ... + ... | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:28:63:28:71 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:28:63:28:71 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:28:74:28:82 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:28:74:28:82 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:29:27:29:35 | access to local variable startInfo | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:29:27:29:35 | access to local variable startInfo | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:32:39:32:47 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:32:39:32:47 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:33:40:33:48 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:33:40:33:48 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:34:47:34:55 | access to local variable userInput | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:34:47:34:55 | access to local variable userInput | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
| CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox : TextBox | CommandInjection.cs:35:27:35:40 | access to local variable startInfoProps | $@ flows to here and is used in a command. | CommandInjection.cs:25:32:25:46 | access to field categoryTextBox | User-provided value |
|
||||
|
||||
@@ -7,13 +7,24 @@ edges
|
||||
| XSS.cs:26:32:26:40 | access to local variable userInput [element] : String | XSS.cs:26:32:26:51 | call to method ToString |
|
||||
| XSS.cs:27:29:27:37 | access to local variable userInput [element] : String | XSS.cs:27:29:27:48 | call to method ToString |
|
||||
| XSS.cs:28:26:28:34 | access to local variable userInput [element] : String | XSS.cs:28:26:28:45 | call to method ToString |
|
||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:37:27:37:61 | access to indexer : String |
|
||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:38:36:38:39 | access to local variable name |
|
||||
| XSS.cs:37:27:37:61 | access to indexer : String | XSS.cs:38:36:38:39 | access to local variable name |
|
||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:57:27:57:73 | access to indexer : String |
|
||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:59:22:59:25 | access to local variable name |
|
||||
| XSS.cs:57:27:57:73 | access to indexer : String | XSS.cs:59:22:59:25 | access to local variable name |
|
||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:75:27:75:61 | access to indexer : String |
|
||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:76:36:76:39 | access to local variable name |
|
||||
| XSS.cs:75:27:75:61 | access to indexer : String | XSS.cs:76:36:76:39 | access to local variable name |
|
||||
| XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | XSS.cs:79:36:79:40 | access to local variable name2 |
|
||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:85:27:85:61 | access to indexer : String |
|
||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:86:28:86:31 | access to local variable name |
|
||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:87:31:87:34 | access to local variable name |
|
||||
| XSS.cs:85:27:85:61 | access to indexer : String | XSS.cs:86:28:86:31 | access to local variable name |
|
||||
| XSS.cs:85:27:85:61 | access to indexer : String | XSS.cs:87:31:87:34 | access to local variable name |
|
||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:94:27:94:61 | access to indexer : String |
|
||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:95:31:95:34 | access to local variable name |
|
||||
| XSS.cs:94:27:94:61 | access to indexer : String | XSS.cs:95:31:95:34 | access to local variable name |
|
||||
| script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> |
|
||||
| script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> |
|
||||
| script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> |
|
||||
@@ -28,17 +39,22 @@ nodes
|
||||
| XSS.cs:28:26:28:34 | access to local variable userInput [element] : String | semmle.label | access to local variable userInput [element] : String |
|
||||
| XSS.cs:28:26:28:45 | call to method ToString | semmle.label | call to method ToString |
|
||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSS.cs:37:27:37:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSS.cs:38:36:38:39 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSS.cs:57:27:57:73 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSS.cs:59:22:59:25 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSS.cs:75:27:75:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSS.cs:76:36:76:39 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | semmle.label | access to property Request : HttpRequestBase |
|
||||
| XSS.cs:79:36:79:40 | access to local variable name2 | semmle.label | access to local variable name2 |
|
||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSS.cs:85:27:85:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSS.cs:86:28:86:31 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:87:31:87:34 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSS.cs:94:27:94:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSS.cs:95:31:95:34 | access to local variable name | semmle.label | access to local variable name |
|
||||
| XSS.cs:134:20:134:33 | access to property RawUrl | semmle.label | access to property RawUrl |
|
||||
| script.aspx:12:1:12:14 | <%= ... %> | semmle.label | <%= ... %> |
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
edges
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:19:25:19:52 | access to indexer : String |
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi |
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi |
|
||||
| XSSAspNet.cs:19:25:19:52 | access to indexer : String | XSSAspNet.cs:26:30:26:34 | access to local variable sayHi |
|
||||
| XSSAspNet.cs:19:25:19:52 | access to indexer : String | XSSAspNet.cs:36:40:36:44 | access to local variable sayHi |
|
||||
| XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | XSSAspNet.cs:43:28:43:55 | access to indexer |
|
||||
| XSSAspNetCore.cs:21:52:21:64 | access to property Query : IQueryCollection | XSSAspNetCore.cs:21:52:21:76 | call to operator implicit conversion |
|
||||
| XSSAspNetCore.cs:40:56:40:58 | foo : String | XSSAspNetCore.cs:44:51:44:53 | access to parameter foo |
|
||||
@@ -12,6 +15,7 @@ edges
|
||||
| XSSAspNetCore.cs:72:51:72:65 | access to property Headers : IHeaderDictionary | XSSAspNetCore.cs:72:51:72:72 | call to operator implicit conversion |
|
||||
nodes
|
||||
| XSSAspNet.cs:19:25:19:43 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XSSAspNet.cs:19:25:19:52 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XSSAspNet.cs:26:30:26:34 | access to local variable sayHi | semmle.label | access to local variable sayHi |
|
||||
| XSSAspNet.cs:36:40:36:44 | access to local variable sayHi | semmle.label | access to local variable sayHi |
|
||||
| XSSAspNet.cs:43:28:43:46 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
edges
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:11:27:11:61 | access to indexer : String |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:14:54:14:78 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:16:21:16:45 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:23:21:23:45 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:24:53:24:77 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:27:48:27:70 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | LDAPInjection.cs:29:20:29:42 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:14:54:14:78 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:16:21:16:45 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:23:21:23:45 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:24:53:24:77 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:27:48:27:70 | ... + ... |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | LDAPInjection.cs:29:20:29:42 | ... + ... |
|
||||
nodes
|
||||
| LDAPInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| LDAPInjection.cs:11:27:11:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| LDAPInjection.cs:14:54:14:78 | ... + ... | semmle.label | ... + ... |
|
||||
| LDAPInjection.cs:16:21:16:45 | ... + ... | semmle.label | ... + ... |
|
||||
| LDAPInjection.cs:23:21:23:45 | ... + ... | semmle.label | ... + ... |
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
edges
|
||||
| Test.cs:8:27:8:49 | access to property QueryString : NameValueCollection | Test.cs:8:27:8:65 | access to indexer : String |
|
||||
| Test.cs:8:27:8:49 | access to property QueryString : NameValueCollection | Test.cs:15:25:15:80 | ... + ... |
|
||||
| Test.cs:8:27:8:65 | access to indexer : String | Test.cs:15:25:15:80 | ... + ... |
|
||||
nodes
|
||||
| Test.cs:8:27:8:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| Test.cs:8:27:8:65 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| Test.cs:15:25:15:80 | ... + ... | semmle.label | ... + ... |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
edges
|
||||
| CodeInjection.cs:23:23:23:45 | access to property QueryString : NameValueCollection | CodeInjection.cs:23:23:23:53 | access to indexer : String |
|
||||
| CodeInjection.cs:23:23:23:45 | access to property QueryString : NameValueCollection | CodeInjection.cs:29:64:29:67 | access to local variable code |
|
||||
| CodeInjection.cs:23:23:23:45 | access to property QueryString : NameValueCollection | CodeInjection.cs:40:36:40:39 | access to local variable code |
|
||||
| CodeInjection.cs:23:23:23:53 | access to indexer : String | CodeInjection.cs:29:64:29:67 | access to local variable code |
|
||||
| CodeInjection.cs:23:23:23:53 | access to indexer : String | CodeInjection.cs:40:36:40:39 | access to local variable code |
|
||||
nodes
|
||||
| CodeInjection.cs:23:23:23:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| CodeInjection.cs:23:23:23:53 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| CodeInjection.cs:29:64:29:67 | access to local variable code | semmle.label | access to local variable code |
|
||||
| CodeInjection.cs:40:36:40:39 | access to local variable code | semmle.label | access to local variable code |
|
||||
| CodeInjection.cs:56:36:56:44 | access to property Text | semmle.label | access to property Text |
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
edges
|
||||
| ResourceInjection.cs:8:27:8:49 | access to property QueryString : NameValueCollection | ResourceInjection.cs:8:27:8:61 | access to indexer : String |
|
||||
| ResourceInjection.cs:8:27:8:49 | access to property QueryString : NameValueCollection | ResourceInjection.cs:11:57:11:72 | access to local variable connectionString |
|
||||
| ResourceInjection.cs:8:27:8:49 | access to property QueryString : NameValueCollection | ResourceInjection.cs:13:42:13:57 | access to local variable connectionString |
|
||||
| ResourceInjection.cs:8:27:8:61 | access to indexer : String | ResourceInjection.cs:11:57:11:72 | access to local variable connectionString |
|
||||
| ResourceInjection.cs:8:27:8:61 | access to indexer : String | ResourceInjection.cs:13:42:13:57 | access to local variable connectionString |
|
||||
nodes
|
||||
| ResourceInjection.cs:8:27:8:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| ResourceInjection.cs:8:27:8:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| ResourceInjection.cs:11:57:11:72 | access to local variable connectionString | semmle.label | access to local variable connectionString |
|
||||
| ResourceInjection.cs:13:42:13:57 | access to local variable connectionString | semmle.label | access to local variable connectionString |
|
||||
subpaths
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
edges
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:12:34:12:75 | access to indexer : String |
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:16:43:16:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:21:43:21:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:27:43:27:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:35:43:35:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:45:43:45:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | MissingXMLValidation.cs:16:43:16:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | MissingXMLValidation.cs:21:43:21:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | MissingXMLValidation.cs:27:43:27:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | MissingXMLValidation.cs:35:43:35:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | MissingXMLValidation.cs:45:43:45:57 | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:16:43:16:57 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:16:26:16:58 | object creation of type StringReader |
|
||||
| MissingXMLValidation.cs:21:43:21:57 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:21:26:21:58 | object creation of type StringReader |
|
||||
| MissingXMLValidation.cs:27:43:27:57 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:27:26:27:58 | object creation of type StringReader |
|
||||
@@ -11,6 +17,7 @@ edges
|
||||
| MissingXMLValidation.cs:45:43:45:57 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:45:26:45:58 | object creation of type StringReader |
|
||||
nodes
|
||||
| MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| MissingXMLValidation.cs:12:34:12:75 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| MissingXMLValidation.cs:16:26:16:58 | object creation of type StringReader | semmle.label | object creation of type StringReader |
|
||||
| MissingXMLValidation.cs:16:43:16:57 | access to local variable userProvidedXml : String | semmle.label | access to local variable userProvidedXml : String |
|
||||
| MissingXMLValidation.cs:21:26:21:58 | object creation of type StringReader | semmle.label | object creation of type StringReader |
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
edges
|
||||
| LogForging.cs:17:27:17:49 | access to property QueryString : NameValueCollection | LogForging.cs:17:27:17:61 | access to indexer : String |
|
||||
| LogForging.cs:17:27:17:49 | access to property QueryString : NameValueCollection | LogForging.cs:20:21:20:43 | ... + ... |
|
||||
| LogForging.cs:17:27:17:49 | access to property QueryString : NameValueCollection | LogForging.cs:26:50:26:72 | ... + ... |
|
||||
| LogForging.cs:17:27:17:61 | access to indexer : String | LogForging.cs:20:21:20:43 | ... + ... |
|
||||
| LogForging.cs:17:27:17:61 | access to indexer : String | LogForging.cs:26:50:26:72 | ... + ... |
|
||||
nodes
|
||||
| LogForging.cs:17:27:17:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| LogForging.cs:17:27:17:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| LogForging.cs:20:21:20:43 | ... + ... | semmle.label | ... + ... |
|
||||
| LogForging.cs:26:50:26:72 | ... + ... | semmle.label | ... + ... |
|
||||
subpaths
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
edges
|
||||
| ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format |
|
||||
| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String |
|
||||
| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:12:23:12:26 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:15:46:15:49 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | UncontrolledFormatString.cs:12:23:12:26 | access to local variable path |
|
||||
| UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | UncontrolledFormatString.cs:15:46:15:49 | access to local variable path |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format |
|
||||
nodes
|
||||
| ConsoleUncontrolledFormatString.cs:8:22:8:39 | call to method ReadLine : String | semmle.label | call to method ReadLine : String |
|
||||
| ConsoleUncontrolledFormatString.cs:11:31:11:36 | access to local variable format | semmle.label | access to local variable format |
|
||||
| UncontrolledFormatString.cs:9:23:9:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UncontrolledFormatString.cs:9:23:9:53 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| UncontrolledFormatString.cs:12:23:12:26 | access to local variable path | semmle.label | access to local variable path |
|
||||
| UncontrolledFormatString.cs:15:46:15:49 | access to local variable path | semmle.label | access to local variable path |
|
||||
| UncontrolledFormatString.cs:32:23:32:31 | access to property Text | semmle.label | access to property Text |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UncontrolledFormatStringBad.cs:9:25:9:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | semmle.label | access to local variable format |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
edges
|
||||
| ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:39:28:39:44 | access to property InnerException : Exception | ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:40:28:40:29 | access to local variable ex : Exception | ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:29 | access to local variable ex : Exception | ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:47:28:47:44 | object creation of type MyException : MyException | ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString |
|
||||
nodes
|
||||
| ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | semmle.label | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:39:28:39:44 | access to property InnerException : Exception | semmle.label | access to property InnerException : Exception |
|
||||
| ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:40:28:40:29 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | semmle.label | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:29 | access to local variable ex : Exception | semmle.label | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | semmle.label | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:47:28:47:44 | object creation of type MyException : MyException | semmle.label | object creation of type MyException : MyException |
|
||||
| ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | semmle.label | call to method ToString |
|
||||
subpaths
|
||||
#select
|
||||
| ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:19:32:19:44 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:19:32:19:33 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:21:32:21:33 | access to local variable ex | access to local variable ex |
|
||||
| ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | access to property StackTrace |
|
||||
| ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | call to method ToString |
|
||||
| ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex : Exception | ExceptionInformationExposure.cs:23:32:23:44 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:23:32:23:33 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | ExceptionInformationExposure.cs:39:28:39:44 | access to property InnerException : Exception | ExceptionInformationExposure.cs:39:28:39:55 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:39:28:39:44 | access to property InnerException | access to property InnerException : Exception |
|
||||
| ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | ExceptionInformationExposure.cs:40:28:40:29 | access to local variable ex : Exception | ExceptionInformationExposure.cs:40:28:40:40 | access to property StackTrace | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:40:28:40:29 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | ExceptionInformationExposure.cs:41:28:41:29 | access to local variable ex : Exception | ExceptionInformationExposure.cs:41:28:41:40 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:41:28:41:29 | access to local variable ex | access to local variable ex : Exception |
|
||||
| ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | ExceptionInformationExposure.cs:47:28:47:44 | object creation of type MyException : MyException | ExceptionInformationExposure.cs:47:28:47:55 | call to method ToString | Exception information from $@ flows to here, and is exposed to the user. | ExceptionInformationExposure.cs:47:28:47:44 | object creation of type MyException | object creation of type MyException : MyException |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
edges
|
||||
| UrlRedirect.cs:12:31:12:53 | access to property QueryString : NameValueCollection | UrlRedirect.cs:12:31:12:61 | access to indexer |
|
||||
| UrlRedirect.cs:22:22:22:44 | access to property QueryString : NameValueCollection | UrlRedirect.cs:22:22:22:52 | access to indexer : String |
|
||||
| UrlRedirect.cs:22:22:22:44 | access to property QueryString : NameValueCollection | UrlRedirect.cs:47:29:47:31 | access to local variable url |
|
||||
| UrlRedirect.cs:22:22:22:52 | access to indexer : String | UrlRedirect.cs:47:29:47:31 | access to local variable url |
|
||||
| UrlRedirect.cs:37:44:37:66 | access to property QueryString : NameValueCollection | UrlRedirect.cs:37:44:37:74 | access to indexer |
|
||||
| UrlRedirect.cs:38:47:38:69 | access to property QueryString : NameValueCollection | UrlRedirect.cs:38:47:38:77 | access to indexer |
|
||||
| UrlRedirectCore.cs:13:44:13:48 | value : String | UrlRedirectCore.cs:16:22:16:26 | access to parameter value |
|
||||
@@ -18,6 +20,7 @@ nodes
|
||||
| UrlRedirect.cs:12:31:12:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UrlRedirect.cs:12:31:12:61 | access to indexer | semmle.label | access to indexer |
|
||||
| UrlRedirect.cs:22:22:22:44 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UrlRedirect.cs:22:22:22:52 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| UrlRedirect.cs:37:44:37:66 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| UrlRedirect.cs:37:44:37:74 | access to indexer | semmle.label | access to indexer |
|
||||
| UrlRedirect.cs:38:47:38:69 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
edges
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:10:27:10:61 | access to indexer : String |
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:16:33:16:33 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:19:29:19:29 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:28:20:28:20 | access to local variable s |
|
||||
@@ -6,6 +7,14 @@ edges
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:40:21:40:21 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:46:22:46:22 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:52:21:52:21 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:16:33:16:33 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:19:29:19:29 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:28:20:28:20 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:34:30:34:30 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:40:21:40:21 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:46:22:46:22 | access to local variable s |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | XPathInjection.cs:52:21:52:21 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:11:27:11:61 | access to indexer : String |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:16:33:16:33 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:19:29:19:29 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:28:20:28:20 | access to local variable s |
|
||||
@@ -13,9 +22,18 @@ edges
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:40:21:40:21 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:46:22:46:22 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | XPathInjection.cs:52:21:52:21 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:16:33:16:33 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:19:29:19:29 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:28:20:28:20 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:34:30:34:30 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:40:21:40:21 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:46:22:46:22 | access to local variable s |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | XPathInjection.cs:52:21:52:21 | access to local variable s |
|
||||
nodes
|
||||
| XPathInjection.cs:10:27:10:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XPathInjection.cs:10:27:10:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XPathInjection.cs:11:27:11:49 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| XPathInjection.cs:11:27:11:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| XPathInjection.cs:16:33:16:33 | access to local variable s | semmle.label | access to local variable s |
|
||||
| XPathInjection.cs:19:29:19:29 | access to local variable s | semmle.label | access to local variable s |
|
||||
| XPathInjection.cs:28:20:28:20 | access to local variable s | semmle.label | access to local variable s |
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
edges
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:11:28:11:63 | access to indexer : String |
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:15:40:15:48 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:16:42:16:50 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:19:139:19:147 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:22:43:22:51 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:24:21:24:29 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | ExponentialRegex.cs:15:40:15:48 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | ExponentialRegex.cs:16:42:16:50 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | ExponentialRegex.cs:19:139:19:147 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | ExponentialRegex.cs:22:43:22:51 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | ExponentialRegex.cs:24:21:24:29 | access to local variable userInput |
|
||||
nodes
|
||||
| ExponentialRegex.cs:11:28:11:50 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| ExponentialRegex.cs:11:28:11:63 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| ExponentialRegex.cs:15:40:15:48 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| ExponentialRegex.cs:16:42:16:50 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
| ExponentialRegex.cs:19:139:19:147 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
edges
|
||||
| ExponentialRegex.cs:13:28:13:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:13:28:13:63 | access to indexer : String |
|
||||
| ExponentialRegex.cs:13:28:13:50 | access to property QueryString : NameValueCollection | ExponentialRegex.cs:16:40:16:48 | access to local variable userInput |
|
||||
| ExponentialRegex.cs:13:28:13:63 | access to indexer : String | ExponentialRegex.cs:16:40:16:48 | access to local variable userInput |
|
||||
nodes
|
||||
| ExponentialRegex.cs:13:28:13:50 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| ExponentialRegex.cs:13:28:13:63 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| ExponentialRegex.cs:16:40:16:48 | access to local variable userInput | semmle.label | access to local variable userInput |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
edges
|
||||
| RegexInjection.cs:10:24:10:46 | access to property QueryString : NameValueCollection | RegexInjection.cs:10:24:10:55 | access to indexer : String |
|
||||
| RegexInjection.cs:10:24:10:46 | access to property QueryString : NameValueCollection | RegexInjection.cs:14:19:14:23 | access to local variable regex |
|
||||
| RegexInjection.cs:10:24:10:55 | access to indexer : String | RegexInjection.cs:14:19:14:23 | access to local variable regex |
|
||||
nodes
|
||||
| RegexInjection.cs:10:24:10:46 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| RegexInjection.cs:10:24:10:55 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| RegexInjection.cs:14:19:14:23 | access to local variable regex | semmle.label | access to local variable regex |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
edges
|
||||
| ConditionalBypass.cs:12:26:12:48 | access to property QueryString : NameValueCollection | ConditionalBypass.cs:12:26:12:59 | access to indexer : String |
|
||||
| ConditionalBypass.cs:12:26:12:48 | access to property QueryString : NameValueCollection | ConditionalBypass.cs:16:13:16:30 | ... == ... |
|
||||
| ConditionalBypass.cs:12:26:12:59 | access to indexer : String | ConditionalBypass.cs:16:13:16:30 | ... == ... |
|
||||
| ConditionalBypass.cs:19:34:19:52 | access to property Cookies : HttpCookieCollection | ConditionalBypass.cs:22:13:22:23 | access to local variable adminCookie : HttpCookie |
|
||||
| ConditionalBypass.cs:19:34:19:52 | access to property Cookies : HttpCookieCollection | ConditionalBypass.cs:27:13:27:23 | access to local variable adminCookie : HttpCookie |
|
||||
| ConditionalBypass.cs:22:13:22:23 | access to local variable adminCookie : HttpCookie | ConditionalBypass.cs:22:13:22:29 | access to property Value : String |
|
||||
@@ -19,6 +21,7 @@ edges
|
||||
| ConditionalBypass.cs:84:13:84:29 | access to property Value : String | ConditionalBypass.cs:84:13:84:40 | ... == ... |
|
||||
nodes
|
||||
| ConditionalBypass.cs:12:26:12:48 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||
| ConditionalBypass.cs:12:26:12:59 | access to indexer : String | semmle.label | access to indexer : String |
|
||||
| ConditionalBypass.cs:16:13:16:30 | ... == ... | semmle.label | ... == ... |
|
||||
| ConditionalBypass.cs:19:34:19:52 | access to property Cookies : HttpCookieCollection | semmle.label | access to property Cookies : HttpCookieCollection |
|
||||
| ConditionalBypass.cs:22:13:22:23 | access to local variable adminCookie : HttpCookie | semmle.label | access to local variable adminCookie : HttpCookie |
|
||||
|
||||
@@ -226,7 +226,8 @@ commands that you can specify for compiled languages.
|
||||
|
||||
- Java project built using Gradle::
|
||||
|
||||
codeql database create java-database --language=java --command='gradle clean test'
|
||||
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL:
|
||||
codeql database create java-database --language=java --command='gradle --no-daemon clean test'
|
||||
|
||||
- Java project built using Maven::
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ Using the starter workspace
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The starter workspace is a Git repository. It contains:
|
||||
|
||||
* The `repository of CodeQL libraries and queries <https://github.com/github/codeql>`__ all supported languages. This is included as a submodule, so it can be updated without affecting your custom queries.
|
||||
* The `repository of CodeQL libraries and queries <https://github.com/github/codeql>`__ for all supported languages. This is included as a submodule, so it can be updated without affecting your custom queries.
|
||||
* A series of folders named ``codeql-custom-queries-<language>``. These are ready for you to start developing your own custom queries for each language, using the standard libraries. There are some example queries to get you started.
|
||||
|
||||
To use the starter workspace:
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
Java,"Java 7 to 18 [4]_","javac (OpenJDK and Oracle JDK),
|
||||
|
||||
Eclipse compiler for Java (ECJ) [5]_",``.java``
|
||||
JavaScript,ECMAScript 2021 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [6]_"
|
||||
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [6]_"
|
||||
Python,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10",Not applicable,``.py``
|
||||
Ruby [7]_,"up to 3.0.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
|
||||
TypeScript [8]_,"2.6-4.6",Standard TypeScript compiler,"``.ts``, ``.tsx``"
|
||||
TypeScript [8]_,"2.6-4.7",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
|
||||
|
||||
.. container:: footnote-group
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 0.1.3
|
||||
version: 0.1.4-dev
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
|
||||
16
go/ql/src/experimental/CWE-285/PamAuthBad.go
Normal file
16
go/ql/src/experimental/CWE-285/PamAuthBad.go
Normal file
@@ -0,0 +1,16 @@
|
||||
func bad() error {
|
||||
t, err := pam.StartFunc("", "username", func(s pam.Style, msg string) (string, error) {
|
||||
switch s {
|
||||
case pam.PromptEchoOff:
|
||||
return string(pass), nil
|
||||
}
|
||||
return "", fmt.Errorf("unsupported message style")
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := t.Authenticate(0); err != nil {
|
||||
return nil, fmt.Errorf("Authenticate: %w", err)
|
||||
}
|
||||
}
|
||||
52
go/ql/src/experimental/CWE-285/PamAuthBypass.qhelp
Normal file
52
go/ql/src/experimental/CWE-285/PamAuthBypass.qhelp
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Using only a call to
|
||||
<code>pam.Authenticate</code>
|
||||
to check the validity of a login can lead to authorization bypass vulnerabilities.
|
||||
</p>
|
||||
<p>
|
||||
A <code>pam.Authenticate</code> call
|
||||
only verifies the credentials of a user. It does not check if a user has an
|
||||
appropriate authorization to actually login. This means a user with an expired
|
||||
login or a password can still access the system.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
A call to
|
||||
<code>pam.Authenticate</code>
|
||||
should be followed by a call to
|
||||
<code>pam.AcctMgmt</code>
|
||||
to check if a user is allowed to login.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following example, the code only checks the credentials of a user. Hence,
|
||||
in this case, a user with expired credentials can still login. This can be
|
||||
verified by creating a new user account, expiring it with
|
||||
<code>chage -E0 `username` </code>
|
||||
and then trying to log in.
|
||||
</p>
|
||||
<sample src="PamAuthBad.go" />
|
||||
|
||||
<p>
|
||||
This can be avoided by calling
|
||||
<code>pam.AcctMgmt</code>
|
||||
call to verify access as has been done in the snippet shown below.
|
||||
</p>
|
||||
<sample src="PamAuthGood.go" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Man-Page:
|
||||
<a href="https://man7.org/linux/man-pages/man3/pam_acct_mgmt.3.html">pam_acct_mgmt</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
65
go/ql/src/experimental/CWE-285/PamAuthBypass.ql
Normal file
65
go/ql/src/experimental/CWE-285/PamAuthBypass.ql
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @name PAM authorization bypass due to incorrect usage
|
||||
* @description Not using `pam.AcctMgmt` after `pam.Authenticate` to check the validity of a login can lead to authorization bypass.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id go/unreachable-statement
|
||||
* @tags maintainability
|
||||
* correctness
|
||||
* external/cwe/cwe-561
|
||||
* external/cwe/cwe-285
|
||||
* @precision very-high
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
predicate isInTestFile(Expr r) {
|
||||
r.getFile().getAbsolutePath().matches("%test%") and
|
||||
not r.getFile().getAbsolutePath().matches("%/ql/test/%")
|
||||
}
|
||||
|
||||
class PamAuthenticate extends Method {
|
||||
PamAuthenticate() {
|
||||
this.hasQualifiedName("github.com/msteinert/pam", "Transaction", "Authenticate")
|
||||
}
|
||||
}
|
||||
|
||||
class PamAcctMgmt extends Method {
|
||||
PamAcctMgmt() { this.hasQualifiedName("github.com/msteinert/pam", "Transaction", "AcctMgmt") }
|
||||
}
|
||||
|
||||
class PamStartFunc extends Function {
|
||||
PamStartFunc() { this.hasQualifiedName("github.com/msteinert/pam", ["StartFunc", "Start"]) }
|
||||
}
|
||||
|
||||
class PamStartToAcctMgmtConfig extends TaintTracking::Configuration {
|
||||
PamStartToAcctMgmtConfig() { this = "PAM auth bypass (Start to AcctMgmt)" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(PamStartFunc p | p.getACall().getResult(0) = source)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(PamAcctMgmt p | p.getACall().getReceiver() = sink)
|
||||
}
|
||||
}
|
||||
|
||||
class PamStartToAuthenticateConfig extends TaintTracking::Configuration {
|
||||
PamStartToAuthenticateConfig() { this = "PAM auth bypass (Start to Authenticate)" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(PamStartFunc p | p.getACall().getResult(0) = source)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(PamAuthenticate p | p.getACall().getReceiver() = sink)
|
||||
}
|
||||
}
|
||||
|
||||
from
|
||||
PamStartToAcctMgmtConfig acctMgmtConfig, PamStartToAuthenticateConfig authConfig,
|
||||
DataFlow::Node source, DataFlow::Node sink
|
||||
where
|
||||
not isInTestFile(source.asExpr()) and
|
||||
(authConfig.hasFlow(source, sink) and not acctMgmtConfig.hasFlow(source, _))
|
||||
select source, "This Pam transaction may not be secure."
|
||||
19
go/ql/src/experimental/CWE-285/PamAuthGood.go
Normal file
19
go/ql/src/experimental/CWE-285/PamAuthGood.go
Normal file
@@ -0,0 +1,19 @@
|
||||
func good() error {
|
||||
t, err := pam.StartFunc("", "username", func(s pam.Style, msg string) (string, error) {
|
||||
switch s {
|
||||
case pam.PromptEchoOff:
|
||||
return string(pass), nil
|
||||
}
|
||||
return "", fmt.Errorf("unsupported message style")
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := t.Authenticate(0); err != nil {
|
||||
return nil, fmt.Errorf("Authenticate: %w", err)
|
||||
}
|
||||
if err := t.AcctMgmt(0); err != nil {
|
||||
return nil, fmt.Errorf("AcctMgmt: %w", err)
|
||||
}
|
||||
}
|
||||
50
go/ql/src/experimental/CWE-321/HardcodedKeys.qhelp
Normal file
50
go/ql/src/experimental/CWE-321/HardcodedKeys.qhelp
Normal file
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
A JSON Web Token (JWT) is used for authenticating and managing users in an application.
|
||||
</p>
|
||||
<p>
|
||||
Using a hard-coded secret key for signing JWT tokens in open source projects
|
||||
can leave the application using the token vulnerable to authentication bypasses.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A JWT token is safe for enforcing authentication and access control as long as it can't be forged by a malicious actor. However, when a project exposes this secret publicly, these seemingly unforgeable tokens can now be easily forged.
|
||||
Since the authentication as well as access control is typically enforced through these JWT tokens, an attacker armed with the secret can create a valid authentication token for any user and may even gain access to other privileged parts of the application.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
Generating a cryptograhically secure secret key during application initialization and using this generated key for future JWT signing requests can prevent this vulnerability.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
The following code uses a hard-coded string as a secret for signing the tokens. In this case, an attacker can very easily forge a token by using the hard-coded secret.
|
||||
</p>
|
||||
|
||||
<sample src="HardcodedKeysBad.go" />
|
||||
|
||||
</example>
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following case, the application uses a programatically generated string as a secret for signing the tokens. In this case, since the secret can't be predicted, the code is secure. A function like `GenerateCryptoString` can be run to generate a secure secret key at the time of application installation/initialization. This generated key can then be used for all future signing requests.
|
||||
</p>
|
||||
|
||||
<sample src="HardcodedKeysGood.go" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<li>
|
||||
CVE-2022-0664:
|
||||
<a href="https://nvd.nist.gov/vuln/detail/CVE-2022-0664">Use of Hard-coded Cryptographic Key in Go github.com/gravitl/netmaker prior to 0.8.5,0.9.4,0.10.0,0.10.1. </a>
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
18
go/ql/src/experimental/CWE-321/HardcodedKeys.ql
Normal file
18
go/ql/src/experimental/CWE-321/HardcodedKeys.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @name Use of a hardcoded key for signing JWT
|
||||
* @description Using a fixed hardcoded key for signing JWT's can allow an attacker to compromise security.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @id go/hardcoded-key
|
||||
* @tags security
|
||||
* external/cwe/cwe-321
|
||||
*/
|
||||
|
||||
import go
|
||||
import HardcodedKeysLib
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from HardcodedKeys::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "$@ is used to sign a JWT token.", source.getNode(),
|
||||
"Hardcoded String"
|
||||
9
go/ql/src/experimental/CWE-321/HardcodedKeysBad.go
Normal file
9
go/ql/src/experimental/CWE-321/HardcodedKeysBad.go
Normal file
@@ -0,0 +1,9 @@
|
||||
mySigningKey := []byte("AllYourBase")
|
||||
|
||||
claims := &jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Unix(1516239022, 0)),
|
||||
Issuer: "test",
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
ss, err := token.SignedString(mySigningKey)
|
||||
23
go/ql/src/experimental/CWE-321/HardcodedKeysGood.go
Normal file
23
go/ql/src/experimental/CWE-321/HardcodedKeysGood.go
Normal file
@@ -0,0 +1,23 @@
|
||||
func GenerateCryptoString(n int) (string, error) {
|
||||
const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
|
||||
ret := make([]byte, n)
|
||||
for i := range ret {
|
||||
num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars))))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ret[i] = chars[num.Int64()]
|
||||
}
|
||||
return string(ret), nil
|
||||
}
|
||||
|
||||
mySigningKey := GenerateCryptoString(64)
|
||||
|
||||
|
||||
claims := &jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Unix(1516239022, 0)),
|
||||
Issuer: "test",
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
ss, err := token.SignedString(mySigningKey)
|
||||
323
go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll
Normal file
323
go/ql/src/experimental/CWE-321/HardcodedKeysLib.qll
Normal file
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for reasoning about
|
||||
* JWT token signing vulnerabilities as well as extension points
|
||||
* for adding your own.
|
||||
*/
|
||||
|
||||
import go
|
||||
import StringOps
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for reasoning about
|
||||
* JWT token signing vulnerabilities as well as extension points
|
||||
* for adding your own.
|
||||
*/
|
||||
module HardcodedKeys {
|
||||
/**
|
||||
* A data flow source for JWT token signing vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for JWT token signing vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for JWT token signing vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer guard for JWT token signing vulnerabilities.
|
||||
*/
|
||||
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
private predicate isTestCode(Expr e) {
|
||||
e.getFile().getAbsolutePath().toLowerCase().matches("%test%") and
|
||||
not e.getFile().getAbsolutePath().toLowerCase().matches("%ql/test%")
|
||||
}
|
||||
|
||||
private predicate isDemoCode(Expr e) {
|
||||
e.getFile().getAbsolutePath().toLowerCase().matches(["%mock%", "%demo%", "%example%"])
|
||||
}
|
||||
|
||||
/**
|
||||
* A hardcoded string literal as a source for JWT token signing vulnerabilities.
|
||||
*/
|
||||
private class HardcodedStringSource extends Source {
|
||||
HardcodedStringSource() {
|
||||
this.asExpr() instanceof StringLit and
|
||||
not (isTestCode(this.asExpr()) or isDemoCode(this.asExpr()))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression used to sign JWT tokens as a sink for JWT token signing vulnerabilities.
|
||||
*/
|
||||
private class GolangJwtSign extends Sink {
|
||||
GolangJwtSign() {
|
||||
exists(string pkg |
|
||||
pkg =
|
||||
[
|
||||
"github.com/golang-jwt/jwt/v4", "github.com/dgrijalva/jwt-go",
|
||||
"github.com/form3tech-oss/jwt-go", "github.com/ory/fosite/token/jwt"
|
||||
]
|
||||
|
|
||||
exists(DataFlow::MethodCallNode m |
|
||||
// Models the `SignedString` method
|
||||
// `func (t *Token) SignedString(key interface{}) (string, error)`
|
||||
m.getTarget().hasQualifiedName(pkg, "Token", "SignedString") and
|
||||
this = m.getArgument(0)
|
||||
or
|
||||
// Model the `Sign` method of the `SigningMethod` interface
|
||||
// type SigningMethod interface {
|
||||
// Verify(signingString, signature string, key interface{}) error
|
||||
// Sign(signingString string, key interface{}) (string, error)
|
||||
// Alg() string
|
||||
// }
|
||||
m.getTarget().hasQualifiedName(pkg, "SigningMethod", "Sign") and
|
||||
this = m.getArgument(1)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class GinJwtSign extends Sink {
|
||||
GinJwtSign() {
|
||||
exists(Field f |
|
||||
// https://pkg.go.dev/github.com/appleboy/gin-jwt/v2#GinJWTMiddleware
|
||||
f.hasQualifiedName("github.com/appleboy/gin-jwt/v2", "GinJWTMiddleware", "Key") and
|
||||
f.getAWrite().getRhs() = this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class SquareJoseKey extends Sink {
|
||||
SquareJoseKey() {
|
||||
exists(Field f, string pkg |
|
||||
// type Recipient struct {
|
||||
// Algorithm KeyAlgorithm
|
||||
// Key interface{}
|
||||
// KeyID string
|
||||
// PBES2Count int
|
||||
// PBES2Salt []byte
|
||||
// }
|
||||
// type SigningKey struct {
|
||||
// Algorithm SignatureAlgorithm
|
||||
// Key interface{}
|
||||
// }
|
||||
f.hasQualifiedName(pkg, ["Recipient", "SigningKey"], "Key") and
|
||||
f.getAWrite().getRhs() = this
|
||||
|
|
||||
pkg = ["github.com/square/go-jose/v3", "gopkg.in/square/go-jose.v2"]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class CrystalHqJwtSigner extends Sink {
|
||||
CrystalHqJwtSigner() {
|
||||
exists(DataFlow::CallNode m |
|
||||
// `func NewSignerHS(alg Algorithm, key []byte) (Signer, error)`
|
||||
m.getTarget().hasQualifiedName("github.com/cristalhq/jwt/v3", "NewSignerHS")
|
||||
|
|
||||
this = m.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class GoKitJwt extends Sink {
|
||||
GoKitJwt() {
|
||||
exists(DataFlow::CallNode m |
|
||||
// `func NewSigner(kid string, key []byte, method jwt.SigningMethod, claims jwt.Claims) endpoint.Middleware`
|
||||
m.getTarget().hasQualifiedName("github.com/go-kit/kit/auth/jwt", "NewSigner")
|
||||
|
|
||||
this = m.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class LestrratJwk extends Sink {
|
||||
LestrratJwk() {
|
||||
exists(DataFlow::CallNode m, string pkg |
|
||||
pkg.matches([
|
||||
"github.com/lestrrat-go/jwx", "github.com/lestrrat/go-jwx/jwk",
|
||||
"github.com/lestrrat-go/jwx%/jwk"
|
||||
]) and
|
||||
// `func New(key interface{}) (Key, error)`
|
||||
m.getTarget().hasQualifiedName(pkg, "New")
|
||||
|
|
||||
this = m.getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes any other use of an operand to a comparison, on the assumption that this may filter
|
||||
* out special constant values -- for example, in context `if key != "invalid_key" { ... }`,
|
||||
* if `"invalid_key"` is indeed the only dangerous key then guarded uses of `key` are likely
|
||||
* to be safe.
|
||||
*
|
||||
* TODO: Before promoting this query look at replacing this with something more principled.
|
||||
*/
|
||||
private class CompareExprSanitizer extends Sanitizer {
|
||||
CompareExprSanitizer() {
|
||||
exists(ComparisonExpr c |
|
||||
c.getAnOperand().getGlobalValueNumber() = this.asExpr().getGlobalValueNumber() and
|
||||
not this.asExpr() instanceof Literal
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks anything returned with an error as a sanitized.
|
||||
*
|
||||
* Typically this means contexts like `return "", errors.New("Oh no")`,
|
||||
* where we can be reasonably confident downstream users won't mistake
|
||||
* that empty string for a usable key.
|
||||
*/
|
||||
private class ReturnedAlongsideErrorSanitizer extends Sanitizer {
|
||||
ReturnedAlongsideErrorSanitizer() {
|
||||
exists(ReturnStmt r, DataFlow::CallNode c |
|
||||
c.getTarget().hasQualifiedName("errors", "New") and
|
||||
r.getNumChild() > 1 and
|
||||
r.getAChild() = c.getAResult().getASuccessor*().asExpr() and
|
||||
r.getAChild() = this.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks anything returned alongside an error-value that is known
|
||||
* to be non-nil by virtue of a guarding check as harmless.
|
||||
*
|
||||
* For example, `if err != nil { return "", err }` is unlikely to be
|
||||
* contributing a dangerous hardcoded key.
|
||||
*/
|
||||
private class ReturnedAlongsideErrorSanitizerGuard extends Sanitizer {
|
||||
ReturnedAlongsideErrorSanitizerGuard() {
|
||||
exists(ControlFlow::ConditionGuardNode guard, SsaWithFields errorVar, ReturnStmt r |
|
||||
guard.ensuresNeq(errorVar.getAUse(), Builtin::nil().getARead()) and
|
||||
guard.dominates(this.getBasicBlock()) and
|
||||
r.getExpr(1) = errorVar.getAUse().asExpr() and
|
||||
this.asExpr() = r.getExpr(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Mark any formatting string call as a sanitizer */
|
||||
private class FormattingSanitizer extends Sanitizer {
|
||||
FormattingSanitizer() { exists(Formatting::StringFormatCall s | s.getAResult() = this) }
|
||||
}
|
||||
|
||||
private string getRandIntFunctionName() {
|
||||
result =
|
||||
[
|
||||
"ExpFloat64", "Float32", "Float64", "Int", "Int31", "Int31n", "Int63", "Int63n", "Intn",
|
||||
"NormFloat64", "Uint32", "Uint64"
|
||||
]
|
||||
}
|
||||
|
||||
private DataFlow::CallNode getARandIntCall() {
|
||||
result.getTarget().hasQualifiedName("math/rand", getRandIntFunctionName()) or
|
||||
result.getTarget().(Method).hasQualifiedName("math/rand", "Rand", getRandIntFunctionName()) or
|
||||
result.getTarget().hasQualifiedName("crypto/rand", "Int")
|
||||
}
|
||||
|
||||
private DataFlow::CallNode getARandReadCall() {
|
||||
result.getTarget().hasQualifiedName("crypto/rand", "Read")
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark any taint arising from a read on a tainted slice with a random index as a
|
||||
* sanitizer for all instances of the taint
|
||||
*/
|
||||
private class RandSliceSanitizer extends Sanitizer {
|
||||
RandSliceSanitizer() {
|
||||
exists(DataFlow::Node randomValue, DataFlow::Node index |
|
||||
// Sanitize flows like this:
|
||||
// func GenerateCryptoString(n int) (string, error) {
|
||||
// const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
|
||||
// ret := make([]byte, n)
|
||||
// for i := range ret {
|
||||
// num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars))))
|
||||
// if err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
// ret[i] = chars[num.Int64()]
|
||||
// }
|
||||
// return string(ret), nil
|
||||
// }
|
||||
randomValue = getARandIntCall().getAResult()
|
||||
or
|
||||
// Sanitize flows like :
|
||||
// func GenerateRandomString(size int) string {
|
||||
// var bytes = make([]byte, size)
|
||||
// rand.Read(bytes)
|
||||
// for i, x := range bytes {
|
||||
// bytes[i] = characters[x%byte(len(characters))]
|
||||
// }
|
||||
// return string(bytes)
|
||||
// }
|
||||
randomValue =
|
||||
any(DataFlow::PostUpdateNode pun |
|
||||
pun.getPreUpdateNode() = getARandReadCall().getArgument(0)
|
||||
)
|
||||
|
|
||||
TaintTracking::localTaint(randomValue, index) and
|
||||
this.(DataFlow::ElementReadNode).reads(_, index)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Models flow from a call to `Int64` if the receiver is tainted
|
||||
*/
|
||||
private class BigIntFlow extends TaintTracking::FunctionModel {
|
||||
BigIntFlow() { this.(Method).hasQualifiedName("math/big", "Int", "Int64") }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp.isReceiver() and
|
||||
outp.isResult(0)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Models taint flow through a binary operation such as a
|
||||
* modulo `%` operation or an addition `+` operation
|
||||
*/
|
||||
|
||||
private class BinExpAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
|
||||
// This is required to model the sanitizers for the `HardcodedKeys` query.
|
||||
// This is required to correctly detect a sanitizer such as the one shown below.
|
||||
// func GenerateRandomString(size int) string {
|
||||
// var bytes = make([]byte, size)
|
||||
// rand.Read(bytes)
|
||||
// for i, x := range bytes {
|
||||
// bytes[i] = characters[x%byte(len(characters))]
|
||||
// }
|
||||
// return string(bytes)
|
||||
// }
|
||||
override predicate step(DataFlow::Node prev, DataFlow::Node succ) {
|
||||
exists(BinaryExpr b | b.getAnOperand() = prev.asExpr() | succ.asExpr() = b)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A configuration depicting taint flow for studying JWT token signing vulnerabilities.
|
||||
*/
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "Hard-coded JWT Signing Key" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof Source }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof Sanitizer }
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof SanitizerGuard
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 0.1.3
|
||||
version: 0.1.4-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
private import InlineExpectationsTestPrivate
|
||||
|
||||
/**
|
||||
* Base class for tests with inline expectations. The test extends this class to provide the actual
|
||||
* The base class for tests with inline expectations. The test extends this class to provide the actual
|
||||
* results of the query, which are then compared with the expected results in comments to produce a
|
||||
* list of failure messages that point out where the actual results differ from the expected
|
||||
* results.
|
||||
@@ -121,11 +121,17 @@ abstract class InlineExpectationsTest extends string {
|
||||
* - `value` - The value of the result, which will be matched against the value associated with
|
||||
* `tag` in any expected result comment on that line.
|
||||
*/
|
||||
abstract predicate hasActualResult(string file, int line, string element, string tag, string value);
|
||||
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
this.hasActualResult(location.getFile().getAbsolutePath(), location.getStartLine(), element,
|
||||
tag, value)
|
||||
/**
|
||||
* Holds if there is an optional result on the specified location.
|
||||
*
|
||||
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
|
||||
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
||||
* Override this predicate to specify optional results.
|
||||
*/
|
||||
predicate hasOptionalResult(Location location, string element, string tag, string value) {
|
||||
none()
|
||||
}
|
||||
|
||||
final predicate hasFailureMessage(FailureLocatable element, string message) {
|
||||
@@ -139,13 +145,14 @@ abstract class InlineExpectationsTest extends string {
|
||||
)
|
||||
or
|
||||
not exists(ValidExpectation expectation | expectation.matchesActualResult(actualResult)) and
|
||||
message = "Unexpected result: " + actualResult.getExpectationText()
|
||||
message = "Unexpected result: " + actualResult.getExpectationText() and
|
||||
not actualResult.isOptional()
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(ValidExpectation expectation |
|
||||
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
|
||||
expectation.getTag() = this.getARelevantTag() and
|
||||
expectation.getTag() = getARelevantTag() and
|
||||
element = expectation and
|
||||
(
|
||||
expectation instanceof GoodExpectation and
|
||||
@@ -174,7 +181,7 @@ private string expectationCommentPattern() { result = "\\s*\\$((?:[^/]|/[^/])*)(
|
||||
/**
|
||||
* The possible columns in an expectation comment. The `TDefaultColumn` branch represents the first
|
||||
* column in a comment. This column is not precedeeded by a name. `TNamedColumn(name)` represents a
|
||||
* column containing expected results preceeded by the string `name:`.
|
||||
* column containing expected results preceded by the string `name:`.
|
||||
*/
|
||||
private newtype TColumn =
|
||||
TDefaultColumn() or
|
||||
@@ -248,9 +255,13 @@ private string expectationPattern() {
|
||||
|
||||
private newtype TFailureLocatable =
|
||||
TActualResult(
|
||||
InlineExpectationsTest test, Location location, string element, string tag, string value
|
||||
InlineExpectationsTest test, Location location, string element, string tag, string value,
|
||||
boolean optional
|
||||
) {
|
||||
test.hasActualResult(location, element, tag, value)
|
||||
test.hasActualResult(location, element, tag, value) and
|
||||
optional = false
|
||||
or
|
||||
test.hasOptionalResult(location, element, tag, value) and optional = true
|
||||
} or
|
||||
TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
|
||||
exists(TColumn column, string tags |
|
||||
@@ -269,7 +280,7 @@ class FailureLocatable extends TFailureLocatable {
|
||||
|
||||
Location getLocation() { none() }
|
||||
|
||||
final string getExpectationText() { result = this.getTag() + "=" + this.getValue() }
|
||||
final string getExpectationText() { result = getTag() + "=" + getValue() }
|
||||
|
||||
string getTag() { none() }
|
||||
|
||||
@@ -282,8 +293,9 @@ class ActualResult extends FailureLocatable, TActualResult {
|
||||
string element;
|
||||
string tag;
|
||||
string value;
|
||||
boolean optional;
|
||||
|
||||
ActualResult() { this = TActualResult(test, location, element, tag, value) }
|
||||
ActualResult() { this = TActualResult(test, location, element, tag, value, optional) }
|
||||
|
||||
override string toString() { result = element }
|
||||
|
||||
@@ -294,6 +306,8 @@ class ActualResult extends FailureLocatable, TActualResult {
|
||||
override string getTag() { result = tag }
|
||||
|
||||
override string getValue() { result = value }
|
||||
|
||||
predicate isOptional() { optional = true }
|
||||
}
|
||||
|
||||
abstract private class Expectation extends FailureLocatable {
|
||||
@@ -318,24 +332,24 @@ private class ValidExpectation extends Expectation, TValidExpectation {
|
||||
string getKnownFailure() { result = knownFailure }
|
||||
|
||||
predicate matchesActualResult(ActualResult actualResult) {
|
||||
this.getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
|
||||
this.getLocation().getFile() = actualResult.getLocation().getFile() and
|
||||
this.getTag() = actualResult.getTag() and
|
||||
this.getValue() = actualResult.getValue()
|
||||
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
|
||||
getLocation().getFile() = actualResult.getLocation().getFile() and
|
||||
getTag() = actualResult.getTag() and
|
||||
getValue() = actualResult.getValue()
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: These next three classes correspond to all the possible values of type `TColumn`. */
|
||||
class GoodExpectation extends ValidExpectation {
|
||||
GoodExpectation() { this.getKnownFailure() = "" }
|
||||
GoodExpectation() { getKnownFailure() = "" }
|
||||
}
|
||||
|
||||
class FalsePositiveExpectation extends ValidExpectation {
|
||||
FalsePositiveExpectation() { this.getKnownFailure() = "SPURIOUS" }
|
||||
FalsePositiveExpectation() { getKnownFailure() = "SPURIOUS" }
|
||||
}
|
||||
|
||||
class FalseNegativeExpectation extends ValidExpectation {
|
||||
FalseNegativeExpectation() { this.getKnownFailure() = "MISSING" }
|
||||
FalseNegativeExpectation() { getKnownFailure() = "MISSING" }
|
||||
}
|
||||
|
||||
class InvalidExpectation extends Expectation, TInvalidExpectation {
|
||||
|
||||
@@ -76,10 +76,11 @@ class InlineFlowTest extends InlineExpectationsTest {
|
||||
|
||||
override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | getValueFlowConfig().hasFlow(src, sink) |
|
||||
sink.hasLocationInfo(file, line, _, _, _) and
|
||||
sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
element = sink.toString() and
|
||||
value = "\"" + sink.toString() + "\""
|
||||
)
|
||||
@@ -88,7 +89,8 @@ class InlineFlowTest extends InlineExpectationsTest {
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
getTaintFlowConfig().hasFlow(src, sink) and not getValueFlowConfig().hasFlow(src, sink)
|
||||
|
|
||||
sink.hasLocationInfo(file, line, _, _, _) and
|
||||
sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
element = sink.toString() and
|
||||
value = "\"" + sink.toString() + "\""
|
||||
)
|
||||
|
||||
1
go/ql/test/experimental/CWE-285/PamAuthBypass.expected
Normal file
1
go/ql/test/experimental/CWE-285/PamAuthBypass.expected
Normal file
@@ -0,0 +1 @@
|
||||
| main.go:10:2:12:3 | ... := ...[0] | This Pam transaction may not be secure. |
|
||||
1
go/ql/test/experimental/CWE-285/PamAuthBypass.qlref
Normal file
1
go/ql/test/experimental/CWE-285/PamAuthBypass.qlref
Normal file
@@ -0,0 +1 @@
|
||||
experimental/CWE-285/PamAuthBypass.ql
|
||||
5
go/ql/test/experimental/CWE-285/go.mod
Normal file
5
go/ql/test/experimental/CWE-285/go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module main
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/msteinert/pam v1.0.0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user