Skip to content

Commit 9997326

Browse files
committed
C++: Refactor BoostorgAsio to use DataFlow::ConfigSig
1 parent 9aa83d7 commit 9997326

File tree

4 files changed

+182
-28
lines changed

4 files changed

+182
-28
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: deprecated
3+
---
4+
* The `SslContextCallAbstractConfig`, `SslContextCallConfig`, `SslContextCallBannedProtocolConfig`, `SslContextCallTls12ProtocolConfig`, `SslContextCallTls13ProtocolConfig`, `SslContextCallTlsProtocolConfig`, `SslContextFlowsToSetOptionConfig`, `SslOptionConfig` dataflow configurations from `BoostorgAsio` have been deprecated. Please use `SslContextCallConfigSig`, `SslContextCallMake`, `SslContextCallFlow`, `SslContextCallBannedProtocolFlow`, `SslContextCallTls12ProtocolFlow`, `SslContextCallTls13ProtocolFlow`, `SslContextCallTlsProtocolFlow`, `SslContextFlowsToSetOptionFlow`.

cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll

Lines changed: 165 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ module BoostorgAsio {
357357
* Abstract class for flows of protocol values to the first argument of a context
358358
* constructor.
359359
*/
360-
abstract class SslContextCallAbstractConfig extends DataFlow::Configuration {
360+
abstract deprecated class SslContextCallAbstractConfig extends DataFlow::Configuration {
361361
bindingset[this]
362362
SslContextCallAbstractConfig() { any() }
363363

@@ -369,10 +369,47 @@ module BoostorgAsio {
369369
}
370370
}
371371

372+
/**
373+
* Signature for flows of protocol values to the first argument of a context
374+
* constructor.
375+
*/
376+
signature module SslContextCallConfigSig {
377+
/**
378+
* Holds if `source` is a relevant data flow source.
379+
*/
380+
predicate isSource(DataFlow::Node source);
381+
382+
/**
383+
* Holds if `sink` is a relevant data flow sink.
384+
*/
385+
default predicate isSink(DataFlow::Node sink) {
386+
exists(ConstructorCall cc, SslContextClass c, Expr e | e = sink.asExpr() |
387+
c.getAContructorCall() = cc and
388+
cc.getArgument(0) = e
389+
)
390+
}
391+
}
392+
393+
/**
394+
* Constructs a standard data flow computation for protocol values to the first argument
395+
* of a context constructor.
396+
*/
397+
module SslContextCallMake<SslContextCallConfigSig Config> {
398+
private module C implements DataFlow::ConfigSig {
399+
predicate isSource = Config::isSource/1;
400+
401+
predicate isSink = Config::isSink/1;
402+
}
403+
404+
module F = DataFlow::Make<C>;
405+
406+
import F
407+
}
408+
372409
/**
373410
* Any protocol value that flows to the first argument of a context constructor.
374411
*/
375-
class SslContextCallConfig extends SslContextCallAbstractConfig {
412+
deprecated class SslContextCallConfig extends SslContextCallAbstractConfig {
376413
SslContextCallConfig() { this = "SslContextCallConfig" }
377414

378415
override predicate isSource(DataFlow::Node source) {
@@ -383,10 +420,24 @@ module BoostorgAsio {
383420
}
384421
}
385422

423+
/**
424+
* Any protocol value that flows to the first argument of a context constructor.
425+
*/
426+
private module SslContextCallConfig implements SslContextCallConfigSig {
427+
predicate isSource(DataFlow::Node source) {
428+
exists(Expr e | e = source.asExpr() |
429+
e.fromSource() and
430+
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
431+
)
432+
}
433+
}
434+
435+
module SslContextCallFlow = SslContextCallMake<SslContextCallConfig>;
436+
386437
/**
387438
* A banned protocol value that flows to the first argument of a context constructor.
388439
*/
389-
class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig {
440+
deprecated class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig {
390441
SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" }
391442

392443
override predicate isSource(DataFlow::Node source) {
@@ -398,10 +449,25 @@ module BoostorgAsio {
398449
}
399450
}
400451

452+
/**
453+
* A banned protocol value that flows to the first argument of a context constructor.
454+
*/
455+
private module SslContextCallBannedProtocolConfig implements SslContextCallConfigSig {
456+
predicate isSource(DataFlow::Node source) {
457+
exists(Expr e | e = source.asExpr() |
458+
e.fromSource() and
459+
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
460+
isExprBannedBoostProtocol(e)
461+
)
462+
}
463+
}
464+
465+
module SslContextCallBannedProtocolFlow = SslContextCallMake<SslContextCallBannedProtocolConfig>;
466+
401467
/**
402468
* A TLS 1.2 protocol value that flows to the first argument of a context constructor.
403469
*/
404-
class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig {
470+
deprecated class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig {
405471
SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
406472

407473
override predicate isSource(DataFlow::Node source) {
@@ -413,10 +479,25 @@ module BoostorgAsio {
413479
}
414480
}
415481

482+
/**
483+
* A TLS 1.2 protocol value that flows to the first argument of a context constructor.
484+
*/
485+
private module SslContextCallTls12ProtocolConfig implements SslContextCallConfigSig {
486+
predicate isSource(DataFlow::Node source) {
487+
exists(Expr e | e = source.asExpr() |
488+
e.fromSource() and
489+
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
490+
isExprTls12BoostProtocol(e)
491+
)
492+
}
493+
}
494+
495+
module SslContextCallTls12ProtocolFlow = SslContextCallMake<SslContextCallTls12ProtocolConfig>;
496+
416497
/**
417498
* A TLS 1.3 protocol value that flows to the first argument of a context constructor.
418499
*/
419-
class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig {
500+
deprecated class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig {
420501
SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" }
421502

422503
override predicate isSource(DataFlow::Node source) {
@@ -428,10 +509,25 @@ module BoostorgAsio {
428509
}
429510
}
430511

512+
/**
513+
* A TLS 1.3 protocol value that flows to the first argument of a context constructor.
514+
*/
515+
private module SslContextCallTls13ProtocolConfig implements SslContextCallConfigSig {
516+
predicate isSource(DataFlow::Node source) {
517+
exists(Expr e | e = source.asExpr() |
518+
e.fromSource() and
519+
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
520+
isExprTls13BoostProtocol(e)
521+
)
522+
}
523+
}
524+
525+
module SslContextCallTls13ProtocolFlow = SslContextCallMake<SslContextCallTls13ProtocolConfig>;
526+
431527
/**
432528
* A generic TLS protocol value that flows to the first argument of a context constructor.
433529
*/
434-
class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig {
530+
deprecated class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig {
435531
SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" }
436532

437533
override predicate isSource(DataFlow::Node source) {
@@ -443,10 +539,25 @@ module BoostorgAsio {
443539
}
444540
}
445541

542+
/**
543+
* A generic TLS protocol value that flows to the first argument of a context constructor.
544+
*/
545+
private module SslContextCallTlsProtocolConfig implements SslContextCallConfigSig {
546+
predicate isSource(DataFlow::Node source) {
547+
exists(Expr e | e = source.asExpr() |
548+
e.fromSource() and
549+
not e.getLocation().getFile().toString().matches("%/boost/asio/%") and
550+
isExprTlsBoostProtocol(e)
551+
)
552+
}
553+
}
554+
555+
module SslContextCallTlsProtocolFlow = SslContextCallMake<SslContextCallTlsProtocolConfig>;
556+
446557
/**
447558
* A context constructor call that flows to a call to `SetOptions()`.
448559
*/
449-
class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration {
560+
deprecated class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration {
450561
SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" }
451562

452563
override predicate isSource(DataFlow::Node source) {
@@ -467,10 +578,34 @@ module BoostorgAsio {
467578
}
468579
}
469580

581+
/**
582+
* A context constructor call that flows to a call to `SetOptions()`.
583+
*/
584+
private module SslContextFlowsToSetOptionConfig implements DataFlow::ConfigSig {
585+
predicate isSource(DataFlow::Node source) {
586+
exists(SslContextClass c, ConstructorCall cc |
587+
cc = source.asExpr() and
588+
c.getAContructorCall() = cc
589+
)
590+
}
591+
592+
predicate isSink(DataFlow::Node sink) {
593+
exists(FunctionCall fc, SslSetOptionsFunction f, Variable v, VariableAccess va |
594+
va = sink.asExpr()
595+
|
596+
f.getACallToThisFunction() = fc and
597+
v.getAnAccess() = va and
598+
va = fc.getQualifier()
599+
)
600+
}
601+
}
602+
603+
module SslContextFlowsToSetOptionFlow = DataFlow::Make<SslContextFlowsToSetOptionConfig>;
604+
470605
/**
471606
* An option value that flows to the first parameter of a call to `SetOptions()`.
472607
*/
473-
class SslOptionConfig extends DataFlow::Configuration {
608+
deprecated class SslOptionConfig extends DataFlow::Configuration {
474609
SslOptionConfig() { this = "SslOptionConfig" }
475610

476611
override predicate isSource(DataFlow::Node source) {
@@ -488,4 +623,26 @@ module BoostorgAsio {
488623
)
489624
}
490625
}
626+
627+
/**
628+
* An option value that flows to the first parameter of a call to `SetOptions()`.
629+
*/
630+
private module SslOptionConfig implements DataFlow::ConfigSig {
631+
predicate isSource(DataFlow::Node source) {
632+
exists(Expr e | e = source.asExpr() |
633+
e.fromSource() and
634+
not e.getLocation().getFile().toString().matches("%/boost/asio/%")
635+
)
636+
}
637+
638+
predicate isSink(DataFlow::Node sink) {
639+
exists(SslSetOptionsFunction f, FunctionCall call |
640+
sink.asExpr() = call.getArgument(0) and
641+
f.getACallToThisFunction() = call and
642+
not sink.getLocation().getFile().toString().matches("%/boost/asio/%")
643+
)
644+
}
645+
}
646+
647+
module SslOptionFlow = DataFlow::Make<SslOptionConfig>;
491648
}

cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
3333
ExistsAnyFlow::hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and
3434
exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions |
3535
contextSetOptions = fcSetOptions.getQualifier() and
36-
forall(
37-
Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig,
38-
Expr optionArgumentSource
39-
|
36+
forall(Expr optionArgument, Expr optionArgumentSource |
4037
optionArgument = fcSetOptions.getArgument(0) and
41-
optionArgConfig
42-
.hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument))
38+
BoostorgAsio::SslOptionFlow::hasFlow(DataFlow::exprNode(optionArgumentSource),
39+
DataFlow::exprNode(optionArgument))
4340
|
4441
optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag
4542
)
@@ -50,11 +47,10 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) {
5047
bindingset[flag]
5148
predicate isOptionNotSet(ConstructorCall cc, int flag) { not isOptionSet(cc, flag, _) }
5249

53-
from
54-
BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor, Expr protocolSource,
55-
Expr protocolSink, ConstructorCall cc, Expr e, string msg
50+
from Expr protocolSource, Expr protocolSink, ConstructorCall cc, Expr e, string msg
5651
where
57-
configConstructor.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and
52+
BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
53+
DataFlow::exprNode(protocolSink)) and
5854
cc.getArgument(0) = protocolSink and
5955
(
6056
BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and

cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@
1212
import cpp
1313
import semmle.code.cpp.security.boostorg.asio.protocols
1414

15-
from
16-
BoostorgAsio::SslContextCallConfig config, Expr protocolSource, Expr protocolSink,
17-
ConstructorCall cc
15+
from Expr protocolSource, Expr protocolSink, ConstructorCall cc
1816
where
19-
config.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and
20-
not exists(BoostorgAsio::SslContextCallTlsProtocolConfig tlsConfig |
21-
tlsConfig.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink))
22-
) and
17+
BoostorgAsio::SslContextCallFlow::hasFlow(DataFlow::exprNode(protocolSource),
18+
DataFlow::exprNode(protocolSink)) and
19+
not BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
20+
DataFlow::exprNode(protocolSink)) and
2321
cc.getArgument(0) = protocolSink and
24-
exists(BoostorgAsio::SslContextCallBannedProtocolConfig bannedConfig |
25-
bannedConfig.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink))
26-
)
22+
BoostorgAsio::SslContextCallBannedProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource),
23+
DataFlow::exprNode(protocolSink))
2724
select protocolSink, "Usage of $@ specifying a deprecated hardcoded protocol $@ in function $@.",
2825
cc, "boost::asio::ssl::context::context", protocolSource, protocolSource.toString(),
2926
cc.getEnclosingFunction(), cc.getEnclosingFunction().toString()

0 commit comments

Comments
 (0)