Skip to content

Commit c56c1cb

Browse files
authored
Merge pull request github#12588 from jketema/boost-config
C++: Refactor `BoostorgAsio` to use `DataFlow::ConfigSig`
2 parents 6639e5a + bbe9536 commit c56c1cb

File tree

4 files changed

+178
-28
lines changed

4 files changed

+178
-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: 161 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,43 @@ 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+
import Config
400+
}
401+
402+
import DataFlow::Make<C>
403+
}
404+
372405
/**
373406
* Any protocol value that flows to the first argument of a context constructor.
374407
*/
375-
class SslContextCallConfig extends SslContextCallAbstractConfig {
408+
deprecated class SslContextCallConfig extends SslContextCallAbstractConfig {
376409
SslContextCallConfig() { this = "SslContextCallConfig" }
377410

378411
override predicate isSource(DataFlow::Node source) {
@@ -383,10 +416,24 @@ module BoostorgAsio {
383416
}
384417
}
385418

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

392439
override predicate isSource(DataFlow::Node source) {
@@ -398,10 +445,25 @@ module BoostorgAsio {
398445
}
399446
}
400447

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

407469
override predicate isSource(DataFlow::Node source) {
@@ -413,10 +475,25 @@ module BoostorgAsio {
413475
}
414476
}
415477

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

422499
override predicate isSource(DataFlow::Node source) {
@@ -428,10 +505,25 @@ module BoostorgAsio {
428505
}
429506
}
430507

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

437529
override predicate isSource(DataFlow::Node source) {
@@ -443,10 +535,25 @@ module BoostorgAsio {
443535
}
444536
}
445537

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

452559
override predicate isSource(DataFlow::Node source) {
@@ -467,10 +574,34 @@ module BoostorgAsio {
467574
}
468575
}
469576

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

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

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)