Skip to content

Commit 1d83479

Browse files
authored
Merge pull request #10114 from RasmusWL/shared-http-client-request
Ruby/Python: Shared HTTP client request concept
2 parents 9a923d8 + 7895a58 commit 1d83479

File tree

23 files changed

+5089
-533
lines changed

23 files changed

+5089
-533
lines changed

config/identical-files.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll",
3131
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll",
3232
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll",
33+
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll",
3334
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll"
3435
],
3536
"DataFlow Java/C++/C#/Python Common": [

javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,70 @@ module Cryptography {
8787
predicate isWeak() { this = "ECB" }
8888
}
8989
}
90+
91+
/** Provides classes for modeling HTTP-related APIs. */
92+
module Http {
93+
/** Provides classes for modeling HTTP clients. */
94+
module Client {
95+
/**
96+
* A data-flow node that makes an outgoing HTTP request.
97+
*
98+
* Extend this class to refine existing API models. If you want to model new APIs,
99+
* extend `Http::Client::Request::Range` instead.
100+
*/
101+
class Request extends DataFlow::Node instanceof Request::Range {
102+
/**
103+
* Gets a data-flow node that contributes to the URL of the request.
104+
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
105+
*/
106+
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
107+
108+
/** Gets a string that identifies the framework used for this request. */
109+
string getFramework() { result = super.getFramework() }
110+
111+
/**
112+
* Holds if this request is made using a mode that disables SSL/TLS
113+
* certificate validation, where `disablingNode` represents the point at
114+
* which the validation was disabled, and `argumentOrigin` represents the origin
115+
* of the argument that disabled the validation (which could be the same node as
116+
* `disablingNode`).
117+
*/
118+
predicate disablesCertificateValidation(
119+
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
120+
) {
121+
super.disablesCertificateValidation(disablingNode, argumentOrigin)
122+
}
123+
}
124+
125+
/** Provides a class for modeling new HTTP requests. */
126+
module Request {
127+
/**
128+
* A data-flow node that makes an outgoing HTTP request.
129+
*
130+
* Extend this class to model new APIs. If you want to refine existing API models,
131+
* extend `Http::Client::Request` instead.
132+
*/
133+
abstract class Range extends DataFlow::Node {
134+
/**
135+
* Gets a data-flow node that contributes to the URL of the request.
136+
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
137+
*/
138+
abstract DataFlow::Node getAUrlPart();
139+
140+
/** Gets a string that identifies the framework used for this request. */
141+
abstract string getFramework();
142+
143+
/**
144+
* Holds if this request is made using a mode that disables SSL/TLS
145+
* certificate validation, where `disablingNode` represents the point at
146+
* which the validation was disabled, and `argumentOrigin` represents the origin
147+
* of the argument that disabled the validation (which could be the same node as
148+
* `disablingNode`).
149+
*/
150+
abstract predicate disablesCertificateValidation(
151+
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
152+
);
153+
}
154+
}
155+
}
156+
}

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,71 +1046,9 @@ module HTTP {
10461046
}
10471047
}
10481048

1049-
/** Provides classes for modeling HTTP clients. */
1050-
module Client {
1051-
/**
1052-
* A data-flow node that makes an outgoing HTTP request.
1053-
*
1054-
* Extend this class to refine existing API models. If you want to model new APIs,
1055-
* extend `HTTP::Client::Request::Range` instead.
1056-
*/
1057-
class Request extends DataFlow::Node instanceof Request::Range {
1058-
/**
1059-
* Gets a data-flow node that contributes to the URL of the request.
1060-
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
1061-
*/
1062-
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
1063-
1064-
/** Gets a string that identifies the framework used for this request. */
1065-
string getFramework() { result = super.getFramework() }
1066-
1067-
/**
1068-
* Holds if this request is made using a mode that disables SSL/TLS
1069-
* certificate validation, where `disablingNode` represents the point at
1070-
* which the validation was disabled, and `argumentOrigin` represents the origin
1071-
* of the argument that disabled the validation (which could be the same node as
1072-
* `disablingNode`).
1073-
*/
1074-
predicate disablesCertificateValidation(
1075-
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
1076-
) {
1077-
super.disablesCertificateValidation(disablingNode, argumentOrigin)
1078-
}
1079-
}
1080-
1081-
/** Provides a class for modeling new HTTP requests. */
1082-
module Request {
1083-
/**
1084-
* A data-flow node that makes an outgoing HTTP request.
1085-
*
1086-
* Extend this class to model new APIs. If you want to refine existing API models,
1087-
* extend `HTTP::Client::Request` instead.
1088-
*/
1089-
abstract class Range extends DataFlow::Node {
1090-
/**
1091-
* Gets a data-flow node that contributes to the URL of the request.
1092-
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
1093-
*/
1094-
abstract DataFlow::Node getAUrlPart();
1095-
1096-
/** Gets a string that identifies the framework used for this request. */
1097-
abstract string getFramework();
1098-
1099-
/**
1100-
* Holds if this request is made using a mode that disables SSL/TLS
1101-
* certificate validation, where `disablingNode` represents the point at
1102-
* which the validation was disabled, and `argumentOrigin` represents the origin
1103-
* of the argument that disabled the validation (which could be the same node as
1104-
* `disablingNode`).
1105-
*/
1106-
abstract predicate disablesCertificateValidation(
1107-
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
1108-
);
1109-
}
1110-
}
1111-
// TODO: investigate whether we should treat responses to client requests as
1112-
// remote-flow-sources in general.
1113-
}
1049+
import semmle.python.internal.ConceptsShared::Http::Client as Client
1050+
// TODO: investigate whether we should treat responses to client requests as
1051+
// remote-flow-sources in general.
11141052
}
11151053

11161054
/**

python/ql/lib/semmle/python/internal/ConceptsShared.qll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,70 @@ module Cryptography {
8787
predicate isWeak() { this = "ECB" }
8888
}
8989
}
90+
91+
/** Provides classes for modeling HTTP-related APIs. */
92+
module Http {
93+
/** Provides classes for modeling HTTP clients. */
94+
module Client {
95+
/**
96+
* A data-flow node that makes an outgoing HTTP request.
97+
*
98+
* Extend this class to refine existing API models. If you want to model new APIs,
99+
* extend `Http::Client::Request::Range` instead.
100+
*/
101+
class Request extends DataFlow::Node instanceof Request::Range {
102+
/**
103+
* Gets a data-flow node that contributes to the URL of the request.
104+
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
105+
*/
106+
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
107+
108+
/** Gets a string that identifies the framework used for this request. */
109+
string getFramework() { result = super.getFramework() }
110+
111+
/**
112+
* Holds if this request is made using a mode that disables SSL/TLS
113+
* certificate validation, where `disablingNode` represents the point at
114+
* which the validation was disabled, and `argumentOrigin` represents the origin
115+
* of the argument that disabled the validation (which could be the same node as
116+
* `disablingNode`).
117+
*/
118+
predicate disablesCertificateValidation(
119+
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
120+
) {
121+
super.disablesCertificateValidation(disablingNode, argumentOrigin)
122+
}
123+
}
124+
125+
/** Provides a class for modeling new HTTP requests. */
126+
module Request {
127+
/**
128+
* A data-flow node that makes an outgoing HTTP request.
129+
*
130+
* Extend this class to model new APIs. If you want to refine existing API models,
131+
* extend `Http::Client::Request` instead.
132+
*/
133+
abstract class Range extends DataFlow::Node {
134+
/**
135+
* Gets a data-flow node that contributes to the URL of the request.
136+
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
137+
*/
138+
abstract DataFlow::Node getAUrlPart();
139+
140+
/** Gets a string that identifies the framework used for this request. */
141+
abstract string getFramework();
142+
143+
/**
144+
* Holds if this request is made using a mode that disables SSL/TLS
145+
* certificate validation, where `disablingNode` represents the point at
146+
* which the validation was disabled, and `argumentOrigin` represents the origin
147+
* of the argument that disabled the validation (which could be the same node as
148+
* `disablingNode`).
149+
*/
150+
abstract predicate disablesCertificateValidation(
151+
DataFlow::Node disablingNode, DataFlow::Node argumentOrigin
152+
);
153+
}
154+
}
155+
}
156+
}

python/ql/src/Security/CWE-295/RequestWithoutValidation.ql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import python
1414
private import semmle.python.dataflow.new.DataFlow
1515
private import semmle.python.Concepts
16-
private import semmle.python.ApiGraphs
1716

1817
from
1918
HTTP::Client::Request request, DataFlow::Node disablingNode, DataFlow::Node origin, string ending
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* Changed the `HTTP::Client::Request` concept from using `MethodCall` as base class, to using `DataFlow::Node` as base class. Any class that extends `HTTP::Client::Request::Range` must be changed, but if you only use the member predicates of `HTTP::Client::Request`, no changes are required.

ruby/ql/lib/codeql/ruby/Concepts.qll

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -474,13 +474,15 @@ module HTTP {
474474

475475
/** Provides classes for modeling HTTP clients. */
476476
module Client {
477+
import codeql.ruby.internal.ConceptsShared::Http::Client as SC
478+
477479
/**
478480
* A method call that makes an outgoing HTTP request.
479481
*
480482
* Extend this class to refine existing API models. If you want to model new APIs,
481483
* extend `Request::Range` instead.
482484
*/
483-
class Request extends MethodCall instanceof Request::Range {
485+
class Request extends SC::Request instanceof Request::Range {
484486
/** Gets a node which returns the body of the response */
485487
DataFlow::Node getResponseBody() { result = super.getResponseBody() }
486488

@@ -490,24 +492,19 @@ module HTTP {
490492
* Gets a node that contributes to the URL of the request.
491493
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
492494
*/
493-
deprecated DataFlow::Node getURL() { result = super.getURL() or result = super.getAUrlPart() }
494-
495-
/**
496-
* Gets a data-flow node that contributes to the URL of the request.
497-
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
498-
*/
499-
DataFlow::Node getAUrlPart() { result = super.getAUrlPart() }
500-
501-
/** Gets a string that identifies the framework used for this request. */
502-
string getFramework() { result = super.getFramework() }
495+
deprecated DataFlow::Node getURL() {
496+
result = super.getURL() or result = Request::Range.super.getAUrlPart()
497+
}
503498

504499
/**
505500
* Holds if this request is made using a mode that disables SSL/TLS
506501
* certificate validation, where `disablingNode` represents the point at
507502
* which the validation was disabled.
508503
*/
509-
predicate disablesCertificateValidation(DataFlow::Node disablingNode) {
510-
super.disablesCertificateValidation(disablingNode)
504+
deprecated predicate disablesCertificateValidation(DataFlow::Node disablingNode) {
505+
Request::Range.super.disablesCertificateValidation(disablingNode, _)
506+
or
507+
Request::Range.super.disablesCertificateValidation(disablingNode)
511508
}
512509
}
513510

@@ -519,7 +516,7 @@ module HTTP {
519516
* Extend this class to model new APIs. If you want to refine existing API models,
520517
* extend `Request` instead.
521518
*/
522-
abstract class Range extends MethodCall {
519+
abstract class Range extends SC::Request::Range {
523520
/** Gets a node which returns the body of the response */
524521
abstract DataFlow::Node getResponseBody();
525522

@@ -532,20 +529,13 @@ module HTTP {
532529
deprecated DataFlow::Node getURL() { none() }
533530

534531
/**
535-
* Gets a data-flow node that contributes to the URL of the request.
536-
* Depending on the framework, a request may have multiple nodes which contribute to the URL.
537-
*/
538-
abstract DataFlow::Node getAUrlPart();
539-
540-
/** Gets a string that identifies the framework used for this request. */
541-
abstract string getFramework();
542-
543-
/**
532+
* DEPRECATED: override `disablesCertificateValidation/2` instead.
533+
*
544534
* Holds if this request is made using a mode that disables SSL/TLS
545535
* certificate validation, where `disablingNode` represents the point at
546536
* which the validation was disabled.
547537
*/
548-
abstract predicate disablesCertificateValidation(DataFlow::Node disablingNode);
538+
deprecated predicate disablesCertificateValidation(DataFlow::Node disablingNode) { none() }
549539
}
550540
}
551541

0 commit comments

Comments
 (0)