Skip to content

Improve CQL Injection Query #200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ac0265e
Minor readability
jeongsoolee09 Jun 17, 2025
6fd6b2a
Make definition of `ImplMethodCallApplicationServiceDefinition` more …
jeongsoolee09 Jun 17, 2025
439ad43
Add `srv.entities` as part of `EntityEntry`
jeongsoolee09 Jun 17, 2025
3b7d741
Put CQL query-relevant definitions in a query library
jeongsoolee09 Jun 17, 2025
440712f
Do some refactoring
jeongsoolee09 Jun 19, 2025
dfa8c08
Sort out EntityReference
jeongsoolee09 Jun 19, 2025
571b316
Create a new CQL injection test project and move the old one to a folder
jeongsoolee09 Jun 20, 2025
1262260
Minor numbering
jeongsoolee09 Jun 20, 2025
908a572
install `@sap/cds-dk` and bump version of `@sap/cds`
jeongsoolee09 Jun 20, 2025
a8a0bb4
Move existing CQL Injection test case to `old/`
jeongsoolee09 Jun 23, 2025
5e39be5
Refine test cases and add more cases
jeongsoolee09 Jun 23, 2025
25450a8
Finalize working draft on current CqlInjection test case
jeongsoolee09 Jun 23, 2025
0f95069
Finalize CqlInjection
jeongsoolee09 Jun 23, 2025
1e83f5a
Fix test case and code
jeongsoolee09 Jun 24, 2025
9a2e99b
Appease compiler to make SensitiveExposure pass
jeongsoolee09 Jun 24, 2025
c5c9740
Debug `isSink`
jeongsoolee09 Jun 24, 2025
89522d0
Cover all cases in the current CQL injection test
jeongsoolee09 Jun 24, 2025
43738d5
Get the query depending on the type of sink
jeongsoolee09 Jun 24, 2025
13691d4
Minor formatting and tidying up
jeongsoolee09 Jun 24, 2025
468a780
Docstrings and comments
jeongsoolee09 Jun 24, 2025
a391d34
Fix a regression in `taintedclause`
jeongsoolee09 Jun 24, 2025
39b2397
Update expected test outputs of old cqlinjection.js
jeongsoolee09 Jun 24, 2025
fd0d13a
Fix a regression in applicationserviceinstance
jeongsoolee09 Jun 24, 2025
621a319
Fix regression in SensitiveExposure
jeongsoolee09 Jun 24, 2025
a0f6d9a
Remove unneeded code
jeongsoolee09 Jun 24, 2025
7652149
Update expected results of sensitive-exposure
jeongsoolee09 Jun 24, 2025
2e56ae0
Fix numbering and remove duplicate case
jeongsoolee09 Jun 24, 2025
a13a825
Make the new CQL injection test project a proper test case and remove…
jeongsoolee09 Jun 24, 2025
8a99661
Remove unneeded comment
jeongsoolee09 Jun 24, 2025
5c1a5ba
Checkpoint
jeongsoolee09 Jun 26, 2025
a93a7b1
Add some more unit test cases
jeongsoolee09 Jun 26, 2025
d968632
Add some more cases and add FP tags
jeongsoolee09 Jun 26, 2025
fb979d2
Remove the old CQL injection test files
jeongsoolee09 Jun 26, 2025
bdfc5bd
Add FP cases that are left out in the previous commit.
jeongsoolee09 Jun 26, 2025
0004b88
Debug query according to the new test cases
jeongsoolee09 Jun 26, 2025
f0bb40c
Add expected test result of new CQL injection test
jeongsoolee09 Jun 26, 2025
8a6e11d
Update test results of sensitive-exposure
jeongsoolee09 Jun 26, 2025
18ef3b5
Update expected analysis results
jeongsoolee09 Jun 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import javascript
import semmle.javascript.security.dataflow.SqlInjectionCustomizations
import advanced_security.javascript.frameworks.cap.CQL
import advanced_security.javascript.frameworks.cap.RemoteFlowSources
import advanced_security.javascript.frameworks.cap.dataflow.FlowSteps

class CqlClauseWithStringConcatParameter instanceof CqlClause {
CqlClauseWithStringConcatParameter() {
exists(DataFlow::Node queryParameter |
(
if this instanceof CqlInsertClause or this instanceof CqlUpsertClause
then
queryParameter = this.getArgument().flow() or
queryParameter = this.getArgument().flow().(SourceNode).getAPropertyWrite().getRhs()
else queryParameter = this.getArgument().flow()
) and
exists(StringConcatenation::getAnOperand(queryParameter))
)
}

Location getLocation() { result = super.getLocation() }

string toString() { result = super.toString() }
}

class CqlShortcutMethodCallWithStringConcat instanceof CqlShortcutMethodCall {
CqlShortcutMethodCallWithStringConcat() {
exists(StringConcatenation::getAnOperand(super.getAQueryParameter()))
}

Location getLocation() { result = super.getLocation() }

string toString() { result = super.toString() }
}

class CqlClauseParserCallWithStringConcat instanceof CqlClauseParserCall {
CqlClauseParserCallWithStringConcat() {
exists(StringConcatenation::getAnOperand(super.getCdlString()))
}

Location getLocation() { result = super.getLocation() }

string toString() { result = super.toString() }
}

class CqlInjectionConfiguration extends TaintTracking::Configuration {
CqlInjectionConfiguration() { this = "CQL injection from untrusted data" }

override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }

override predicate isSink(DataFlow::Node node) {
exists(CqlRunMethodCall cqlRunMethodCall |
node = cqlRunMethodCall.(CqlRunMethodCall).getAQueryParameter()
)
or
exists(CqlShortcutMethodCallWithStringConcat queryRunnerCall |
node = queryRunnerCall.(CqlQueryRunnerCall).getAQueryParameter()
)
or
exists(AwaitExpr await, CqlClauseWithStringConcatParameter cqlClauseWithStringConcat |
node = await.flow() and
await.getOperand() = cqlClauseWithStringConcat.(CqlClause).getArgument()
)
}

override predicate isSanitizer(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer }

override predicate isAdditionalTaintStep(DataFlow::Node start, DataFlow::Node end) {
exists(CqlClauseParserCallWithStringConcat cqlParseCallWithStringConcat |
start = cqlParseCallWithStringConcat.(CqlClauseParserCall).getAnArgument() and
end = cqlParseCallWithStringConcat
)
or
exists(CqlClause cqlClause |
start = cqlClause.getArgument().flow() and
end = cqlClause.flow()
)
}
}
Loading
Loading