Skip to content

C++: Diff-informed queries: phase 3 (non-trivial locations) #20073

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 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
09daa56
[TEST] C++: CWE-020/ExternalAPI: add tests based on qlhelp (TODO: pro…
d10c Jul 15, 2025
b3db51e
[TEST] C++: CleartextSqliteDatabase: add new test
d10c Jul 15, 2025
cec225d
[DIFF-INFORMED] C++: OverflowDestination
d10c Jul 15, 2025
a955c36
[DIFF-INFORMED] C++: ConstantSizeArrayOffByOne
d10c Jul 15, 2025
72c8d9a
[DIFF-INFORMED] C++: DecompressionBombs
d10c Jul 15, 2025
47103cc
[DIFF-INFORMED] C++: NonConstantFormat
d10c Jul 15, 2025
553cf7f
[DIFF-INFORMED] C++: LeapYear
d10c Jul 16, 2025
bc1f71d
[DIFF-INFORMED] C++: (IR) ExternalAPIs
d10c Jul 16, 2025
f7a1cf0
[DIFF-INFORMED] C++: TaintedPath
d10c Jul 16, 2025
b5dcd86
[DIFF-INFORMED] C++: ExecTainted
d10c Jul 16, 2025
3751865
[DIFF-INFORMED] C++: CgiXss
d10c Jul 16, 2025
f43d062
[DIFF-INFORMED] C++: SqlTainted
d10c Jul 16, 2025
2621dc8
[DIFF-INFORMED] C++: UnboundedWrite
d10c Jul 16, 2025
6e2c11a
[DIFF-INFORMED] C++: ImproperNullTerminationTainted
d10c Jul 16, 2025
b4724e4
[DIFF-INFORMED] C++: CWE-190/ArithmeticTainted,etc.
d10c Jul 16, 2025
675b088
[DIFF-INFORMED] C++: AuthenticationBypass
d10c Jul 16, 2025
0d45ca0
[DIFF-INFORMED] C++: SSLResultConflation (has secondary config but pa…
d10c Jul 16, 2025
31d0113
[DIFF-INFORMED] C++: CWE-311/Cleartext…
d10c Jul 16, 2025
5c028b8
[DIFF-INFORMED] C++: CleartextSqliteDatabase
d10c Jul 16, 2025
8a9c1c1
[DIFF-INFORMED] C++: UseOfHttp
d10c Jul 16, 2025
9f003ba
[DIFF-INFORMED] C++: InsufficientKeySize
d10c Jul 16, 2025
616c918
[DIFF-INFORMED] C++: IteratorToExpiredContainer
d10c Jul 16, 2025
18a5787
[DIFF-INFORMED] C++: UnsafeCreateProcessCall
d10c Jul 16, 2025
96c5565
[DIFF-INFORMED] C++: UnsafeDaclSecurityDescriptor
d10c Jul 16, 2025
99612ea
[DIFF-INFORMED] C++: TaintedCondition
d10c Jul 16, 2025
46546b2
[DIFF-INFORMED] C++: TypeConfusion
d10c Jul 16, 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
10 changes: 10 additions & 0 deletions cpp/ql/src/Critical/OverflowDestination.ql
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ module OverflowDestinationConfig implements DataFlow::ConfigSig {
nodeIsBarrierEqualityCandidate(node, access, checkedVar)
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) { none() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(FunctionCall fc | result = fc.getLocation() |
sourceSized(fc, sink.asIndirectConvertedExpr())
)
}
}

module OverflowDestination = TaintTracking::Global<OverflowDestinationConfig>;
Expand Down
13 changes: 13 additions & 0 deletions cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,19 @@ module NonConstFlowConfig implements DataFlow::ConfigSig {
cannotContainString(t)
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) { none() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
exists(FormattingFunctionCall call, Expr formatString | result = call.getLocation() |
isSinkImpl(sink, formatString) and
call.getArgument(call.getFormatParameterIndex()) = formatString
)
}
}

module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>;
Expand Down
12 changes: 12 additions & 0 deletions cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ private module LeapYearCheckConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(ChecksForLeapYearFunctionCall fc | sink.asExpr() = fc.getAnArgument())
}

predicate observeDiffInformedIncrementalMode() {
none() // only used negatively in UncheckedLeapYearAfterYearModification.ql
}
}

module LeapYearCheckFlow = DataFlow::Global<LeapYearCheckConfig>;
Expand Down Expand Up @@ -285,6 +289,14 @@ private module PossibleYearArithmeticOperationCheckConfig implements DataFlow::C
aexpr.getLValue() = fa
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) {
result = source.asExpr().getLocation()
}

Location getASelectedSinkLocation(DataFlow::Node sink) { result = sink.asExpr().getLocation() }
}

module PossibleYearArithmeticOperationCheckFlow =
Expand Down
4 changes: 4 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
}

predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }

predicate observeDiffInformedIncrementalMode() {
none() // risky since used in library: normal use in UntrustedDataToExternalApi.ql; used via ExternalApiUsedWithUntrustedData (no location) in CountUntrustedDataToExternalAPI.ql
}
}

module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExternalApiConfig>;
4 changes: 4 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }

predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode }

predicate observeDiffInformedIncrementalMode() {
none() // risky since used in library: normal use in IRUntrustedDataToExternalApi.ql; used via ExternalApiUsedWithUntrustedData (no location) in IRCountUntrustedDataToExternalAPI.ql
}
}

module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExternalApiConfig>;
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ module TaintedPathConfig implements DataFlow::ConfigSig {
// make sinks barriers so that we only report the closest instance
isSink(node)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.asIndirectArgument().getLocation()
}
}

module TaintedPath = TaintTracking::Global<TaintedPathConfig>;
Expand Down
11 changes: 11 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ module ExecTaintConfig implements DataFlow::StateConfigSig {
predicate isBarrierOut(DataFlow::Node node) {
isSink(node, _) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(DataFlow::Node concatResult, Expr command, ExecState state |
result = [concatResult.getLocation(), command.getLocation()] and
isSink(sink, state) and
isSinkImpl(sink, command, _) and
concatResult = state.getOutgoingNode()
)
}
}

module ExecTaint = TaintTracking::GlobalWithState<ExecTaintConfig>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ module Config implements DataFlow::ConfigSig {
or
node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) {
exists(QueryString query | result = query.getLocation() | query = source.asIndirectExpr())
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
sql.barrierSqlArgument(input, _)
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(Expr taintedArg | result = taintedArg.getLocation() | taintedArg = asSinkExpr(sink))
}
}

module SqlTainted = TaintTracking::Global<SqlTaintedConfig>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ module Config implements DataFlow::ConfigSig {
// Block flow if the node is guarded by any <, <= or = operations.
node = DataFlow::BarrierGuard<lessThanOrEqual/3>::getABarrierNode()
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(BufferWrite bw | result = bw.getLocation() | isSink(sink, bw, _))
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ private module Config implements DataFlow::ConfigSig {
}

predicate isSink(DataFlow::Node sink) { isSink(sink, _) }

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(VariableAccess va | result = va.getLocation() | isSink(sink, va))
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ module Config implements DataFlow::ConfigSig {
not iTo instanceof PointerArithmeticInstruction
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(Expr e | result = e.getLocation() | isSink(sink, _, e))
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ module UncontrolledArithConfig implements DataFlow::ConfigSig {
// block unintended flow to pointers
node.asExpr().getUnspecifiedType() instanceof PointerType
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) {
result = getExpr(source).getLocation()
}
}

module UncontrolledArith = TaintTracking::Global<UncontrolledArithConfig>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ module Config implements DataFlow::ConfigSig {
not iTo instanceof PointerArithmeticInstruction
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(VariableAccess va | result = va.getLocation() | isSink(sink, va, _))
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ module TaintedAllocationSizeConfig implements DataFlow::ConfigSig {
// to duplicate results)
any(HeuristicAllocationFunction f).getAParameter() = node.asParameter()
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(Expr alloc | result = alloc.getLocation() | allocSink(alloc, sink))
}
}

module TaintedAllocationSize = TaintTracking::Global<TaintedAllocationSizeConfig>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-290/AuthenticationBypass.ql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSource(source, _) }

predicate isSink(DataFlow::Node sink) { isSink(sink, _) }

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(Expr condition | result = condition.getLocation() | isSink(sink, condition))
}
}

module Flow = TaintTracking::Global<Config>;
Expand Down
8 changes: 8 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ module VerifyResultConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
exists(GuardCondition guard | guard.getAChild*() = sink.asExpr())
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(GuardCondition guard | result = guard.getLocation() |
guard.comparesEq(sink.asExpr(), _, 0, false, _)
)
}
}

module VerifyResult = DataFlow::Global<VerifyResultConfig>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ module ToBufferConfig implements DataFlow::ConfigSig {
}

predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(SensitiveBufferWrite w | result = w.getLocation() | isSinkImpl(sink, w))
}
}

module ToBufferFlow = TaintTracking::Global<ToBufferConfig>;
Expand Down
10 changes: 10 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) {
node.asExpr().getUnspecifiedType() instanceof IntegralType
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node sourceNode) {
exists(SensitiveExpr source | result = source.getLocation() | isSourceImpl(sourceNode, source))
}

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(FileWrite w | result = w.getLocation() | isSinkImpl(sink, w, _))
}
}

module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>;
Expand Down
16 changes: 16 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ module FromSensitiveConfig implements DataFlow::ConfigSig {
// sources to not get path duplication.
isSource(node)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(NetworkSendRecv networkSendRecv | result = networkSendRecv.getLocation() |
isSinkSendRecv(sink, networkSendRecv)
)
}
}

module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>;
Expand All @@ -266,6 +274,10 @@ module ToEncryptionConfig implements DataFlow::ConfigSig {
// sources to not get path duplication.
isSource(node)
}

predicate observeDiffInformedIncrementalMode() {
none() // only used negatively
}
}

module ToEncryptionFlow = TaintTracking::Global<ToEncryptionConfig>;
Expand All @@ -281,6 +293,10 @@ module FromEncryptionConfig implements DataFlow::ConfigSig {
predicate isBarrier(DataFlow::Node node) {
node.asExpr().getUnspecifiedType() instanceof IntegralType
}

predicate observeDiffInformedIncrementalMode() {
none() // only used negatively
}
}

module FromEncryptionFlow = TaintTracking::Global<FromEncryptionConfig>;
Expand Down
14 changes: 14 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,20 @@ module FromSensitiveConfig implements DataFlow::ConfigSig {
content.(DataFlow::FieldContent).getField() = getRecField(t.stripType())
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) {
exists(SensitiveExpr sensitive | result = sensitive.getLocation() |
isSourceImpl(source, sensitive)
)
}

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(SqliteFunctionCall sqliteCall | result = sqliteCall.getLocation() |
isSinkImpl(sink, sqliteCall, _)
)
}
}

module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>;
Expand Down
8 changes: 8 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ module HttpStringToUrlOpenConfig implements DataFlow::ConfigSig {
sink.asIndirectExpr() = fc.getArgument(3)
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) {
result = source.asIndirectExpr().getLocation()
}

Location getASelectedSinkLocation(DataFlow::Node sink) { none() }
}

module HttpStringToUrlOpen = TaintTracking::Global<HttpStringToUrlOpenConfig>;
Expand Down
6 changes: 6 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ module KeyStrengthFlowConfig implements DataFlow::ConfigSig {
exists(getMinimumKeyStrength(name, param))
)
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(FunctionCall fc | result = fc.getLocation() | sink.asExpr() = fc.getArgument(_))
}
}

module KeyStrengthFlow = DataFlow::Global<KeyStrengthFlowConfig>;
Expand Down
12 changes: 12 additions & 0 deletions cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ module Config implements DataFlow::StateConfigSig {
// ```
result instanceof DataFlow::FeatureHasSinkCallContext
}

predicate observeDiffInformedIncrementalMode() { any() }

Location getASelectedSourceLocation(DataFlow::Node source) { none() }

Location getASelectedSinkLocation(DataFlow::Node sink) {
exists(DataFlow::Node mid, FlowState state | result = mid.getLocation() |
destroyedToBeginSink(sink) and
isSink(sink, state) and
state = Config::DestroyedToBegin(mid)
)
}
}

module Flow = DataFlow::GlobalWithState<Config>;
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy