Merge branch 'master' of github.com:github/codeql into SharedDataflow_Classes

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-08-11 07:24:17 +02:00
95 changed files with 4416 additions and 689 deletions

View File

@@ -0,0 +1,19 @@
# Improvements to C/C++ analysis
The following changes in version 1.26 affect C/C++ analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
## Changes to libraries

View File

@@ -0,0 +1,30 @@
# Improvements to JavaScript analysis
## General improvements
* Support for the following frameworks and libraries has been improved:
- [fast-json-stable-stringify](https://www.npmjs.com/package/fast-json-stable-stringify)
- [fast-safe-stringify](https://www.npmjs.com/package/fast-safe-stringify)
- [javascript-stringify](https://www.npmjs.com/package/javascript-stringify)
- [js-stringify](https://www.npmjs.com/package/js-stringify)
- [json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify)
- [json-stringify-safe](https://www.npmjs.com/package/json-stringify-safe)
- [json3](https://www.npmjs.com/package/json3)
- [object-inspect](https://www.npmjs.com/package/object-inspect)
- [pretty-format](https://www.npmjs.com/package/pretty-format)
- [stringify-object](https://www.npmjs.com/package/stringify-object)
## New queries
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
## Changes to libraries

View File

@@ -50,7 +50,12 @@ predicate illDefinedDecrForStmt(
DataFlow::localFlowStep(DataFlow::exprNode(initialCondition), DataFlow::exprNode(lesserOperand)) and
// `initialCondition` < `terminalCondition`
(
upperBound(initialCondition) < lowerBound(terminalCondition)
upperBound(initialCondition) < lowerBound(terminalCondition) and
(
// exclude cases where the loop counter is `unsigned` (where wrapping behaviour can be used deliberately)
v.getUnspecifiedType().(IntegralType).isSigned() or
initialCondition.getValue().toInt() = 0
)
or
(forstmt.conditionAlwaysFalse() or forstmt.conditionAlwaysTrue())
)

View File

@@ -214,6 +214,9 @@ abstract class ImplicitConversionFunction extends MemberFunction {
}
/**
* DEPRECATED: as of C++11 this class does not correspond perfectly with the
* language definition of a converting constructor.
*
* A C++ constructor that also defines an implicit conversion. For example the
* function `MyClass` in the following code is a `ConversionConstructor`:
* ```
@@ -225,15 +228,16 @@ abstract class ImplicitConversionFunction extends MemberFunction {
* };
* ```
*/
class ConversionConstructor extends Constructor, ImplicitConversionFunction {
deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction {
ConversionConstructor() {
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
not hasSpecifier("explicit") and
not this instanceof CopyConstructor
not hasSpecifier("explicit")
}
override string getAPrimaryQlClass() {
not this instanceof MoveConstructor and result = "ConversionConstructor"
not this instanceof CopyConstructor and
not this instanceof MoveConstructor and
result = "ConversionConstructor"
}
/** Gets the type this `ConversionConstructor` takes as input. */

View File

@@ -65,6 +65,15 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
// tracking. The flow from expression `x` into `x++` etc. is handled in the
// case above.
exprTo = DataFlow::getAnAccessToAssignedVariable(exprFrom.(PostfixCrementOperation))
or
// In `for (char c : s) { ... c ... }`, this rule propagates taint from `s`
// to `c`.
exists(RangeBasedForStmt rbf |
exprFrom = rbf.getRange() and
// It's guaranteed up to at least C++20 that the range-based for loop
// desugars to a variable with an initializer.
exprTo = rbf.getVariable().getInitializer().getExpr()
)
)
or
// Taint can flow through modeled functions

View File

@@ -7,9 +7,17 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint
/**
* Model for C++ conversion constructors.
* Model for C++ conversion constructors. As of C++11 this does not correspond
* perfectly with the language definition of a converting constructor, however,
* it does correspond with the constructors we are confident taint should flow
* through.
*/
class ConversionConstructorModel extends ConversionConstructor, TaintFunction {
class ConversionConstructorModel extends Constructor, TaintFunction {
ConversionConstructorModel() {
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
not hasSpecifier("explicit")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from the first constructor argument to the returned object
input.isParameter(0) and

View File

@@ -308,99 +308,205 @@
| movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT |
| stl.cpp:67:12:67:17 | call to source | stl.cpp:71:7:71:7 | a | |
| stl.cpp:68:16:68:20 | 123 | stl.cpp:68:16:68:21 | call to basic_string | TAINT |
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:72:7:72:7 | b | |
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:74:7:74:7 | b | |
| stl.cpp:69:16:69:21 | call to source | stl.cpp:69:16:69:24 | call to basic_string | TAINT |
| stl.cpp:69:16:69:24 | call to basic_string | stl.cpp:73:7:73:7 | c | |
| stl.cpp:69:16:69:24 | call to basic_string | stl.cpp:75:7:75:7 | c | |
| stl.cpp:74:7:74:7 | b | stl.cpp:74:9:74:13 | call to c_str | TAINT |
| stl.cpp:75:7:75:7 | c | stl.cpp:75:9:75:13 | call to c_str | TAINT |
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:83:2:83:4 | ss1 | |
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:89:7:89:9 | ss1 | |
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:94:7:94:9 | ss1 | |
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:84:2:84:4 | ss2 | |
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:90:7:90:9 | ss2 | |
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:95:7:95:9 | ss2 | |
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:85:2:85:4 | ss3 | |
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:91:7:91:9 | ss3 | |
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:96:7:96:9 | ss3 | |
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:86:2:86:4 | ss4 | |
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:92:7:92:9 | ss4 | |
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:97:7:97:9 | ss4 | |
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:87:2:87:4 | ss5 | |
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:93:7:93:9 | ss5 | |
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:98:7:98:9 | ss5 | |
| stl.cpp:81:16:81:21 | call to source | stl.cpp:81:16:81:24 | call to basic_string | TAINT |
| stl.cpp:81:16:81:24 | call to basic_string | stl.cpp:87:9:87:9 | t | |
| stl.cpp:83:2:83:4 | ref arg ss1 | stl.cpp:89:7:89:9 | ss1 | |
| stl.cpp:83:2:83:4 | ref arg ss1 | stl.cpp:94:7:94:9 | ss1 | |
| stl.cpp:84:2:84:4 | ref arg ss2 | stl.cpp:90:7:90:9 | ss2 | |
| stl.cpp:84:2:84:4 | ref arg ss2 | stl.cpp:95:7:95:9 | ss2 | |
| stl.cpp:85:2:85:4 | ref arg ss3 | stl.cpp:91:7:91:9 | ss3 | |
| stl.cpp:85:2:85:4 | ref arg ss3 | stl.cpp:96:7:96:9 | ss3 | |
| stl.cpp:86:2:86:4 | ref arg ss4 | stl.cpp:92:7:92:9 | ss4 | |
| stl.cpp:86:2:86:4 | ref arg ss4 | stl.cpp:97:7:97:9 | ss4 | |
| stl.cpp:87:2:87:4 | ref arg ss5 | stl.cpp:93:7:93:9 | ss5 | |
| stl.cpp:87:2:87:4 | ref arg ss5 | stl.cpp:98:7:98:9 | ss5 | |
| stl.cpp:101:32:101:37 | source | stl.cpp:106:9:106:14 | source | |
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:105:2:105:4 | ss1 | |
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:108:7:108:9 | ss1 | |
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:110:7:110:9 | ss1 | |
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:106:2:106:4 | ss2 | |
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:109:7:109:9 | ss2 | |
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:111:7:111:9 | ss2 | |
| stl.cpp:105:2:105:4 | ref arg ss1 | stl.cpp:108:7:108:9 | ss1 | |
| stl.cpp:105:2:105:4 | ref arg ss1 | stl.cpp:110:7:110:9 | ss1 | |
| stl.cpp:106:2:106:4 | ref arg ss2 | stl.cpp:109:7:109:9 | ss2 | |
| stl.cpp:106:2:106:4 | ref arg ss2 | stl.cpp:111:7:111:9 | ss2 | |
| stl.cpp:124:16:124:28 | call to basic_string | stl.cpp:125:7:125:11 | path1 | |
| stl.cpp:124:17:124:26 | call to user_input | stl.cpp:124:16:124:28 | call to basic_string | TAINT |
| stl.cpp:125:7:125:11 | path1 | stl.cpp:125:13:125:17 | call to c_str | TAINT |
| stl.cpp:128:10:128:19 | call to user_input | stl.cpp:128:10:128:21 | call to basic_string | TAINT |
| stl.cpp:128:10:128:21 | call to basic_string | stl.cpp:128:2:128:21 | ... = ... | |
| stl.cpp:128:10:128:21 | call to basic_string | stl.cpp:129:7:129:11 | path2 | |
| stl.cpp:129:7:129:11 | path2 | stl.cpp:129:13:129:17 | call to c_str | TAINT |
| stl.cpp:131:15:131:24 | call to user_input | stl.cpp:131:15:131:27 | call to basic_string | TAINT |
| stl.cpp:131:15:131:27 | call to basic_string | stl.cpp:132:7:132:11 | path3 | |
| stl.cpp:132:7:132:11 | path3 | stl.cpp:132:13:132:17 | call to c_str | TAINT |
| stl.cpp:137:19:137:24 | call to source | stl.cpp:140:17:140:18 | cs | |
| stl.cpp:137:19:137:24 | call to source | stl.cpp:142:7:142:8 | cs | |
| stl.cpp:140:17:140:18 | cs | stl.cpp:140:17:140:19 | call to basic_string | TAINT |
| stl.cpp:140:17:140:19 | call to basic_string | stl.cpp:143:7:143:8 | ss | |
| stl.cpp:148:19:148:24 | call to source | stl.cpp:151:17:151:18 | cs | |
| stl.cpp:151:17:151:18 | cs | stl.cpp:151:17:151:19 | call to basic_string | TAINT |
| stl.cpp:151:17:151:19 | call to basic_string | stl.cpp:154:7:154:8 | ss | |
| stl.cpp:151:17:151:19 | call to basic_string | stl.cpp:157:7:157:8 | ss | |
| stl.cpp:154:7:154:8 | ss | stl.cpp:154:10:154:14 | call to c_str | TAINT |
| stl.cpp:154:10:154:14 | call to c_str | stl.cpp:154:2:154:16 | ... = ... | |
| stl.cpp:154:10:154:14 | call to c_str | stl.cpp:156:7:156:8 | cs | |
| stl.cpp:163:18:163:24 | hello | stl.cpp:163:18:163:25 | call to basic_string | TAINT |
| stl.cpp:163:18:163:25 | call to basic_string | stl.cpp:168:8:168:9 | s1 | |
| stl.cpp:164:19:164:26 | call to basic_string | stl.cpp:169:8:169:9 | s2 | |
| stl.cpp:164:20:164:26 | hello | stl.cpp:164:19:164:26 | call to basic_string | TAINT |
| stl.cpp:166:8:166:14 | call to basic_string | stl.cpp:166:3:166:14 | ... = ... | |
| stl.cpp:166:8:166:14 | call to basic_string | stl.cpp:170:8:170:9 | s3 | |
| stl.cpp:166:8:166:14 | hello | stl.cpp:166:8:166:14 | call to basic_string | TAINT |
| stl.cpp:174:18:174:23 | call to source | stl.cpp:174:18:174:26 | call to basic_string | TAINT |
| stl.cpp:174:18:174:26 | call to basic_string | stl.cpp:179:8:179:9 | s1 | |
| stl.cpp:175:19:175:27 | call to basic_string | stl.cpp:180:8:180:9 | s2 | |
| stl.cpp:175:20:175:25 | call to source | stl.cpp:175:19:175:27 | call to basic_string | TAINT |
| stl.cpp:177:8:177:13 | call to source | stl.cpp:177:8:177:15 | call to basic_string | TAINT |
| stl.cpp:177:8:177:15 | call to basic_string | stl.cpp:177:3:177:15 | ... = ... | |
| stl.cpp:177:8:177:15 | call to basic_string | stl.cpp:181:8:181:9 | s3 | |
| stl.cpp:185:15:185:16 | call to basic_string | stl.cpp:186:20:186:21 | s1 | |
| stl.cpp:185:15:185:16 | call to basic_string | stl.cpp:188:8:188:9 | s1 | |
| stl.cpp:185:15:185:16 | call to basic_string | stl.cpp:190:8:190:9 | s1 | |
| stl.cpp:186:20:186:21 | s1 | stl.cpp:191:8:191:9 | s2 | |
| stl.cpp:188:8:188:9 | s1 | stl.cpp:188:3:188:9 | ... = ... | |
| stl.cpp:188:8:188:9 | s1 | stl.cpp:192:8:192:9 | s3 | |
| stl.cpp:196:19:196:40 | call to basic_string | stl.cpp:200:8:200:9 | s1 | |
| stl.cpp:196:32:196:37 | call to source | stl.cpp:196:19:196:40 | call to basic_string | TAINT |
| stl.cpp:198:8:198:28 | call to basic_string | stl.cpp:198:3:198:28 | ... = ... | |
| stl.cpp:198:8:198:28 | call to basic_string | stl.cpp:201:8:201:9 | s2 | |
| stl.cpp:198:20:198:25 | call to source | stl.cpp:198:8:198:28 | call to basic_string | TAINT |
| stl.cpp:97:12:97:17 | call to source | stl.cpp:101:7:101:7 | a | |
| stl.cpp:98:16:98:20 | 123 | stl.cpp:98:16:98:21 | call to basic_string | TAINT |
| stl.cpp:98:16:98:21 | call to basic_string | stl.cpp:102:7:102:7 | b | |
| stl.cpp:98:16:98:21 | call to basic_string | stl.cpp:104:7:104:7 | b | |
| stl.cpp:99:16:99:21 | call to source | stl.cpp:99:16:99:24 | call to basic_string | TAINT |
| stl.cpp:99:16:99:24 | call to basic_string | stl.cpp:103:7:103:7 | c | |
| stl.cpp:99:16:99:24 | call to basic_string | stl.cpp:105:7:105:7 | c | |
| stl.cpp:104:7:104:7 | b | stl.cpp:104:9:104:13 | call to c_str | TAINT |
| stl.cpp:105:7:105:7 | c | stl.cpp:105:9:105:13 | call to c_str | TAINT |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:113:2:113:4 | ss1 | |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:119:7:119:9 | ss1 | |
| stl.cpp:110:20:110:22 | call to basic_stringstream | stl.cpp:124:7:124:9 | ss1 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:114:2:114:4 | ss2 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:120:7:120:9 | ss2 | |
| stl.cpp:110:25:110:27 | call to basic_stringstream | stl.cpp:125:7:125:9 | ss2 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:115:2:115:4 | ss3 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:121:7:121:9 | ss3 | |
| stl.cpp:110:30:110:32 | call to basic_stringstream | stl.cpp:126:7:126:9 | ss3 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:116:2:116:4 | ss4 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:122:7:122:9 | ss4 | |
| stl.cpp:110:35:110:37 | call to basic_stringstream | stl.cpp:127:7:127:9 | ss4 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:117:2:117:4 | ss5 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:123:7:123:9 | ss5 | |
| stl.cpp:110:40:110:42 | call to basic_stringstream | stl.cpp:128:7:128:9 | ss5 | |
| stl.cpp:111:16:111:21 | call to source | stl.cpp:111:16:111:24 | call to basic_string | TAINT |
| stl.cpp:111:16:111:24 | call to basic_string | stl.cpp:117:9:117:9 | t | |
| stl.cpp:113:2:113:4 | ref arg ss1 | stl.cpp:119:7:119:9 | ss1 | |
| stl.cpp:113:2:113:4 | ref arg ss1 | stl.cpp:124:7:124:9 | ss1 | |
| stl.cpp:114:2:114:4 | ref arg ss2 | stl.cpp:120:7:120:9 | ss2 | |
| stl.cpp:114:2:114:4 | ref arg ss2 | stl.cpp:125:7:125:9 | ss2 | |
| stl.cpp:115:2:115:4 | ref arg ss3 | stl.cpp:121:7:121:9 | ss3 | |
| stl.cpp:115:2:115:4 | ref arg ss3 | stl.cpp:126:7:126:9 | ss3 | |
| stl.cpp:116:2:116:4 | ref arg ss4 | stl.cpp:122:7:122:9 | ss4 | |
| stl.cpp:116:2:116:4 | ref arg ss4 | stl.cpp:127:7:127:9 | ss4 | |
| stl.cpp:117:2:117:4 | ref arg ss5 | stl.cpp:123:7:123:9 | ss5 | |
| stl.cpp:117:2:117:4 | ref arg ss5 | stl.cpp:128:7:128:9 | ss5 | |
| stl.cpp:131:32:131:37 | source | stl.cpp:136:9:136:14 | source | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:135:2:135:4 | ss1 | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:138:7:138:9 | ss1 | |
| stl.cpp:133:20:133:22 | call to basic_stringstream | stl.cpp:140:7:140:9 | ss1 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:136:2:136:4 | ss2 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:139:7:139:9 | ss2 | |
| stl.cpp:133:25:133:27 | call to basic_stringstream | stl.cpp:141:7:141:9 | ss2 | |
| stl.cpp:135:2:135:4 | ref arg ss1 | stl.cpp:138:7:138:9 | ss1 | |
| stl.cpp:135:2:135:4 | ref arg ss1 | stl.cpp:140:7:140:9 | ss1 | |
| stl.cpp:136:2:136:4 | ref arg ss2 | stl.cpp:139:7:139:9 | ss2 | |
| stl.cpp:136:2:136:4 | ref arg ss2 | stl.cpp:141:7:141:9 | ss2 | |
| stl.cpp:154:16:154:28 | call to basic_string | stl.cpp:155:7:155:11 | path1 | |
| stl.cpp:154:17:154:26 | call to user_input | stl.cpp:154:16:154:28 | call to basic_string | TAINT |
| stl.cpp:155:7:155:11 | path1 | stl.cpp:155:13:155:17 | call to c_str | TAINT |
| stl.cpp:158:10:158:19 | call to user_input | stl.cpp:158:10:158:21 | call to basic_string | TAINT |
| stl.cpp:158:10:158:21 | call to basic_string | stl.cpp:158:2:158:21 | ... = ... | |
| stl.cpp:158:10:158:21 | call to basic_string | stl.cpp:159:7:159:11 | path2 | |
| stl.cpp:159:7:159:11 | path2 | stl.cpp:159:13:159:17 | call to c_str | TAINT |
| stl.cpp:161:15:161:24 | call to user_input | stl.cpp:161:15:161:27 | call to basic_string | TAINT |
| stl.cpp:161:15:161:27 | call to basic_string | stl.cpp:162:7:162:11 | path3 | |
| stl.cpp:162:7:162:11 | path3 | stl.cpp:162:13:162:17 | call to c_str | TAINT |
| stl.cpp:167:19:167:24 | call to source | stl.cpp:170:17:170:18 | cs | |
| stl.cpp:167:19:167:24 | call to source | stl.cpp:172:7:172:8 | cs | |
| stl.cpp:170:17:170:18 | cs | stl.cpp:170:17:170:19 | call to basic_string | TAINT |
| stl.cpp:170:17:170:19 | call to basic_string | stl.cpp:173:7:173:8 | ss | |
| stl.cpp:178:19:178:24 | call to source | stl.cpp:181:17:181:18 | cs | |
| stl.cpp:181:17:181:18 | cs | stl.cpp:181:17:181:19 | call to basic_string | TAINT |
| stl.cpp:181:17:181:19 | call to basic_string | stl.cpp:184:7:184:8 | ss | |
| stl.cpp:181:17:181:19 | call to basic_string | stl.cpp:187:7:187:8 | ss | |
| stl.cpp:184:7:184:8 | ss | stl.cpp:184:10:184:14 | call to c_str | TAINT |
| stl.cpp:184:10:184:14 | call to c_str | stl.cpp:184:2:184:16 | ... = ... | |
| stl.cpp:184:10:184:14 | call to c_str | stl.cpp:186:7:186:8 | cs | |
| stl.cpp:193:18:193:24 | hello | stl.cpp:193:18:193:25 | call to basic_string | TAINT |
| stl.cpp:193:18:193:25 | call to basic_string | stl.cpp:198:8:198:9 | s1 | |
| stl.cpp:194:19:194:26 | call to basic_string | stl.cpp:199:8:199:9 | s2 | |
| stl.cpp:194:20:194:26 | hello | stl.cpp:194:19:194:26 | call to basic_string | TAINT |
| stl.cpp:196:8:196:14 | call to basic_string | stl.cpp:196:3:196:14 | ... = ... | |
| stl.cpp:196:8:196:14 | call to basic_string | stl.cpp:200:8:200:9 | s3 | |
| stl.cpp:196:8:196:14 | hello | stl.cpp:196:8:196:14 | call to basic_string | TAINT |
| stl.cpp:204:18:204:23 | call to source | stl.cpp:204:18:204:26 | call to basic_string | TAINT |
| stl.cpp:204:18:204:26 | call to basic_string | stl.cpp:209:8:209:9 | s1 | |
| stl.cpp:205:19:205:27 | call to basic_string | stl.cpp:210:8:210:9 | s2 | |
| stl.cpp:205:20:205:25 | call to source | stl.cpp:205:19:205:27 | call to basic_string | TAINT |
| stl.cpp:207:8:207:13 | call to source | stl.cpp:207:8:207:15 | call to basic_string | TAINT |
| stl.cpp:207:8:207:15 | call to basic_string | stl.cpp:207:3:207:15 | ... = ... | |
| stl.cpp:207:8:207:15 | call to basic_string | stl.cpp:211:8:211:9 | s3 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:216:20:216:21 | s1 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:218:8:218:9 | s1 | |
| stl.cpp:215:15:215:16 | call to basic_string | stl.cpp:220:8:220:9 | s1 | |
| stl.cpp:216:20:216:21 | s1 | stl.cpp:221:8:221:9 | s2 | |
| stl.cpp:218:8:218:9 | s1 | stl.cpp:218:3:218:9 | ... = ... | |
| stl.cpp:218:8:218:9 | s1 | stl.cpp:222:8:222:9 | s3 | |
| stl.cpp:226:19:226:40 | call to basic_string | stl.cpp:230:8:230:9 | s1 | |
| stl.cpp:226:32:226:37 | call to source | stl.cpp:226:19:226:40 | call to basic_string | TAINT |
| stl.cpp:228:8:228:28 | call to basic_string | stl.cpp:228:3:228:28 | ... = ... | |
| stl.cpp:228:8:228:28 | call to basic_string | stl.cpp:231:8:231:9 | s2 | |
| stl.cpp:228:20:228:25 | call to source | stl.cpp:228:8:228:28 | call to basic_string | TAINT |
| stl.cpp:238:16:238:21 | call to source | stl.cpp:238:16:238:24 | call to basic_string | TAINT |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:239:15:239:15 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:243:33:243:33 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:243:50:243:50 | s | |
| stl.cpp:238:16:238:24 | call to basic_string | stl.cpp:247:16:247:16 | s | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to begin | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | call to end | stl.cpp:239:15:239:15 | (__end) | |
| stl.cpp:239:15:239:15 | call to operator* | stl.cpp:240:8:240:8 | c | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__begin) | stl.cpp:239:15:239:15 | (__begin) | |
| stl.cpp:239:15:239:15 | ref arg (__range) | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | (__range) | |
| stl.cpp:239:15:239:15 | s | stl.cpp:239:15:239:15 | call to operator* | TAINT |
| stl.cpp:243:33:243:33 | ref arg s | stl.cpp:243:50:243:50 | s | |
| stl.cpp:243:33:243:33 | ref arg s | stl.cpp:247:16:247:16 | s | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:243:44:243:45 | it | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:243:61:243:62 | it | |
| stl.cpp:243:35:243:39 | call to begin | stl.cpp:244:9:244:10 | it | |
| stl.cpp:243:50:243:50 | ref arg s | stl.cpp:243:50:243:50 | s | |
| stl.cpp:243:50:243:50 | ref arg s | stl.cpp:247:16:247:16 | s | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:243:44:243:45 | it | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:243:61:243:62 | it | |
| stl.cpp:243:61:243:62 | ref arg it | stl.cpp:244:9:244:10 | it | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to begin | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | call to end | stl.cpp:247:16:247:16 | (__end) | |
| stl.cpp:247:16:247:16 | call to operator* | stl.cpp:248:8:248:8 | c | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__begin) | stl.cpp:247:16:247:16 | (__begin) | |
| stl.cpp:247:16:247:16 | ref arg (__range) | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | (__range) | |
| stl.cpp:247:16:247:16 | s | stl.cpp:247:16:247:16 | call to operator* | TAINT |
| stl.cpp:251:28:251:33 | call to source | stl.cpp:251:28:251:36 | call to basic_string | TAINT |
| stl.cpp:251:28:251:36 | call to basic_string | stl.cpp:252:22:252:28 | const_s | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to begin | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | call to end | stl.cpp:252:22:252:22 | (__end) | |
| stl.cpp:252:22:252:22 | call to operator* | stl.cpp:253:8:253:8 | c | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:22 | ref arg (__begin) | stl.cpp:252:22:252:22 | (__begin) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | (__range) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | (__range) | |
| stl.cpp:252:22:252:28 | const_s | stl.cpp:252:22:252:22 | call to operator* | TAINT |
| stl.cpp:288:43:288:49 | source1 | stl.cpp:292:21:292:27 | source1 | |
| stl.cpp:288:43:288:49 | source1 | stl.cpp:306:33:306:39 | source1 | |
| stl.cpp:292:21:292:27 | source1 | stl.cpp:292:21:292:28 | call to vector | TAINT |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:294:14:294:14 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:298:38:298:38 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:298:55:298:55 | v | |
| stl.cpp:292:21:292:28 | call to vector | stl.cpp:302:15:302:15 | v | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to begin | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | call to end | stl.cpp:294:14:294:14 | (__end) | |
| stl.cpp:294:14:294:14 | call to operator* | stl.cpp:295:8:295:8 | x | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__begin) | stl.cpp:294:14:294:14 | (__begin) | |
| stl.cpp:294:14:294:14 | ref arg (__range) | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | (__range) | |
| stl.cpp:294:14:294:14 | v | stl.cpp:294:14:294:14 | call to operator* | TAINT |
| stl.cpp:298:38:298:38 | ref arg v | stl.cpp:298:55:298:55 | v | |
| stl.cpp:298:38:298:38 | ref arg v | stl.cpp:302:15:302:15 | v | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:298:49:298:50 | it | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:298:66:298:67 | it | |
| stl.cpp:298:40:298:44 | call to begin | stl.cpp:299:9:299:10 | it | |
| stl.cpp:298:55:298:55 | ref arg v | stl.cpp:298:55:298:55 | v | |
| stl.cpp:298:55:298:55 | ref arg v | stl.cpp:302:15:302:15 | v | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:298:49:298:50 | it | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:298:66:298:67 | it | |
| stl.cpp:298:66:298:67 | ref arg it | stl.cpp:299:9:299:10 | it | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to begin | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | call to end | stl.cpp:302:15:302:15 | (__end) | |
| stl.cpp:302:15:302:15 | call to operator* | stl.cpp:303:8:303:8 | x | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__begin) | stl.cpp:302:15:302:15 | (__begin) | |
| stl.cpp:302:15:302:15 | ref arg (__range) | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | (__range) | |
| stl.cpp:302:15:302:15 | v | stl.cpp:302:15:302:15 | call to operator* | TAINT |
| stl.cpp:306:33:306:39 | source1 | stl.cpp:306:33:306:40 | call to vector | TAINT |
| stl.cpp:306:33:306:40 | call to vector | stl.cpp:307:21:307:27 | const_v | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to begin | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | call to end | stl.cpp:307:21:307:21 | (__end) | |
| stl.cpp:307:21:307:21 | call to operator* | stl.cpp:308:8:308:8 | x | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:21 | ref arg (__begin) | stl.cpp:307:21:307:21 | (__begin) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | (__range) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | (__range) | |
| stl.cpp:307:21:307:27 | const_v | stl.cpp:307:21:307:21 | call to operator* | TAINT |
| structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT |
| structlikeclass.cpp:5:7:5:7 | Unknown literal | structlikeclass.cpp:5:7:5:7 | constructor init of field v | TAINT |
| structlikeclass.cpp:5:7:5:7 | this | structlikeclass.cpp:5:7:5:7 | constructor init of field v [pre-this] | |

View File

@@ -7,6 +7,26 @@ namespace std
typedef size_t streamsize;
struct ptrdiff_t;
template <class iterator_category,
class value_type,
class difference_type = ptrdiff_t,
class pointer_type = value_type*,
class reference_type = value_type&>
struct iterator {
iterator &operator++();
iterator operator++(int);
bool operator==(iterator other) const;
bool operator!=(iterator other) const;
reference_type operator*() const;
};
struct input_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
template <class T> class allocator {
public:
allocator() throw();
@@ -19,6 +39,16 @@ namespace std
basic_string(const charT* s, const Allocator& a = Allocator());
const charT* c_str() const;
typedef std::iterator<random_access_iterator_tag, charT> iterator;
typedef std::iterator<random_access_iterator_tag, const charT> const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
};
typedef basic_string<char> string;
@@ -202,3 +232,79 @@ void test_string_constructors_assignments()
}
}
void sink(char) {}
void test_range_based_for_loop_string() {
std::string s(source());
for(char c : s) {
sink(c); // tainted [NOT DETECTED by IR]
}
for(std::string::iterator it = s.begin(); it != s.end(); ++it) {
sink(*it); // tainted [NOT DETECTED]
}
for(char& c : s) {
sink(c); // tainted [NOT DETECTED by IR]
}
const std::string const_s(source());
for(const char& c : const_s) {
sink(c); // tainted [NOT DETECTED by IR]
}
}
namespace std {
template <class T>
class vector {
private:
void *data_;
public:
vector(int size);
T& operator[](int idx);
const T& operator[](int idx) const;
typedef std::iterator<random_access_iterator_tag, T> iterator;
typedef std::iterator<random_access_iterator_tag, const T> const_iterator;
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
};
}
void sink(int);
void test_range_based_for_loop_vector(int source1) {
// Tainting the vector by allocating a tainted length. This doesn't represent
// how a vector would typically get tainted, but it allows this test to avoid
// being concerned with std::vector modeling.
std::vector<int> v(source1);
for(int x : v) {
sink(x); // tainted [NOT DETECTED by IR]
}
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
sink(*it); // tainted [NOT DETECTED]
}
for(int& x : v) {
sink(x); // tainted [NOT DETECTED by IR]
}
const std::vector<int> const_v(source1);
for(const int& x : const_v) {
sink(x); // tainted [NOT DETECTED by IR]
}
}

View File

@@ -32,21 +32,27 @@
| movableclass.cpp:55:8:55:9 | s2 | movableclass.cpp:52:23:52:28 | call to source |
| movableclass.cpp:64:8:64:9 | s2 | movableclass.cpp:23:55:23:60 | call to source |
| movableclass.cpp:65:11:65:11 | call to operator= | movableclass.cpp:65:13:65:18 | call to source |
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
| stl.cpp:73:7:73:7 | c | stl.cpp:69:16:69:21 | call to source |
| stl.cpp:75:9:75:13 | call to c_str | stl.cpp:69:16:69:21 | call to source |
| stl.cpp:125:13:125:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
| stl.cpp:129:13:129:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
| stl.cpp:132:13:132:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
| stl.cpp:142:7:142:8 | cs | stl.cpp:137:19:137:24 | call to source |
| stl.cpp:143:7:143:8 | ss | stl.cpp:137:19:137:24 | call to source |
| stl.cpp:156:7:156:8 | cs | stl.cpp:148:19:148:24 | call to source |
| stl.cpp:157:7:157:8 | ss | stl.cpp:148:19:148:24 | call to source |
| stl.cpp:179:8:179:9 | s1 | stl.cpp:174:18:174:23 | call to source |
| stl.cpp:180:8:180:9 | s2 | stl.cpp:175:20:175:25 | call to source |
| stl.cpp:181:8:181:9 | s3 | stl.cpp:177:8:177:13 | call to source |
| stl.cpp:200:8:200:9 | s1 | stl.cpp:196:32:196:37 | call to source |
| stl.cpp:201:8:201:9 | s2 | stl.cpp:198:20:198:25 | call to source |
| stl.cpp:101:7:101:7 | a | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:103:7:103:7 | c | stl.cpp:99:16:99:21 | call to source |
| stl.cpp:105:9:105:13 | call to c_str | stl.cpp:99:16:99:21 | call to source |
| stl.cpp:155:13:155:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:159:13:159:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:162:13:162:17 | call to c_str | stl.cpp:147:10:147:15 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:173:7:173:8 | ss | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:186:7:186:8 | cs | stl.cpp:178:19:178:24 | call to source |
| stl.cpp:187:7:187:8 | ss | stl.cpp:178:19:178:24 | call to source |
| stl.cpp:209:8:209:9 | s1 | stl.cpp:204:18:204:23 | call to source |
| stl.cpp:210:8:210:9 | s2 | stl.cpp:205:20:205:25 | call to source |
| stl.cpp:211:8:211:9 | s3 | stl.cpp:207:8:207:13 | call to source |
| stl.cpp:230:8:230:9 | s1 | stl.cpp:226:32:226:37 | call to source |
| stl.cpp:231:8:231:9 | s2 | stl.cpp:228:20:228:25 | call to source |
| stl.cpp:240:8:240:8 | c | stl.cpp:238:16:238:21 | call to source |
| stl.cpp:248:8:248:8 | c | stl.cpp:238:16:238:21 | call to source |
| stl.cpp:253:8:253:8 | c | stl.cpp:251:28:251:33 | call to source |
| stl.cpp:295:8:295:8 | x | stl.cpp:288:43:288:49 | source1 |
| stl.cpp:303:8:303:8 | x | stl.cpp:288:43:288:49 | source1 |
| stl.cpp:308:8:308:8 | x | stl.cpp:288:43:288:49 | source1 |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |

View File

@@ -30,20 +30,26 @@
| movableclass.cpp:55:8:55:9 | movableclass.cpp:52:23:52:28 | AST only |
| movableclass.cpp:64:8:64:9 | movableclass.cpp:23:55:23:60 | AST only |
| movableclass.cpp:65:11:65:11 | movableclass.cpp:65:13:65:18 | AST only |
| stl.cpp:73:7:73:7 | stl.cpp:69:16:69:21 | AST only |
| stl.cpp:75:9:75:13 | stl.cpp:69:16:69:21 | AST only |
| stl.cpp:125:13:125:17 | stl.cpp:117:10:117:15 | AST only |
| stl.cpp:129:13:129:17 | stl.cpp:117:10:117:15 | AST only |
| stl.cpp:132:13:132:17 | stl.cpp:117:10:117:15 | AST only |
| stl.cpp:142:7:142:8 | stl.cpp:137:19:137:26 | IR only |
| stl.cpp:143:7:143:8 | stl.cpp:137:19:137:24 | AST only |
| stl.cpp:156:7:156:8 | stl.cpp:148:19:148:24 | AST only |
| stl.cpp:157:7:157:8 | stl.cpp:148:19:148:24 | AST only |
| stl.cpp:179:8:179:9 | stl.cpp:174:18:174:23 | AST only |
| stl.cpp:180:8:180:9 | stl.cpp:175:20:175:25 | AST only |
| stl.cpp:181:8:181:9 | stl.cpp:177:8:177:13 | AST only |
| stl.cpp:200:8:200:9 | stl.cpp:196:32:196:37 | AST only |
| stl.cpp:201:8:201:9 | stl.cpp:198:20:198:25 | AST only |
| stl.cpp:103:7:103:7 | stl.cpp:99:16:99:21 | AST only |
| stl.cpp:105:9:105:13 | stl.cpp:99:16:99:21 | AST only |
| stl.cpp:155:13:155:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:159:13:159:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:162:13:162:17 | stl.cpp:147:10:147:15 | AST only |
| stl.cpp:172:7:172:8 | stl.cpp:167:19:167:26 | IR only |
| stl.cpp:173:7:173:8 | stl.cpp:167:19:167:24 | AST only |
| stl.cpp:186:7:186:8 | stl.cpp:178:19:178:24 | AST only |
| stl.cpp:187:7:187:8 | stl.cpp:178:19:178:24 | AST only |
| stl.cpp:209:8:209:9 | stl.cpp:204:18:204:23 | AST only |
| stl.cpp:210:8:210:9 | stl.cpp:205:20:205:25 | AST only |
| stl.cpp:211:8:211:9 | stl.cpp:207:8:207:13 | AST only |
| stl.cpp:230:8:230:9 | stl.cpp:226:32:226:37 | AST only |
| stl.cpp:231:8:231:9 | stl.cpp:228:20:228:25 | AST only |
| stl.cpp:240:8:240:8 | stl.cpp:238:16:238:21 | AST only |
| stl.cpp:248:8:248:8 | stl.cpp:238:16:238:21 | AST only |
| stl.cpp:253:8:253:8 | stl.cpp:251:28:251:33 | AST only |
| stl.cpp:295:8:295:8 | stl.cpp:288:43:288:49 | AST only |
| stl.cpp:303:8:303:8 | stl.cpp:288:43:288:49 | AST only |
| stl.cpp:308:8:308:8 | stl.cpp:288:43:288:49 | AST only |
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |

View File

@@ -1,10 +1,10 @@
| format.cpp:157:7:157:22 | (int)... | format.cpp:147:12:147:25 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
| stl.cpp:71:7:71:7 | (const char *)... | stl.cpp:67:12:67:17 | call to source |
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
| stl.cpp:142:7:142:8 | cs | stl.cpp:137:19:137:24 | call to source |
| stl.cpp:142:7:142:8 | cs | stl.cpp:137:19:137:26 | (const char *)... |
| stl.cpp:101:7:101:7 | (const char *)... | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:101:7:101:7 | a | stl.cpp:97:12:97:17 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:24 | call to source |
| stl.cpp:172:7:172:8 | cs | stl.cpp:167:19:167:26 | (const char *)... |
| structlikeclass.cpp:38:8:38:9 | s4 | structlikeclass.cpp:33:8:33:13 | call to source |
| structlikeclass.cpp:61:8:61:9 | s2 | structlikeclass.cpp:58:24:58:29 | call to source |
| structlikeclass.cpp:62:8:62:20 | ... = ... | structlikeclass.cpp:62:13:62:18 | call to source |

View File

@@ -20,7 +20,7 @@
| functions.cpp:23:7:23:11 | Table | Class | functions.cpp:30:8:30:13 | insert | |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:33:7:33:7 | operator= | |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:36:2:36:8 | MyClass | Constructor, NoArgConstructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:37:2:37:8 | MyClass | Constructor, ConversionConstructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:37:2:37:8 | MyClass | Constructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:38:2:38:8 | MyClass | Constructor, CopyConstructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:39:2:39:8 | MyClass | Constructor, ConversionConstructor, MoveConstructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:39:2:39:8 | MyClass | Constructor, MoveConstructor, getAConstructor() |
| functions.cpp:33:7:33:13 | MyClass | Class | functions.cpp:40:2:40:13 | operator int | ConversionOperator |

View File

@@ -19,9 +19,6 @@ string describe(Class c, MemberFunction f) {
f instanceof Destructor and
result = "Destructor"
or
f instanceof ConversionConstructor and
result = "ConversionConstructor"
or
f instanceof CopyConstructor and
result = "CopyConstructor"
or

View File

@@ -177,4 +177,43 @@ void FalseNegativeTestCases()
for (int i = 100; i > 0; i += 2) {}
// For comparison
for (int i = 100; i > 0; i ++ ) {} // BUG
}
}
void IntendedOverflow(unsigned char p)
{
const unsigned char m = 10;
unsigned char i;
signed char s;
for (i = 63; i < 64; i--) {} // GOOD (legitimate way to count down with an unsigned)
for (i = 63; i < 128; i--) {} // DUBIOUS (could still be a typo?)
for (i = 63; i < 255; i--) {} // GOOD
for (i = m - 1; i < m; i--) {} // GOOD
for (i = m - 2; i < m; i--) {} // DUBIOUS
for (i = m; i < m + 1; i--) {} // GOOD
for (s = 63; s < 64; s--) {} // BAD (signed numbers don't wrap at 0 / at all)
for (s = m + 1; s < m; s--) {} // BAD (never runs)
for (i = p - 1; i < p; i--) {} // GOOD
for (s = p - 1; s < p; s--) {} // BAD [NOT DETECTED]
{
int n;
n = 64;
for (i = n - 1; i < n; i--) {} // GOOD
n = 64;
for (i = n - 1; i < 64; i--) {} // GOOD
n = 64;
for (i = 63; i < n; i--) {} // GOOD
n = 64;
for (s = n - 1; s < n; s--) {} // BAD [NOT DETECTED]
n = 64;
for (s = n - 1; s < 64; s--) {} // BAD
n = 64;
for (s = 63; s < n; s--) {} // BAD [NOT DETECTED]
}
}

View File

@@ -20,3 +20,6 @@
| inconsistentLoopDirection.cpp:140:5:142:5 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (200), but the terminal condition is lower (0). |
| inconsistentLoopDirection.cpp:175:5:175:36 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts downward from a value (0), but the terminal condition is higher (10). |
| inconsistentLoopDirection.cpp:179:5:179:38 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "i" counts upward from a value (100), but the terminal condition is lower (0). |
| inconsistentLoopDirection.cpp:196:5:196:32 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "s" counts downward from a value (63), but the terminal condition is higher (64). |
| inconsistentLoopDirection.cpp:197:5:197:34 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "s" counts downward from a value (... + ...), but the terminal condition is always false. |
| inconsistentLoopDirection.cpp:215:3:215:33 | for(...;...;...) ... | Ill-defined for-loop: a loop using variable "s" counts downward from a value (... - ...), but the terminal condition is higher (64). |

View File

@@ -0,0 +1,23 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The <code>DataSet</code> and <code>DataTable</code> types are legacy .NET components that you can use to represent data sets as managed objects.</p>
<p>While <code>DataSet</code> and <code>DataTable</code> do impose default limitations on the types that are allowed to be present while deserializing XML payloads, <code>DataSet</code> and <code>DataTable</code> are in general not safe when populated with untrusted input.</p>
<p>Please visit <a href="https://go.microsoft.com/fwlink/?linkid=2132227">DataSet and DataTable security guidance</a> for more details.</p>
</overview>
<recommendation>
<p>Please review the <a href="https://go.microsoft.com/fwlink/?linkid=2132227">DataSet and DataTable security guidance</a> before making use of these types for serialization.</p>
</recommendation>
<references>
<li>Microsoft Docs<a href="https://go.microsoft.com/fwlink/?linkid=2132227">DataSet and DataTable security guidance</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,100 @@
/**
* Provides classes for `DataSet` or `DataTable` deserialization queries.
*
* Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.
*/
import csharp
/**
* Abstract class that depends or inherits from `DataSet` or `DataTable` types.
*/
abstract class DataSetOrTableRelatedClass extends Class { }
/**
* `DataSet`, `DataTable` types, or any types derived from them.
*/
class DataSetOrTable extends DataSetOrTableRelatedClass {
DataSetOrTable() {
this.getABaseType*().getQualifiedName() = "System.Data.DataTable" or
this.getABaseType*().getQualifiedName() = "System.Data.DataSet"
}
}
/**
* A Class that include a property or generic collection of type `DataSet` and `DataTable`
*/
class ClassWithDataSetOrTableMember extends DataSetOrTableRelatedClass {
ClassWithDataSetOrTableMember() {
this.getAMember().(AssignableMember).getType() instanceof DataSetOrTable
or
exists(Property p | p = this.getAProperty() |
p.getType() instanceof DataSetOrTable or
p.getType().(ConstructedGeneric).getATypeArgument() instanceof DataSetOrTable
)
}
}
/**
* Serializable types
*/
class SerializableClass extends Class {
SerializableClass() {
(
this.getABaseType*().getQualifiedName() = "System.Xml.Serialization.XmlSerializer" or
this.getABaseType*().getQualifiedName() = "System.Runtime.Serialization.ISerializable" or
this.getABaseType*().getQualifiedName() = "System.Runtime.Serialization.XmlObjectSerializer" or
this.getABaseType*().getQualifiedName() =
"System.Runtime.Serialization.ISerializationSurrogateProvider" or
this.getABaseType*().getQualifiedName() =
"System.Runtime.Serialization.XmlSerializableServices" or
this.getABaseType*().getQualifiedName() = "System.Xml.Serialization.IXmlSerializable"
)
or
exists(Attribute a | a = this.getAnAttribute() |
a.getType().getQualifiedName() = "System.SerializableAttribute"
)
}
}
/**
* Holds if the serializable class `c` has a property or field `m` that is of `DataSet` or `DataTable` related type
*/
predicate isClassUnsafeXmlSerializerImplementation(SerializableClass c, AssignableMember am) {
am = c.getAMember() and
am.getType() instanceof DataSetOrTableRelatedClass
}
/**
* Serializable class that has a property or field that is of `DataSet` or `DataTable` related type
*/
class UnsafeXmlSerializerImplementation extends SerializableClass {
UnsafeXmlSerializerImplementation() { isClassUnsafeXmlSerializerImplementation(this, _) }
}
/**
* Method that may be unsafe when used to deserialize DataSet and DataTable related types
*/
class UnsafeXmlReadMethod extends Method {
UnsafeXmlReadMethod() {
this.getQualifiedName() = "System.Data.DataTable.ReadXml"
or
this.getQualifiedName() = "System.Data.DataTable.ReadXmlSchema"
or
this.getQualifiedName() = "System.Data.DataSet.ReadXml"
or
this.getQualifiedName() = "System.Data.DataSet.ReadXmlSchema"
or
this.getName().matches("ReadXml%") and
exists(Class c | c.getAMethod() = this |
c.getABaseType*() instanceof DataSetOrTableRelatedClass
)
}
}
/**
* MethodCall that may be unsafe when used to deserialize DataSet and DataTable related types
*/
class UnsafeXmlReadMethodCall extends MethodCall {
UnsafeXmlReadMethodCall() { exists(UnsafeXmlReadMethod uxrm | uxrm.getACall() = this) }
}

View File

@@ -0,0 +1,5 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="DataSetSerialization.qhelp" /></qhelp>

View File

@@ -0,0 +1,16 @@
/**
* @name Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types
* @description Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types may lead to the usage of dangerous functionality. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.
* @kind problem
* @problem.severity warning
* @id cs/dataset-serialization/defining-dataset-related-type
* @tags security
*/
import csharp
import DataSetSerialization
from DataSetOrTableRelatedClass dstc
where dstc.fromSource()
select dstc,
"Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."

View File

@@ -0,0 +1,5 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="DataSetSerialization.qhelp" /></qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name Defining a potentially unsafe XML serializer
* @description Defining an XML serializable class that includes members that derive from DataSet or DataTable type may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.
* @kind problem
* @problem.severity error
* @precision medium
* @id cs/dataset-serialization/defining-potentially-unsafe-xml-serializer
* @tags security
*/
import csharp
import DataSetSerialization
from UnsafeXmlSerializerImplementation c, Member m
where
c.fromSource() and
isClassUnsafeXmlSerializerImplementation(c, m)
select m,
"Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details.",
c, c.toString(), m, m.toString()

View File

@@ -0,0 +1,5 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="DataSetSerialization.qhelp" /></qhelp>

View File

@@ -0,0 +1,43 @@
/**
* @name Unsafe type is used in data contract serializer
* @description Unsafe type is used in data contract serializer. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."
* @kind problem
* @problem.severity error
* @precision medium
* @id cs/dataset-serialization/unsafe-type-used-data-contract-serializer
* @tags security
*/
import csharp
import DataSetSerialization
predicate xmlSerializerConstructorArgument(Expr e) {
exists(ObjectCreation oc, Constructor c | e = oc.getArgument(0) |
c = oc.getTarget() and
c.getDeclaringType().getABaseType*().hasQualifiedName("System.Xml.Serialization.XmlSerializer")
)
}
predicate unsafeDataContractTypeCreation(Expr e) {
exists(MethodCall gt |
gt.getTarget().getName() = "GetType" and
e = gt and
gt.getQualifier().getType() instanceof DataSetOrTableRelatedClass
)
or
e.(TypeofExpr).getTypeAccess().getTarget() instanceof DataSetOrTableRelatedClass
}
class Conf extends DataFlow::Configuration {
Conf() { this = "FlowToDataSerializerConstructor" }
override predicate isSource(DataFlow::Node node) { unsafeDataContractTypeCreation(node.asExpr()) }
override predicate isSink(DataFlow::Node node) { xmlSerializerConstructorArgument(node.asExpr()) }
}
from Conf conf, DataFlow::Node source, DataFlow::Node sink
where conf.hasFlow(source, sink)
select sink,
"Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source.",
source, source.toString()

View File

@@ -0,0 +1,5 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<include src="DataSetSerialization.qhelp" /></qhelp>

View File

@@ -0,0 +1,16 @@
/**
* @name XML deserialization with a type type derived from DataSet or DataTable
* @description Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."
* @kind problem
* @problem.severity error
* @precision medium
* @id cs/dataset-serialization/xml-deserialization-with-dataset
* @tags security
*/
import csharp
import DataSetSerialization
from UnsafeXmlReadMethodCall mc
select mc,
"Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details."

View File

@@ -0,0 +1,2 @@
| test0.cs:13:18:13:43 | DerivesFromDeprecatedType1 | Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. |
| test0.cs:59:18:59:38 | AttributeSerializer01 | Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. |

View File

@@ -0,0 +1 @@
experimental/Security Features/Serialization/DefiningDatasetRelatedType.ql

View File

@@ -0,0 +1,2 @@
| test0.cs:15:24:15:32 | MyDataSet | Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | test0.cs:13:18:13:43 | DerivesFromDeprecatedType1 | DerivesFromDeprecatedType1 | test0.cs:15:24:15:32 | MyDataSet | MyDataSet |
| test0.cs:61:25:61:33 | MyDataSet | Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | test0.cs:59:18:59:38 | AttributeSerializer01 | AttributeSerializer01 | test0.cs:61:25:61:33 | MyDataSet | MyDataSet |

View File

@@ -0,0 +1 @@
experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.ql

View File

@@ -0,0 +1,2 @@
| test0.cs:95:49:95:63 | typeof(...) | Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source. | test0.cs:95:49:95:63 | typeof(...) | typeof(...) |
| test0.cs:96:49:96:77 | typeof(...) | Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source. | test0.cs:96:49:96:77 | typeof(...) | typeof(...) |

View File

@@ -0,0 +1 @@
experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql

View File

@@ -0,0 +1 @@
| test0.cs:88:17:88:46 | call to method ReadXmlSchema | Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. |

View File

@@ -0,0 +1 @@
experimental/Security Features/Serialization/XmlDeserializationWithDataSet.ql

View File

@@ -0,0 +1,101 @@
// semmle-extractor-options: /r:System.Data.Common.dll /r:System.Runtime.WindowsRuntime.dll /r:System.Xml.XmlSerializer.dll /r:System.Runtime.Serialization.Xml.dll /r:System.Runtime.Serialization.Xml.dll /r:System.Collections.dll /r:System.Private.Xml.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Extensions.dll /r:System.ComponentModel.TypeConverter.dll /r:System.Xml.ReaderWriter.dll /r:System.IO.FileSystem.dll
using System;
using System.Data;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Xml;
using System.Collections.Generic;
namespace DataSetSerializationTest
{
public class DerivesFromDeprecatedType1 : XmlSerializer // warning:DefiningDatasetRelatedType.ql
{
public DataSet MyDataSet { get; set; } // bug:DefiningPotentiallyUnsafeXmlSerializer.ql
public DerivesFromDeprecatedType1()
{
}
}
/*
* TODO: I cannot use DataContract on a QL unit test
*
[DataContract(Name = "Customer", Namespace = "http://www.contoso.com")]
public class PatternDataContractSerializer : XmlObjectSerializer
{
[DataMember()]
public DataSet MyDataSet { get; set; }
[DataMember()]
public DataTable MyDataTable { get; set; }
PatternDataContractSerializer() { }
private ExtensionDataObject extensionData_Value;
public ExtensionDataObject ExtensionData
{
get
{
return extensionData_Value;
}
set
{
extensionData_Value = value;
}
}
public override void WriteObject(System.IO.Stream stream, object graph) { }
public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) { }
public override bool IsStartObject(System.Xml.XmlDictionaryReader reader) { return false; }
public override void WriteStartObject(System.Xml.XmlDictionaryWriter writer, object graph) { }
public override void WriteEndObject(System.Xml.XmlWriter writer) { }
public override void WriteEndObject(XmlDictionaryWriter writer) { }
public override object ReadObject(System.IO.Stream stream) { return null; }
public override object ReadObject(XmlDictionaryReader reader, bool b) { return null; }
}
*/
[Serializable()]
public class AttributeSerializer01 // warning:DefiningDatasetRelatedType.ql
{
private DataSet MyDataSet; // bug:DefiningPotentiallyUnsafeXmlSerializer.ql
AttributeSerializer01()
{
}
}
class Program
{
static string GetSerializedDataSet(DataSet dataSet)
{
DataTable dataTable = new DataTable("MyTable");
dataTable.Columns.Add("FirstName", typeof(string));
dataTable.Columns.Add("LastName", typeof(string));
dataTable.Columns.Add("Age", typeof(int));
StringWriter writer = new StringWriter();
dataSet.WriteXml(writer, XmlWriteMode.DiffGram);
return writer.ToString();
}
static void datatable_readxmlschema_01(string fileName)
{
using (FileStream fs = File.OpenRead(fileName))
{
DataTable newTable = new DataTable();
System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(fs);
newTable.ReadXmlSchema(reader); //bug:XmlDeserializationWithDataSet.ql
}
}
static void Main(string[] args)
{
XmlSerializer x = new XmlSerializer(typeof(DataSet)); // bug:UnsafeTypeUsedDataContractSerializer.ql
XmlSerializer y = new XmlSerializer(typeof(AttributeSerializer01)); //bug:UnsafeTypeUsedDataContractSerializer.ql
Console.WriteLine("Hello World!");
}
}
}

View File

@@ -7,7 +7,6 @@
* @precision very-high
* @id java/integer-multiplication-cast-to-long
* @tags reliability
* security
* correctness
* types
* external/cwe/cwe-190

View File

@@ -1,74 +0,0 @@
import java
import semmle.code.java.controlflow.Guards
abstract class PathCreation extends Expr {
abstract Expr getInput();
}
class PathsGet extends PathCreation, MethodAccess {
PathsGet() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypePaths and
m.getName() = "get"
)
}
override Expr getInput() { result = this.getAnArgument() }
}
class FileSystemGetPath extends PathCreation, MethodAccess {
FileSystemGetPath() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypeFileSystem and
m.getName() = "getPath"
)
}
override Expr getInput() { result = this.getAnArgument() }
}
class FileCreation extends PathCreation, ClassInstanceExpr {
FileCreation() { this.getConstructedType() instanceof TypeFile }
override Expr getInput() {
result = this.getAnArgument() and
// Relevant arguments include those that are not a `File`.
not result.getType() instanceof TypeFile
}
}
class FileWriterCreation extends PathCreation, ClassInstanceExpr {
FileWriterCreation() { this.getConstructedType().getQualifiedName() = "java.io.FileWriter" }
override Expr getInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
predicate inWeakCheck(Expr e) {
// None of these are sufficient to guarantee that a string is safe.
exists(MethodAccess m, Method def | m.getQualifier() = e and m.getMethod() = def |
def.getName() = "startsWith" or
def.getName() = "endsWith" or
def.getName() = "isEmpty" or
def.getName() = "equals"
)
or
// Checking against `null` has no bearing on path traversal.
exists(EqualityTest b | b.getAnOperand() = e | b.getAnOperand() instanceof NullLiteral)
}
// Ignore cases where the variable has been checked somehow,
// but allow some particularly obviously bad cases.
predicate guarded(VarAccess e) {
exists(PathCreation p | e = p.getInput()) and
exists(ConditionBlock cb, Expr c |
cb.getCondition().getAChildExpr*() = c and
c = e.getVariable().getAnAccess() and
cb.controls(e.getBasicBlock(), true) and
// Disallow a few obviously bad checks.
not inWeakCheck(c)
)
}

View File

@@ -14,8 +14,9 @@
import java
import semmle.code.java.dataflow.FlowSources
import PathsCommon
import semmle.code.java.security.PathCreation
import DataFlow::PathGraph
import TaintedPathCommon
class ContainsDotDotSanitizer extends DataFlow::BarrierGuard {
ContainsDotDotSanitizer() {
@@ -34,7 +35,7 @@ class TaintedPathConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
exists(Expr e | e = sink.asExpr() | e = any(PathCreation p).getInput() and not guarded(e))
exists(Expr e | e = sink.asExpr() | e = any(PathCreation p).getAnInput() and not guarded(e))
}
override predicate isSanitizer(DataFlow::Node node) {
@@ -48,7 +49,7 @@ class TaintedPathConfig extends TaintTracking::Configuration {
from DataFlow::PathNode source, DataFlow::PathNode sink, PathCreation p, TaintedPathConfig conf
where
sink.getNode().asExpr() = p.getInput() and
sink.getNode().asExpr() = p.getAnInput() and
conf.hasFlowPath(source, sink)
select p, source, sink, "$@ flows to here and is used in a path.", source.getNode(),
"User-provided value"

View File

@@ -0,0 +1,33 @@
/**
* Models a very basic guard for the tainted path queries.
*/
import java
import semmle.code.java.controlflow.Guards
import semmle.code.java.security.PathCreation
private predicate inWeakCheck(Expr e) {
// None of these are sufficient to guarantee that a string is safe.
exists(MethodAccess m, Method def | m.getQualifier() = e and m.getMethod() = def |
def.getName() = "startsWith" or
def.getName() = "endsWith" or
def.getName() = "isEmpty" or
def.getName() = "equals"
)
or
// Checking against `null` has no bearing on path traversal.
exists(EqualityTest b | b.getAnOperand() = e | b.getAnOperand() instanceof NullLiteral)
}
// Ignore cases where the variable has been checked somehow,
// but allow some particularly obviously bad cases.
predicate guarded(VarAccess e) {
exists(PathCreation p | e = p.getAnInput()) and
exists(ConditionBlock cb, Expr c |
cb.getCondition().getAChildExpr*() = c and
c = e.getVariable().getAnAccess() and
cb.controls(e.getBasicBlock(), true) and
// Disallow a few obviously bad checks.
not inWeakCheck(c)
)
}

View File

@@ -14,15 +14,18 @@
import java
import semmle.code.java.dataflow.FlowSources
import PathsCommon
import semmle.code.java.security.PathCreation
import DataFlow::PathGraph
import TaintedPathCommon
class TaintedPathLocalConfig extends TaintTracking::Configuration {
TaintedPathLocalConfig() { this = "TaintedPathLocalConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PathCreation p).getInput() }
override predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PathCreation p).getAnInput()
}
}
from
@@ -30,7 +33,7 @@ from
TaintedPathLocalConfig conf
where
e = sink.getNode().asExpr() and
e = p.getInput() and
e = p.getAnInput() and
conf.hasFlowPath(source, sink) and
not guarded(e)
select p, source, sink, "$@ flows to here and is used in a path.", source.getNode(),

View File

@@ -1,10 +1,7 @@
import java
import semmle.code.java.dataflow.FlowSources
import DataFlow
import semmle.code.java.frameworks.Jndi
import semmle.code.java.frameworks.UnboundId
import semmle.code.java.frameworks.SpringLdap
import semmle.code.java.frameworks.ApacheLdap
import semmle.code.java.security.LdapInjection
/**
* A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
@@ -16,391 +13,9 @@ class LdapInjectionFlowConfig extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof LdapInjectionSink }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof LdapInjectionSanitizer }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
ldapNameStep(node1, node2) or
ldapNameAddAllStep(node1, node2) or
ldapNameGetCloneStep(node1, node2) or
filterStep(node1, node2) or
filterToStringStep(node1, node2) or
unboundIdSearchRequestStep(node1, node2) or
unboundIdSearchRequestDuplicateStep(node1, node2) or
unboundIdSearchRequestSetStep(node1, node2) or
ldapQueryStep(node1, node2) or
ldapQueryBaseStep(node1, node2) or
ldapQueryBuilderStep(node1, node2) or
hardcodedFilterStep(node1, node2) or
springLdapFilterToStringStep(node1, node2) or
ldapNameBuilderStep(node1, node2) or
ldapNameBuilderBuildStep(node1, node2) or
ldapUtilsStep(node1, node2) or
apacheSearchRequestStep(node1, node2) or
apacheSearchRequestGetStep(node1, node2) or
apacheLdapDnStep(node1, node2) or
apacheLdapDnGetStep(node1, node2)
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
any(LdapInjectionAdditionalTaintStep a).step(pred, succ)
}
}
/**
* JNDI sink for LDAP injection vulnerabilities, i.e. 1st (DN) or 2nd (filter) argument to
* `search` method from `DirContext`.
*/
predicate jndiLdapInjectionSinkMethod(Method m, int index) {
m.getDeclaringType().getAnAncestor() instanceof TypeDirContext and
m.hasName("search") and
index in [0 .. 1]
}
/**
* UnboundID sink for LDAP injection vulnerabilities,
* i.e. LDAPConnection.search, LDAPConnection.asyncSearch or LDAPConnection.searchForEntry method.
*/
predicate unboundIdLdapInjectionSinkMethod(Method m, int index) {
exists(Parameter param | m.getParameter(index) = param and not param.isVarargs() |
m instanceof MethodUnboundIdLDAPConnectionSearch or
m instanceof MethodUnboundIdLDAPConnectionAsyncSearch or
m instanceof MethodUnboundIdLDAPConnectionSearchForEntry
)
}
/**
* Spring LDAP sink for LDAP injection vulnerabilities,
* i.e. LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method.
*/
predicate springLdapInjectionSinkMethod(Method m, int index) {
// LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method
(
m instanceof MethodSpringLdapTemplateAuthenticate or
m instanceof MethodSpringLdapTemplateFind or
m instanceof MethodSpringLdapTemplateFindOne or
m instanceof MethodSpringLdapTemplateSearch or
m instanceof MethodSpringLdapTemplateSearchForContext or
m instanceof MethodSpringLdapTemplateSearchForObject
) and
(
// Parameter index is 1 (DN or query) or 2 (filter) if method is not authenticate
index in [0 .. 1] and
not m instanceof MethodSpringLdapTemplateAuthenticate
or
// But it's not the last parameter in case of authenticate method (last param is password)
index in [0 .. 1] and
index < m.getNumberOfParameters() - 1 and
m instanceof MethodSpringLdapTemplateAuthenticate
)
}
/** Apache LDAP API sink for LDAP injection vulnerabilities, i.e. LdapConnection.search method. */
predicate apacheLdapInjectionSinkMethod(Method m, int index) {
exists(Parameter param | m.getParameter(index) = param and not param.isVarargs() |
m.getDeclaringType().getAnAncestor() instanceof TypeApacheLdapConnection and
m.hasName("search")
)
}
/** Holds if parameter at index `index` in method `m` is LDAP injection sink. */
predicate ldapInjectionSinkMethod(Method m, int index) {
jndiLdapInjectionSinkMethod(m, index) or
unboundIdLdapInjectionSinkMethod(m, index) or
springLdapInjectionSinkMethod(m, index) or
apacheLdapInjectionSinkMethod(m, index)
}
/** A data flow sink for unvalidated user input that is used to construct LDAP queries. */
class LdapInjectionSink extends DataFlow::ExprNode {
LdapInjectionSink() {
exists(MethodAccess ma, Method m, int index |
ma.getMethod() = m and
ma.getArgument(index) = this.getExpr() and
ldapInjectionSinkMethod(m, index)
)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `LdapName`,
* i.e. `new LdapName(tainted)`.
*/
predicate ldapNameStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeLdapName |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `List<Rdn>` and `LdapName`,
* i.e. `new LdapName().addAll(tainted)`.
*/
predicate ldapNameAddAllStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma |
n1.asExpr() = ma.getAnArgument() and
(n2.asExpr() = ma or n2.asExpr() = ma.getQualifier())
|
ma.getMethod() instanceof MethodLdapNameAddAll
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `LdapName` and `LdapName` or
* `String`, i.e. `taintedLdapName.clone()`, `taintedLdapName.getAll()`,
* `taintedLdapName.getRdns()` or `taintedLdapName.toString()`.
*/
predicate ldapNameGetCloneStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodLdapNameClone or
m instanceof MethodLdapNameGetAll or
m instanceof MethodLdapNameGetRdns or
m instanceof MethodLdapNameToString
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and UnboundID `Filter`,
* i.e. `Filter.create*(tainted)`.
*/
predicate filterStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodUnboundIdFilterCreate or
m instanceof MethodUnboundIdFilterCreateANDFilter or
m instanceof MethodUnboundIdFilterCreateNOTFilter or
m instanceof MethodUnboundIdFilterCreateORFilter or
m instanceof MethodUnboundIdFilterSimplifyFilter
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between UnboundID `Filter` and `String`,
* i.e. `taintedFilter.toString()` or `taintedFilter.toString(buffer)`.
*/
predicate filterToStringStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
(n2.asExpr() = ma or n2.asExpr() = ma.getAnArgument())
|
ma.getMethod() = m and
m.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
(m.hasName("toString") or m.hasName("toNormalizedString"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and UnboundID
* `SearchRequest`, i.e. `new SearchRequest(tainted)`.
*/
predicate unboundIdSearchRequestStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc, int index, Parameter param |
cc.getConstructedType() instanceof TypeUnboundIdSearchRequest
|
n1.asExpr() = cc.getArgument(index) and
n2.asExpr() = cc and
cc.getConstructor().getParameter(index) = param and
not param.isVarargs()
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between UnboundID `SearchRequest`
* and UnboundID `SearchRequest`, i.e. `taintedSearchRequest.duplicate()`.
*/
predicate unboundIdSearchRequestDuplicateStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeUnboundIdReadOnlySearchRequest and
m.hasName("duplicate")
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between DN or filter and UnboundID
* `SearchRequest`, i.e. `searchRequest.setBaseDN(tainted)` or `searchRequest.setFilter(tainted)`.
*/
predicate unboundIdSearchRequestSetStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma.getQualifier() and
ma.getMethod() = m
|
m instanceof MethodUnboundIdSearchRequestSetBaseDN or
m instanceof MethodUnboundIdSearchRequestSetFilter
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring `LdapQuery`,
* i.e. `LdapQueryBuilder.query().filter(tainted)` or `LdapQueryBuilder.query().base(tainted)`.
*/
predicate ldapQueryStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m, int index |
n1.asExpr() = ma.getArgument(index) and
n2.asExpr() = ma and
ma.getMethod() = m and
index = 0
|
m instanceof MethodSpringLdapQueryBuilderFilter or
m instanceof MethodSpringLdapQueryBuilderBase
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `LdapQueryBuilder` and
* `Name`, i.e. `taintedLdapQueryBuilder.base()`.
*/
predicate ldapQueryBaseStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodSpringLdapQueryBuilderBase and
m.getNumberOfParameters() = 0
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `LdapQueryBuilder`,
* `ConditionCriteria` or `ContainerCriteria`, i.e. when the query is built, for example
* `query().base(tainted).where("objectclass").is("person")`.
*/
predicate ldapQueryBuilderStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
(
m.getDeclaringType() instanceof TypeSpringLdapQueryBuilder or
m.getDeclaringType() instanceof TypeSpringConditionCriteria or
m.getDeclaringType() instanceof TypeSpringContainerCriteria
) and
(
m.getReturnType() instanceof TypeSpringLdapQueryBuilder or
m.getReturnType() instanceof TypeSpringConditionCriteria or
m.getReturnType() instanceof TypeSpringContainerCriteria
)
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring
* `HardcodedFilter`, i.e. `new HardcodedFilter(tainted)`.
*/
predicate hardcodedFilterStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeSpringHardcodedFilter |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `Filter` and
* `String`, i.e. `taintedFilter.toString()`, `taintedFilter.encode()` or
* `taintedFilter.encode(buffer)`.
*/
predicate springLdapFilterToStringStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
(n2.asExpr() = ma or n2.asExpr() = ma.getAnArgument()) and
ma.getMethod() = m
|
m.getDeclaringType().getAnAncestor() instanceof TypeSpringLdapFilter and
(m.hasName("encode") or m.hasName("toString"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring
* `LdapNameBuilder`, i.e. `LdapNameBuilder.newInstance(tainted)` or
* `LdapNameBuilder.newInstance().add(tainted)`.
*/
predicate ldapNameBuilderStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
(n2.asExpr() = ma or n2.asExpr() = ma.getQualifier()) and
ma.getMethod() = m and
m.getNumberOfParameters() = 1
|
m instanceof MethodSpringLdapNameBuilderNewInstance or
m instanceof MethodSpringLdapNameBuilderAdd
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between tainted Spring `LdapNameBuilder`
* and `LdapName`, `LdapNameBuilder.build()`.
*/
predicate ldapNameBuilderBuildStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() instanceof MethodSpringLdapNameBuilderBuild
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `LdapName` via
* Spring `LdapUtils.newLdapName`, i.e. `LdapUtils.newLdapName(tainted)`.
*/
predicate ldapUtilsStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma | n1.asExpr() = ma.getAnArgument() and n2.asExpr() = ma |
ma.getMethod() instanceof MethodSpringLdapUtilsNewLdapName
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Apache LDAP API
* `SearchRequest`, i.e. `searchRequest.setFilter(tainted)` or `searchRequest.setBase(tainted)`.
*/
predicate apacheSearchRequestStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma.getQualifier()
|
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheSearchRequest and
(m.hasName("setFilter") or m.hasName("setBase"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Apache LDAP API `SearchRequest`
* and filter or DN i.e. `tainterSearchRequest.getFilter()` or `taintedSearchRequest.getBase()`.
*/
predicate apacheSearchRequestGetStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheSearchRequest and
(m.hasName("getFilter") or m.hasName("getBase"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Apache LDAP API
* `Dn`, i.e. `new Dn(tainted)`.
*/
predicate apacheLdapDnStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeApacheDn |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Apache LDAP API `Dn`
* and `String` i.e. `taintedDn.getName()`, `taintedDn.getNormName()` or `taintedDn.toString()`.
*/
predicate apacheLdapDnGetStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheDn and
(m.hasName("getName") or m.hasName("getNormName") or m.hasName("toString"))
)
}

View File

@@ -11,7 +11,8 @@
*/
import java
import ResponseSplitting
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ResponseSplitting
import DataFlow::PathGraph
class ResponseSplittingConfig extends TaintTracking::Configuration {
@@ -19,7 +20,7 @@ class ResponseSplittingConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
not source instanceof WhitelistedSource
not source instanceof SafeHeaderSplittingSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }

View File

@@ -1,38 +0,0 @@
import java
import semmle.code.java.frameworks.Servlets
import semmle.code.java.dataflow.FlowSources
/**
* Header-splitting sinks. Expressions that end up in an HTTP header.
*/
class HeaderSplittingSink extends DataFlow::ExprNode {
HeaderSplittingSink() {
exists(ResponseAddCookieMethod m, MethodAccess ma |
ma.getMethod() = m and
this.getExpr() = ma.getArgument(0)
)
or
exists(ResponseAddHeaderMethod m, MethodAccess ma |
ma.getMethod() = m and
this.getExpr() = ma.getAnArgument()
)
or
exists(ResponseSetHeaderMethod m, MethodAccess ma |
ma.getMethod() = m and
this.getExpr() = ma.getAnArgument()
)
or
exists(JaxRsResponseBuilder builder, Method m |
m = builder.getAMethod() and m.getName() = "header"
|
this.getExpr() = m.getAReference().getArgument(1)
)
}
}
class WhitelistedSource extends DataFlow::ExprNode {
WhitelistedSource() {
this.asExpr().(MethodAccess).getMethod() instanceof HttpServletRequestGetHeaderMethod or
this.asExpr().(MethodAccess).getMethod() instanceof CookieGetNameMethod
}
}

View File

@@ -12,7 +12,7 @@
import java
import semmle.code.java.dataflow.FlowSources
import ResponseSplitting
import semmle.code.java.security.ResponseSplitting
import DataFlow::PathGraph
class ResponseSplittingLocalConfig extends TaintTracking::Configuration {

View File

@@ -22,7 +22,10 @@ import semmle.code.java.security.XSS
*/
class PrintStackTraceMethod extends Method {
PrintStackTraceMethod() {
getDeclaringType().hasQualifiedName("java.lang", "Throwable") and
getDeclaringType()
.getSourceDeclaration()
.getASourceSupertype*()
.hasQualifiedName("java.lang", "Throwable") and
getName() = "printStackTrace"
}
}
@@ -96,7 +99,8 @@ class StackTraceStringToXssSinkFlowConfig extends TaintTracking2::Configuration
*/
predicate printsStackExternally(MethodAccess call, Expr stackTrace) {
printsStackToWriter(call) and
call.getQualifier() = stackTrace
call.getQualifier() = stackTrace and
not call.getQualifier() instanceof SuperAccess
}
/**

View File

@@ -3,7 +3,7 @@
* @description Using broken or weak cryptographic algorithms can allow an attacker to compromise security.
* @kind path-problem
* @problem.severity warning
* @precision medium
* @precision high
* @id java/weak-cryptographic-algorithm
* @tags security
* external/cwe/cwe-327

View File

@@ -0,0 +1,49 @@
public class InsecureBasicAuth {
/**
* Test basic authentication with Apache HTTP request.
*/
public void testApacheHttpRequest(String username, String password) {
{
// BAD: basic authentication over HTTP
String url = "http://www.example.com/rest/getuser.do?uid=abcdx";
}
{
// GOOD: basic authentication over HTTPS
String url = "https://www.example.com/rest/getuser.do?uid=abcdx";
}
HttpPost post = new HttpPost(url);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Java HTTP URL connection.
*/
public void testHttpUrlConnection(String username, String password) {
{
// BAD: basic authentication over HTTP
String urlStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
}
{
// GOOD: basic authentication over HTTPS
String urlStr = "https://www.example.com/rest/getuser.do?uid=abcdx";
}
String authString = username + ":" + password;
String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8"));
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding);
}
}

View File

@@ -0,0 +1,30 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>Basic authentication only obfuscates username/password in Base64 encoding, which can be easily recognized and reversed, thus it must not be transmitted over the cleartext HTTP channel. Transmission of sensitive information not in HTTPS is vulnerable to packet sniffing.</p>
</overview>
<recommendation>
<p>Either use a more secure authentication mechanism like digest authentication or federated authentication, or use the HTTPS communication protocol.</p>
</recommendation>
<example>
<p>The following example shows two ways of using basic authentication. In the 'BAD' case, the credentials are transmitted over HTTP. In the 'GOOD' case, the credentials are transmitted over HTTPS.</p>
<sample src="InsecureBasicAuth.java" />
</example>
<references>
<li>
<a href="https://cwe.mitre.org/data/definitions/522">CWE-522</a>
</li>
<li>
SonarSource rule:
<a href="https://rules.sonarsource.com/java/tag/owasp/RSPEC-2647">Basic authentication should not be used</a>
</li>
<li>
Acunetix:
<a href="https://www.acunetix.com/vulnerabilities/web/basic-authentication-over-http/">WEB VULNERABILITIES INDEX - Basic authentication over HTTP</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,263 @@
/**
* @name Insecure basic authentication
* @description Basic authentication only obfuscates username/password in Base64 encoding, which can be easily recognized and reversed. Transmission of sensitive information not over HTTPS is vulnerable to packet sniffing.
* @kind path-problem
* @id java/insecure-basic-auth
* @tags security
* external/cwe-522
* external/cwe-319
*/
import java
import semmle.code.java.frameworks.Networking
import semmle.code.java.dataflow.TaintTracking
import DataFlow::PathGraph
/**
* Gets a regular expression for matching private hosts, which only matches the host portion therefore checking for port is not necessary.
*/
private string getPrivateHostRegex() {
result =
"(?i)localhost(?:[:/?#].*)?|127\\.0\\.0\\.1(?:[:/?#].*)?|10(?:\\.[0-9]+){3}(?:[:/?#].*)?|172\\.16(?:\\.[0-9]+){2}(?:[:/?#].*)?|192.168(?:\\.[0-9]+){2}(?:[:/?#].*)?|\\[?0:0:0:0:0:0:0:1\\]?(?:[:/?#].*)?|\\[?::1\\]?(?:[:/?#].*)?"
}
/**
* The Java class `org.apache.http.client.methods.HttpRequestBase`. Popular subclasses include `HttpGet`, `HttpPost`, and `HttpPut`.
* And the Java class `org.apache.http.message.BasicHttpRequest`.
*/
class ApacheHttpRequest extends RefType {
ApacheHttpRequest() {
this
.getASourceSupertype*()
.hasQualifiedName("org.apache.http.client.methods", "HttpRequestBase") or
this.getASourceSupertype*().hasQualifiedName("org.apache.http.message", "BasicHttpRequest")
}
}
/**
* Class of Java URL constructor.
*/
class URLConstructor extends ClassInstanceExpr {
URLConstructor() { this.getConstructor().getDeclaringType() instanceof TypeUrl }
predicate hasHttpStringArg() {
this.getConstructor().getParameter(0).getType() instanceof TypeString and
(
// URLs constructed with any of the three string constructors below:
// `URL(String protocol, String host, int port, String file)`,
// `URL(String protocol, String host, int port, String file, URLStreamHandler handler)`,
// `URL(String protocol, String host, String file)`
this.getConstructor().getNumberOfParameters() > 1 and
concatHttpString(getArgument(0), this.getArgument(1)) // First argument contains the protocol part and the second argument contains the host part.
or
// URLs constructed with the string constructor `URL(String spec)`
this.getConstructor().getNumberOfParameters() = 1 and
this.getArgument(0) instanceof HttpString // First argument contains the whole spec.
)
}
}
/**
* Class of Java URI constructor.
*/
class URIConstructor extends ClassInstanceExpr {
URIConstructor() { this.getConstructor().getDeclaringType().hasQualifiedName("java.net", "URI") }
predicate hasHttpStringArg() {
(
this.getNumArgument() = 1 and
this.getArgument(0) instanceof HttpString // `URI(String str)`
or
this.getNumArgument() = 4 and
concatHttpString(this.getArgument(0), this.getArgument(1)) // `URI(String scheme, String host, String path, String fragment)`
or
this.getNumArgument() = 5 and
concatHttpString(this.getArgument(0), this.getArgument(1)) // `URI(String scheme, String authority, String path, String query, String fragment)` without user-info in authority
or
this.getNumArgument() = 7 and
concatHttpString(this.getArgument(0), this.getArgument(2)) // `URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)`
)
}
}
/**
* String of HTTP URLs not in private domains.
*/
class HttpStringLiteral extends StringLiteral {
HttpStringLiteral() {
// Match URLs with the HTTP protocol and without private IP addresses to reduce false positives.
exists(string s | this.getRepresentedString() = s |
s.regexpMatch("(?i)http://[\\[a-zA-Z0-9].*") and
not s.substring(7, s.length()).regexpMatch(getPrivateHostRegex())
)
}
}
/**
* Checks both parts of protocol and host.
*/
predicate concatHttpString(Expr protocol, Expr host) {
(
protocol.(CompileTimeConstantExpr).getStringValue().regexpMatch("(?i)http(://)?") or
protocol
.(VarAccess)
.getVariable()
.getAnAssignedValue()
.(CompileTimeConstantExpr)
.getStringValue()
.regexpMatch("(?i)http(://)?")
) and
not exists(string hostString |
hostString = host.(CompileTimeConstantExpr).getStringValue() or
hostString =
host.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue()
|
hostString.length() = 0 or // Empty host is loopback address
hostString.regexpMatch(getPrivateHostRegex())
)
}
/** Gets the leftmost operand in a concatenated string */
Expr getLeftmostConcatOperand(Expr expr) {
if expr instanceof AddExpr
then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand())
else result = expr
}
/**
* String concatenated with `HttpStringLiteral`.
*/
class HttpString extends Expr {
HttpString() {
this instanceof HttpStringLiteral
or
concatHttpString(this.(AddExpr).getLeftOperand(),
getLeftmostConcatOperand(this.(AddExpr).getRightOperand()))
}
}
/**
* String pattern of basic authentication.
*/
class BasicAuthString extends StringLiteral {
BasicAuthString() { exists(string s | this.getRepresentedString() = s | s.matches("Basic %")) }
}
/**
* String concatenated with `BasicAuthString`.
*/
predicate builtFromBasicAuthStringConcat(Expr expr) {
expr instanceof BasicAuthString
or
builtFromBasicAuthStringConcat(expr.(AddExpr).getLeftOperand())
or
exists(Expr other | builtFromBasicAuthStringConcat(other) |
exists(Variable var | var.getAnAssignedValue() = other and var.getAnAccess() = expr)
)
}
/** The `openConnection` method of Java URL. Not to include `openStream` since it won't be used in this query. */
class HttpURLOpenMethod extends Method {
HttpURLOpenMethod() {
this.getDeclaringType() instanceof TypeUrl and
this.getName() = "openConnection"
}
}
/** Constructor of `ApacheHttpRequest` */
predicate apacheHttpRequest(DataFlow::Node node1, DataFlow::Node node2) {
exists(ConstructorCall cc |
cc.getConstructedType() instanceof ApacheHttpRequest and
node2.asExpr() = cc and
cc.getAnArgument() = node1.asExpr()
)
}
/** `URI` methods */
predicate createURI(DataFlow::Node node1, DataFlow::Node node2) {
exists(
URIConstructor cc // new URI
|
node2.asExpr() = cc and
cc.getArgument(0) = node1.asExpr()
)
or
exists(
StaticMethodAccess ma // URI.create
|
ma.getMethod().getDeclaringType().hasQualifiedName("java.net", "URI") and
ma.getMethod().hasName("create") and
node1.asExpr() = ma.getArgument(0) and
node2.asExpr() = ma
)
}
/** Constructors of `URL` */
predicate createURL(DataFlow::Node node1, DataFlow::Node node2) {
exists(URLConstructor cc |
node2.asExpr() = cc and
cc.getArgument(0) = node1.asExpr()
)
}
/** Method call of `HttpURLOpenMethod` */
predicate urlOpen(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma |
ma.getMethod() instanceof HttpURLOpenMethod and
node1.asExpr() = ma.getQualifier() and
ma = node2.asExpr()
)
}
/** Constructor of `BasicRequestLine` */
predicate basicRequestLine(DataFlow::Node node1, DataFlow::Node node2) {
exists(ConstructorCall mcc |
mcc.getConstructedType().hasQualifiedName("org.apache.http.message", "BasicRequestLine") and
mcc.getArgument(1) = node1.asExpr() and // `BasicRequestLine(String method, String uri, ProtocolVersion version)
node2.asExpr() = mcc
)
}
class BasicAuthFlowConfig extends TaintTracking::Configuration {
BasicAuthFlowConfig() { this = "InsecureBasicAuth::BasicAuthFlowConfig" }
override predicate isSource(DataFlow::Node src) {
src.asExpr() instanceof HttpString
or
exists(URLConstructor uc |
uc.hasHttpStringArg() and
src.asExpr() = uc.getArgument(0)
)
or
exists(URIConstructor uc |
uc.hasHttpStringArg() and
src.asExpr() = uc.getArgument(0)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
sink.asExpr() = ma.getQualifier() and
(
ma.getMethod().hasName("addHeader") or
ma.getMethod().hasName("setHeader") or
ma.getMethod().hasName("setRequestProperty")
) and
ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "Authorization" and
builtFromBasicAuthStringConcat(ma.getArgument(1))
)
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
apacheHttpRequest(node1, node2) or
createURI(node1, node2) or
basicRequestLine(node1, node2) or
createURL(node1, node2) or
urlOpen(node1, node2)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, BasicAuthFlowConfig config
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Insecure basic authentication from $@.", source.getNode(),
"HTTP url"

View File

@@ -194,7 +194,16 @@ class TypeVariable extends BoundedType, @typevariable {
* and the second wildcard has a lower bound of `Float`.
*/
class Wildcard extends BoundedType, @wildcard {
/** Holds if this wildcard has an upper bound. */
/**
* Holds if this wildcard is either unconstrained (i.e. `?`) or
* has a type bound.
*/
override predicate hasTypeBound() { BoundedType.super.hasTypeBound() }
/**
* Holds if this wildcard is either unconstrained (i.e. `?`) or
* has an upper bound.
*/
predicate hasUpperBound() { wildcards(this, _, 1) }
/** Holds if this wildcard has a lower bound. */

View File

@@ -0,0 +1,413 @@
/** Provides classes to reason about LDAP injection attacks. */
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.frameworks.Jndi
import semmle.code.java.frameworks.UnboundId
import semmle.code.java.frameworks.SpringLdap
import semmle.code.java.frameworks.ApacheLdap
/** A data flow sink for unvalidated user input that is used to construct LDAP queries. */
abstract class LdapInjectionSink extends DataFlow::Node { }
/** A sanitizer that prevents LDAP injection attacks. */
abstract class LdapInjectionSanitizer extends DataFlow::Node { }
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to the `LdapInjectionFlowConfig`.
*/
class LdapInjectionAdditionalTaintStep extends TaintTracking::Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for the `LdapInjectionFlowConfig` configuration.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/** Default sink for LDAP injection vulnerabilities. */
private class DefaultLdapInjectionSink extends LdapInjectionSink {
DefaultLdapInjectionSink() {
exists(MethodAccess ma, Method m, int index |
ma.getMethod() = m and
ma.getArgument(index) = this.asExpr() and
ldapInjectionSinkMethod(m, index)
)
}
}
/** Holds if the method parameter at `index` is susceptible to an LDAP injection attack. */
private predicate ldapInjectionSinkMethod(Method m, int index) {
jndiLdapInjectionSinkMethod(m, index) or
unboundIdLdapInjectionSinkMethod(m, index) or
springLdapInjectionSinkMethod(m, index) or
apacheLdapInjectionSinkMethod(m, index)
}
/** Holds if the JNDI method parameter at `index` is susceptible to an LDAP injection attack. */
private predicate jndiLdapInjectionSinkMethod(Method m, int index) {
m.getDeclaringType().getAnAncestor() instanceof TypeDirContext and
m.hasName("search") and
index in [0 .. 1]
}
/** Holds if the UnboundID method parameter at `index` is susceptible to an LDAP injection attack. */
private predicate unboundIdLdapInjectionSinkMethod(Method m, int index) {
exists(Parameter param | m.getParameter(index) = param and not param.isVarargs() |
m instanceof MethodUnboundIdLDAPConnectionSearch or
m instanceof MethodUnboundIdLDAPConnectionAsyncSearch or
m instanceof MethodUnboundIdLDAPConnectionSearchForEntry
)
}
/** Holds if the Spring method parameter at `index` is susceptible to an LDAP injection attack. */
private predicate springLdapInjectionSinkMethod(Method m, int index) {
// LdapTemplate.authenticate, LdapTemplate.find* or LdapTemplate.search* method
(
m instanceof MethodSpringLdapTemplateAuthenticate or
m instanceof MethodSpringLdapTemplateFind or
m instanceof MethodSpringLdapTemplateFindOne or
m instanceof MethodSpringLdapTemplateSearch or
m instanceof MethodSpringLdapTemplateSearchForContext or
m instanceof MethodSpringLdapTemplateSearchForObject
) and
(
// Parameter index is 1 (DN or query) or 2 (filter) if method is not authenticate
index in [0 .. 1] and
not m instanceof MethodSpringLdapTemplateAuthenticate
or
// But it's not the last parameter in case of authenticate method (last param is password)
index in [0 .. 1] and
index < m.getNumberOfParameters() - 1 and
m instanceof MethodSpringLdapTemplateAuthenticate
)
}
/** Holds if the Apache LDAP API method parameter at `index` is susceptible to an LDAP injection attack. */
private predicate apacheLdapInjectionSinkMethod(Method m, int index) {
exists(Parameter param | m.getParameter(index) = param and not param.isVarargs() |
m.getDeclaringType().getAnAncestor() instanceof TypeApacheLdapConnection and
m.hasName("search")
)
}
/** A sanitizer that clears the taint on (boxed) primitive types. */
private class DefaultLdapSanitizer extends LdapInjectionSanitizer {
DefaultLdapSanitizer() {
this.getType() instanceof PrimitiveType or
this.getType() instanceof BoxedType
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `LdapName`,
* i.e. `new LdapName(tainted)`.
*/
private predicate ldapNameStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeLdapName |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `List<Rdn>` and `LdapName`,
* i.e. `new LdapName().addAll(tainted)`.
*/
private predicate ldapNameAddAllStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma |
n1.asExpr() = ma.getAnArgument() and
(n2.asExpr() = ma or n2.asExpr() = ma.getQualifier())
|
ma.getMethod() instanceof MethodLdapNameAddAll
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `LdapName` and `LdapName` or
* `String`, i.e. `taintedLdapName.clone()`, `taintedLdapName.getAll()`,
* `taintedLdapName.getRdns()` or `taintedLdapName.toString()`.
*/
private predicate ldapNameGetCloneStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodLdapNameClone or
m instanceof MethodLdapNameGetAll or
m instanceof MethodLdapNameGetRdns or
m instanceof MethodLdapNameToString
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and UnboundID `Filter`,
* i.e. `Filter.create*(tainted)`.
*/
private predicate filterStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodUnboundIdFilterCreate or
m instanceof MethodUnboundIdFilterCreateANDFilter or
m instanceof MethodUnboundIdFilterCreateNOTFilter or
m instanceof MethodUnboundIdFilterCreateORFilter or
m instanceof MethodUnboundIdFilterSimplifyFilter
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between UnboundID `Filter` and `String`,
* i.e. `taintedFilter.toString()` or `taintedFilter.toString(buffer)`.
*/
private predicate filterToStringStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
(n2.asExpr() = ma or n2.asExpr() = ma.getAnArgument())
|
ma.getMethod() = m and
m.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
(m.hasName("toString") or m.hasName("toNormalizedString"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and UnboundID
* `SearchRequest`, i.e. `new SearchRequest(tainted)`.
*/
private predicate unboundIdSearchRequestStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc, int index, Parameter param |
cc.getConstructedType() instanceof TypeUnboundIdSearchRequest
|
n1.asExpr() = cc.getArgument(index) and
n2.asExpr() = cc and
cc.getConstructor().getParameter(index) = param and
not param.isVarargs()
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between UnboundID `SearchRequest`
* and UnboundID `SearchRequest`, i.e. `taintedSearchRequest.duplicate()`.
*/
private predicate unboundIdSearchRequestDuplicateStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeUnboundIdReadOnlySearchRequest and
m.hasName("duplicate")
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between DN or filter and UnboundID
* `SearchRequest`, i.e. `searchRequest.setBaseDN(tainted)` or `searchRequest.setFilter(tainted)`.
*/
private predicate unboundIdSearchRequestSetStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma.getQualifier() and
ma.getMethod() = m
|
m instanceof MethodUnboundIdSearchRequestSetBaseDN or
m instanceof MethodUnboundIdSearchRequestSetFilter
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring `LdapQuery`,
* i.e. `LdapQueryBuilder.query().filter(tainted)` or `LdapQueryBuilder.query().base(tainted)`.
*/
private predicate ldapQueryStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m, int index |
n1.asExpr() = ma.getArgument(index) and
n2.asExpr() = ma and
ma.getMethod() = m and
index = 0
|
m instanceof MethodSpringLdapQueryBuilderFilter or
m instanceof MethodSpringLdapQueryBuilderBase
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `LdapQueryBuilder` and
* `Name`, i.e. `taintedLdapQueryBuilder.base()`.
*/
private predicate ldapQueryBaseStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
m instanceof MethodSpringLdapQueryBuilderBase and
m.getNumberOfParameters() = 0
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `LdapQueryBuilder`,
* `ConditionCriteria` or `ContainerCriteria`, i.e. when the query is built, for example
* `query().base(tainted).where("objectclass").is("person")`.
*/
private predicate ldapQueryBuilderStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
ma.getMethod() = m
|
(
m.getDeclaringType() instanceof TypeSpringLdapQueryBuilder or
m.getDeclaringType() instanceof TypeSpringConditionCriteria or
m.getDeclaringType() instanceof TypeSpringContainerCriteria
) and
(
m.getReturnType() instanceof TypeSpringLdapQueryBuilder or
m.getReturnType() instanceof TypeSpringConditionCriteria or
m.getReturnType() instanceof TypeSpringContainerCriteria
)
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring
* `HardcodedFilter`, i.e. `new HardcodedFilter(tainted)`.
*/
private predicate hardcodedFilterStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeSpringHardcodedFilter |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Spring `Filter` and
* `String`, i.e. `taintedFilter.toString()`, `taintedFilter.encode()` or
* `taintedFilter.encode(buffer)`.
*/
private predicate springLdapFilterToStringStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getQualifier() and
(n2.asExpr() = ma or n2.asExpr() = ma.getAnArgument()) and
ma.getMethod() = m
|
m.getDeclaringType().getAnAncestor() instanceof TypeSpringLdapFilter and
(m.hasName("encode") or m.hasName("toString"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Spring
* `LdapNameBuilder`, i.e. `LdapNameBuilder.newInstance(tainted)` or
* `LdapNameBuilder.newInstance().add(tainted)`.
*/
private predicate ldapNameBuilderStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
(n2.asExpr() = ma or n2.asExpr() = ma.getQualifier()) and
ma.getMethod() = m and
m.getNumberOfParameters() = 1
|
m instanceof MethodSpringLdapNameBuilderNewInstance or
m instanceof MethodSpringLdapNameBuilderAdd
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between tainted Spring `LdapNameBuilder`
* and `LdapName`, `LdapNameBuilder.build()`.
*/
private predicate ldapNameBuilderBuildStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() instanceof MethodSpringLdapNameBuilderBuild
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and `LdapName` via
* Spring `LdapUtils.newLdapName`, i.e. `LdapUtils.newLdapName(tainted)`.
*/
private predicate ldapUtilsStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma | n1.asExpr() = ma.getAnArgument() and n2.asExpr() = ma |
ma.getMethod() instanceof MethodSpringLdapUtilsNewLdapName
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Apache LDAP API
* `SearchRequest`, i.e. `searchRequest.setFilter(tainted)` or `searchRequest.setBase(tainted)`.
*/
private predicate apacheSearchRequestStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma.getQualifier()
|
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheSearchRequest and
(m.hasName("setFilter") or m.hasName("setBase"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Apache LDAP API `SearchRequest`
* and filter or DN i.e. `tainterSearchRequest.getFilter()` or `taintedSearchRequest.getBase()`.
*/
private predicate apacheSearchRequestGetStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheSearchRequest and
(m.hasName("getFilter") or m.hasName("getBase"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `String` and Apache LDAP API
* `Dn`, i.e. `new Dn(tainted)`.
*/
private predicate apacheLdapDnStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeApacheDn |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between Apache LDAP API `Dn`
* and `String` i.e. `taintedDn.getName()`, `taintedDn.getNormName()` or `taintedDn.toString()`.
*/
private predicate apacheLdapDnGetStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getQualifier() and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType().getAnAncestor() instanceof TypeApacheDn and
(m.hasName("getName") or m.hasName("getNormName") or m.hasName("toString"))
)
}
/** A set of additional taint steps to consider when taint tracking LDAP related data flows. */
private class DefaultLdapInjectionAdditionalTaintStep extends LdapInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
ldapNameStep(node1, node2) or
ldapNameAddAllStep(node1, node2) or
ldapNameGetCloneStep(node1, node2) or
filterStep(node1, node2) or
filterToStringStep(node1, node2) or
unboundIdSearchRequestStep(node1, node2) or
unboundIdSearchRequestDuplicateStep(node1, node2) or
unboundIdSearchRequestSetStep(node1, node2) or
ldapQueryStep(node1, node2) or
ldapQueryBaseStep(node1, node2) or
ldapQueryBuilderStep(node1, node2) or
hardcodedFilterStep(node1, node2) or
springLdapFilterToStringStep(node1, node2) or
ldapNameBuilderStep(node1, node2) or
ldapNameBuilderBuildStep(node1, node2) or
ldapUtilsStep(node1, node2) or
apacheSearchRequestStep(node1, node2) or
apacheSearchRequestGetStep(node1, node2) or
apacheLdapDnStep(node1, node2) or
apacheLdapDnGetStep(node1, node2)
}
}

View File

@@ -0,0 +1,141 @@
/**
* Models the different ways to create paths. Either by using `java.io.File`-related APIs or `java.nio.file.Path`-related APIs.
*/
import java
/** Models the creation of a path. */
abstract class PathCreation extends Expr {
/**
* Gets an input that is used in the creation of this path.
* This excludes inputs of type `File` and `Path`.
*/
abstract Expr getAnInput();
}
/** Models the `java.nio.file.Paths.get` method. */
private class PathsGet extends PathCreation, MethodAccess {
PathsGet() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypePaths and
m.getName() = "get"
)
}
override Expr getAnInput() { result = this.getAnArgument() }
}
/** Models the `java.nio.file.FileSystem.getPath` method. */
private class FileSystemGetPath extends PathCreation, MethodAccess {
FileSystemGetPath() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypeFileSystem and
m.getName() = "getPath"
)
}
override Expr getAnInput() { result = this.getAnArgument() }
}
/** Models the `new java.io.File(...)` constructor. */
private class FileCreation extends PathCreation, ClassInstanceExpr {
FileCreation() { this.getConstructedType() instanceof TypeFile }
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments include those that are not a `File`.
not result.getType() instanceof TypeFile
}
}
/** Models the `java.nio.file.Path.resolveSibling` method. */
private class PathResolveSiblingCreation extends PathCreation, MethodAccess {
PathResolveSiblingCreation() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypePath and
m.getName() = "resolveSibling"
)
}
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
/** Models the `java.nio.file.Path.resolve` method. */
private class PathResolveCreation extends PathCreation, MethodAccess {
PathResolveCreation() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypePath and
m.getName() = "resolve"
)
}
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
/** Models the `java.nio.file.Path.of` method. */
private class PathOfCreation extends PathCreation, MethodAccess {
PathOfCreation() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypePath and
m.getName() = "of"
)
}
override Expr getAnInput() { result = this.getAnArgument() }
}
/** Models the `new java.io.FileWriter(...)` constructor. */
private class FileWriterCreation extends PathCreation, ClassInstanceExpr {
FileWriterCreation() { this.getConstructedType().hasQualifiedName("java.io", "FileWriter") }
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
/** Models the `new java.io.FileReader(...)` constructor. */
private class FileReaderCreation extends PathCreation, ClassInstanceExpr {
FileReaderCreation() { this.getConstructedType().hasQualifiedName("java.io", "FileReader") }
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
/** Models the `new java.io.FileInputStream(...)` constructor. */
private class FileInputStreamCreation extends PathCreation, ClassInstanceExpr {
FileInputStreamCreation() {
this.getConstructedType().hasQualifiedName("java.io", "FileInputStream")
}
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}
/** Models the `new java.io.FileOutputStream(...)` constructor. */
private class FileOutputStreamCreation extends PathCreation, ClassInstanceExpr {
FileOutputStreamCreation() {
this.getConstructedType().hasQualifiedName("java.io", "FileOutputStream")
}
override Expr getAnInput() {
result = this.getAnArgument() and
// Relevant arguments are those of type `String`.
result.getType() instanceof TypeString
}
}

View File

@@ -0,0 +1,49 @@
/** Provides classes to reason about header splitting attacks. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.frameworks.Servlets
import semmle.code.java.frameworks.JaxWS
/** A sink that is vulnerable to an HTTP header splitting attack. */
abstract class HeaderSplittingSink extends DataFlow::Node { }
/** A source that introduces data considered safe to use by a header splitting source. */
abstract class SafeHeaderSplittingSource extends DataFlow::Node {
SafeHeaderSplittingSource() { this instanceof RemoteFlowSource }
}
/** A sink that identifies a Java Servlet or JaxWs method that is vulnerable to an HTTP header splitting attack. */
private class ServletHeaderSplittingSink extends HeaderSplittingSink {
ServletHeaderSplittingSink() {
exists(ResponseAddCookieMethod m, MethodAccess ma |
ma.getMethod() = m and
this.asExpr() = ma.getArgument(0)
)
or
exists(ResponseAddHeaderMethod m, MethodAccess ma |
ma.getMethod() = m and
this.asExpr() = ma.getAnArgument()
)
or
exists(ResponseSetHeaderMethod m, MethodAccess ma |
ma.getMethod() = m and
this.asExpr() = ma.getAnArgument()
)
or
exists(JaxRsResponseBuilder builder, Method m |
m = builder.getAMethod() and m.getName() = "header"
|
this.asExpr() = m.getAReference().getArgument(1)
)
}
}
/** A default source that introduces data considered safe to use by a header splitting source. */
private class DefaultSafeHeaderSplittingSource extends SafeHeaderSplittingSource {
DefaultSafeHeaderSplittingSource() {
this.asExpr().(MethodAccess).getMethod() instanceof HttpServletRequestGetHeaderMethod or
this.asExpr().(MethodAccess).getMethod() instanceof CookieGetNameMethod
}
}

View File

@@ -0,0 +1,43 @@
edges
| InsecureBasicAuth.java:20:39:20:52 | ... + ... : String | InsecureBasicAuth.java:28:3:28:6 | post |
| InsecureBasicAuth.java:35:19:35:64 | "http://www.example.com:8000/payment/retrieve" : String | InsecureBasicAuth.java:38:3:38:5 | get |
| InsecureBasicAuth.java:45:19:45:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:54:3:54:6 | post |
| InsecureBasicAuth.java:61:19:61:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:71:3:71:6 | post |
| InsecureBasicAuth.java:78:47:78:52 | "http" : String | InsecureBasicAuth.java:86:3:86:6 | post |
| InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:102:3:102:6 | post |
| InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:119:3:119:6 | post |
| InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection |
| InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection | InsecureBasicAuth.java:133:3:133:6 | conn |
| InsecureBasicAuth.java:145:21:145:28 | protocol : String | InsecureBasicAuth.java:146:28:146:67 | (...)... : URLConnection |
| InsecureBasicAuth.java:146:28:146:67 | (...)... : URLConnection | InsecureBasicAuth.java:149:3:149:6 | conn |
nodes
| InsecureBasicAuth.java:20:39:20:52 | ... + ... : String | semmle.label | ... + ... : String |
| InsecureBasicAuth.java:28:3:28:6 | post | semmle.label | post |
| InsecureBasicAuth.java:35:19:35:64 | "http://www.example.com:8000/payment/retrieve" : String | semmle.label | "http://www.example.com:8000/payment/retrieve" : String |
| InsecureBasicAuth.java:38:3:38:5 | get | semmle.label | get |
| InsecureBasicAuth.java:45:19:45:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
| InsecureBasicAuth.java:54:3:54:6 | post | semmle.label | post |
| InsecureBasicAuth.java:61:19:61:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
| InsecureBasicAuth.java:71:3:71:6 | post | semmle.label | post |
| InsecureBasicAuth.java:78:47:78:52 | "http" : String | semmle.label | "http" : String |
| InsecureBasicAuth.java:86:3:86:6 | post | semmle.label | post |
| InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
| InsecureBasicAuth.java:102:3:102:6 | post | semmle.label | post |
| InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
| InsecureBasicAuth.java:119:3:119:6 | post | semmle.label | post |
| InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | semmle.label | "http://www.example.com/rest/getuser.do?uid=abcdx" : String |
| InsecureBasicAuth.java:130:28:130:67 | (...)... : URLConnection | semmle.label | (...)... : URLConnection |
| InsecureBasicAuth.java:133:3:133:6 | conn | semmle.label | conn |
| InsecureBasicAuth.java:145:21:145:28 | protocol : String | semmle.label | protocol : String |
| InsecureBasicAuth.java:146:28:146:67 | (...)... : URLConnection | semmle.label | (...)... : URLConnection |
| InsecureBasicAuth.java:149:3:149:6 | conn | semmle.label | conn |
#select
| InsecureBasicAuth.java:28:3:28:6 | post | InsecureBasicAuth.java:20:39:20:52 | ... + ... : String | InsecureBasicAuth.java:28:3:28:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:20:39:20:52 | ... + ... | HTTP url |
| InsecureBasicAuth.java:38:3:38:5 | get | InsecureBasicAuth.java:35:19:35:64 | "http://www.example.com:8000/payment/retrieve" : String | InsecureBasicAuth.java:38:3:38:5 | get | Insecure basic authentication from $@. | InsecureBasicAuth.java:35:19:35:64 | "http://www.example.com:8000/payment/retrieve" | HTTP url |
| InsecureBasicAuth.java:54:3:54:6 | post | InsecureBasicAuth.java:45:19:45:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:54:3:54:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:45:19:45:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" | HTTP url |
| InsecureBasicAuth.java:71:3:71:6 | post | InsecureBasicAuth.java:61:19:61:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:71:3:71:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:61:19:61:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" | HTTP url |
| InsecureBasicAuth.java:86:3:86:6 | post | InsecureBasicAuth.java:78:47:78:52 | "http" : String | InsecureBasicAuth.java:86:3:86:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:78:47:78:52 | "http" | HTTP url |
| InsecureBasicAuth.java:102:3:102:6 | post | InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:102:3:102:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:93:19:93:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" | HTTP url |
| InsecureBasicAuth.java:119:3:119:6 | post | InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:119:3:119:6 | post | Insecure basic authentication from $@. | InsecureBasicAuth.java:109:19:109:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" | HTTP url |
| InsecureBasicAuth.java:133:3:133:6 | conn | InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" : String | InsecureBasicAuth.java:133:3:133:6 | conn | Insecure basic authentication from $@. | InsecureBasicAuth.java:126:19:126:68 | "http://www.example.com/rest/getuser.do?uid=abcdx" | HTTP url |
| InsecureBasicAuth.java:149:3:149:6 | conn | InsecureBasicAuth.java:145:21:145:28 | protocol : String | InsecureBasicAuth.java:149:3:149:6 | conn | Insecure basic authentication from $@. | InsecureBasicAuth.java:145:21:145:28 | protocol | HTTP url |

View File

@@ -0,0 +1,164 @@
import org.apache.http.RequestLine;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.BasicRequestLine;
import java.net.URI;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.util.Base64;
public class InsecureBasicAuth {
/**
* Test basic authentication with Apache HTTP POST request using string constructor.
*/
public void testApacheHttpRequest(String username, String password) {
String host = "www.example.com";
HttpRequestBase post = new HttpPost("http://"+host+"/rest/getuser.do?uid=abcdx");
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Apache HTTP GET request.
*/
public void testApacheHttpRequest2(String url) throws java.io.IOException {
String urlStr = "http://www.example.com:8000/payment/retrieve";
HttpGet get = new HttpGet(urlStr);
get.setHeader("Accept", "application/json");
get.setHeader("Authorization", "Basic " + new String(Base64.getEncoder().encode("admin:test".getBytes())));
}
/**
* Test basic authentication with Apache HTTP POST request using URI create method.
*/
public void testApacheHttpRequest3(String username, String password) {
String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
HttpRequestBase post = new HttpPost(URI.create(uriStr));
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Apache HTTP POST request using the URI constructor with one argument.
*/
public void testApacheHttpRequest4(String username, String password) {
String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
URI uri = new URI(uriStr);
HttpRequestBase post = new HttpPost(uri);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Apache HTTP POST request using a URI constructor with multiple arguments.
*/
public void testApacheHttpRequest5(String username, String password) {
HttpRequestBase post = new HttpPost(new URI("http", "www.example.com", "/test", "abc=123", null));
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Apache HTTP `BasicHttpRequest` using string constructor.
*/
public void testApacheHttpRequest6(String username, String password) {
String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
BasicHttpRequest post = new BasicHttpRequest("POST", uriStr);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Apache HTTP `BasicHttpRequest` using `RequestLine`.
*/
public void testApacheHttpRequest7(String username, String password) {
String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
RequestLine requestLine = new BasicRequestLine("POST", uriStr, null);
BasicHttpRequest post = new BasicHttpRequest(requestLine);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
String authString = username + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes());
String authStringEnc = new String(authEncBytes);
post.addHeader("Authorization", "Basic " + authStringEnc);
}
/**
* Test basic authentication with Java HTTP URL connection using the `URL(String spec)` constructor.
*/
public void testHttpUrlConnection(String username, String password) {
String urlStr = "http://www.example.com/rest/getuser.do?uid=abcdx";
String authString = username + ":" + password;
String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8"));
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding);
}
/**
* Test basic authentication with Java HTTP URL connection using the `URL(String protocol, String host, String file)` constructor.
*/
public void testHttpUrlConnection2(String username, String password) {
String host = "www.example.com";
String path = "/rest/getuser.do?uid=abcdx";
String protocol = "http";
String authString = username + ":" + password;
String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8"));
URL url = new URL(protocol, host, path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding);
}
/**
* Test basic authentication with Java HTTP URL connection using a constructor with private URL.
*/
public void testHttpUrlConnection3(String username, String password) {
String host = "LOCALHOST";
String authString = username + ":" + password;
String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8"));
HttpURLConnection conn = (HttpURLConnection) new URL("http://"+(((host+"/rest/getuser.do")+"?uid=abcdx"))).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding);
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql

View File

@@ -0,0 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13

View File

@@ -0,0 +1,25 @@
| PathCreation.java:13:18:13:32 | new File(...) | PathCreation.java:13:27:13:31 | "dir" |
| PathCreation.java:14:19:14:40 | new File(...) | PathCreation.java:14:28:14:32 | "dir" |
| PathCreation.java:14:19:14:40 | new File(...) | PathCreation.java:14:35:14:39 | "sub" |
| PathCreation.java:18:18:18:49 | new File(...) | PathCreation.java:18:44:18:48 | "sub" |
| PathCreation.java:18:27:18:41 | new File(...) | PathCreation.java:18:36:18:40 | "dir" |
| PathCreation.java:22:18:22:41 | new File(...) | PathCreation.java:22:27:22:40 | new URI(...) |
| PathCreation.java:26:18:26:31 | of(...) | PathCreation.java:26:26:26:30 | "dir" |
| PathCreation.java:27:19:27:39 | of(...) | PathCreation.java:27:27:27:31 | "dir" |
| PathCreation.java:27:19:27:39 | of(...) | PathCreation.java:27:34:27:38 | "sub" |
| PathCreation.java:31:18:31:40 | of(...) | PathCreation.java:31:26:31:39 | new URI(...) |
| PathCreation.java:35:18:35:33 | get(...) | PathCreation.java:35:28:35:32 | "dir" |
| PathCreation.java:36:19:36:41 | get(...) | PathCreation.java:36:29:36:33 | "dir" |
| PathCreation.java:36:19:36:41 | get(...) | PathCreation.java:36:36:36:40 | "sub" |
| PathCreation.java:40:18:40:42 | get(...) | PathCreation.java:40:28:40:41 | new URI(...) |
| PathCreation.java:44:18:44:56 | getPath(...) | PathCreation.java:44:51:44:55 | "dir" |
| PathCreation.java:45:19:45:64 | getPath(...) | PathCreation.java:45:52:45:56 | "dir" |
| PathCreation.java:45:19:45:64 | getPath(...) | PathCreation.java:45:59:45:63 | "sub" |
| PathCreation.java:49:18:49:31 | of(...) | PathCreation.java:49:26:49:30 | "dir" |
| PathCreation.java:49:18:49:53 | resolveSibling(...) | PathCreation.java:49:48:49:52 | "sub" |
| PathCreation.java:53:18:53:31 | of(...) | PathCreation.java:53:26:53:30 | "dir" |
| PathCreation.java:53:18:53:46 | resolve(...) | PathCreation.java:53:41:53:45 | "sub" |
| PathCreation.java:57:25:57:45 | new FileWriter(...) | PathCreation.java:57:40:57:44 | "dir" |
| PathCreation.java:61:25:61:45 | new FileReader(...) | PathCreation.java:61:40:61:44 | "dir" |
| PathCreation.java:65:32:65:58 | new FileOutputStream(...) | PathCreation.java:65:53:65:57 | "dir" |
| PathCreation.java:69:31:69:56 | new FileInputStream(...) | PathCreation.java:69:51:69:55 | "dir" |

View File

@@ -0,0 +1,71 @@
import java.io.File;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.FileSystems;
import java.net.URI;
class PathCreation {
public void testNewFileWithString() {
File f = new File("dir");
File f2 = new File("dir", "sub");
}
public void testNewFileWithFileString() {
File f = new File(new File("dir"), "sub");
}
public void testNewFileWithURI() {
File f = new File(new URI("dir"));
}
public void testPathOfWithString() {
Path p = Path.of("dir");
Path p2 = Path.of("dir", "sub");
}
public void testPathOfWithURI() {
Path p = Path.of(new URI("dir"));
}
public void testPathsGetWithString() {
Path p = Paths.get("dir");
Path p2 = Paths.get("dir", "sub");
}
public void testPathsGetWithURI() {
Path p = Paths.get(new URI("dir"));
}
public void testFileSystemGetPathWithString() {
Path p = FileSystems.getDefault().getPath("dir");
Path p2 = FileSystems.getDefault().getPath("dir", "sub");
}
public void testPathResolveSiblingWithString() {
Path p = Path.of("dir").resolveSibling("sub");
}
public void testPathResolveWithString() {
Path p = Path.of("dir").resolve("sub");
}
public void testNewFileWriterWithString() {
FileWriter fw = new FileWriter("dir");
}
public void testNewFileReaderWithString() {
FileReader fr = new FileReader("dir");
}
public void testNewFileOutputStreamWithString() {
FileOutputStream fos = new FileOutputStream("dir");
}
public void testNewFileInputStreamWithString() {
FileInputStream fis = new FileInputStream("dir");
}
}

View File

@@ -0,0 +1,5 @@
import java
import semmle.code.java.security.PathCreation
from PathCreation path
select path, path.getAnInput()

View File

@@ -0,0 +1,70 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/Header.java $
* $Revision: 569636 $
* $Date: 2007-08-25 00:34:47 -0700 (Sat, 25 Aug 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* Represents an HTTP header field.
*
* <p>
* The HTTP header fields follow the same generic format as that given in
* Section 3.1 of RFC 822. Each header field consists of a name followed by a
* colon (":") and the field value. Field names are case-insensitive. The field
* value MAY be preceded by any amount of LWS, though a single SP is preferred.
*
* <pre>
* message-header = field-name ":" [ field-value ]
* field-name = token
* field-value = *( field-content | LWS )
* field-content = &lt;the OCTETs making up the field-value
* and consisting of either *TEXT or combinations
* of token, separators, and quoted-string&gt;
* </pre>
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
* @version $Revision: 569636 $
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface Header {
String getName();
String getValue();
HeaderElement[] getElements() throws ParseException;
}

View File

@@ -0,0 +1,65 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HeaderElement.java $
* $Revision: 569828 $
* $Date: 2007-08-26 08:49:38 -0700 (Sun, 26 Aug 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* One element of an HTTP {@link Header header} value.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
*
* <!-- empty lines above to avoid 'svn diff' context problems -->
* @version $Revision: 569828 $ $Date: 2007-08-26 08:49:38 -0700 (Sun, 26 Aug
* 2007) $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface HeaderElement {
String getName();
String getValue();
NameValuePair[] getParameters();
NameValuePair getParameterByName(String name);
int getParameterCount();
NameValuePair getParameter(int index);
}

View File

@@ -0,0 +1,66 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HeaderElementIterator.java $
* $Revision: 584542 $
* $Date: 2007-10-14 06:29:34 -0700 (Sun, 14 Oct 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
import java.util.Iterator;
/**
* A type-safe iterator for {@link HeaderElement HeaderElement} objects.
*
* @version $Revision: 584542 $
*
* @deprecated Please use {@link java.net.URL#openConnection} instead.
* Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
* for further details.
*/
@Deprecated
public interface HeaderElementIterator extends Iterator {
/**
* Indicates whether there is another header element in this
* iteration.
*
* @return <code>true</code> if there is another header element,
* <code>false</code> otherwise
*/
boolean hasNext();
/**
* Obtains the next header element from this iteration.
* This method should only be called while {@link #hasNext hasNext}
* is true.
*
* @return the next header element in this iteration
*/
HeaderElement nextElement();
}

View File

@@ -0,0 +1,64 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HeaderIterator.java $
* $Revision: 581981 $
* $Date: 2007-10-04 11:26:26 -0700 (Thu, 04 Oct 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
import java.util.Iterator;
/**
* A type-safe iterator for {@link Header Header} objects.
*
* @version $Revision: 581981 $
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface HeaderIterator extends Iterator {
/**
* Indicates whether there is another header in this iteration.
*
* @return <code>true</code> if there is another header, <code>false</code>
* otherwise
*/
boolean hasNext();
/**
* Obtains the next header from this iteration. This method should only be
* called while {@link #hasNext hasNext} is true.
*
* @return the next header in this iteration
*/
Header nextHeader();
}

View File

@@ -0,0 +1,186 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpEntity.java $
* $Revision: 645824 $
* $Date: 2008-04-08 03:12:41 -0700 (Tue, 08 Apr 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* An entity that can be sent or received with an HTTP message. Entities can be
* found in some {@link HttpEntityEnclosingRequest requests} and in
* {@link HttpResponse responses}, where they are optional.
* <p>
* In some places, the JavaDoc distinguishes three kinds of entities, depending
* on where their {@link #getContent content} originates:
* <ul>
* <li><b>streamed</b>: The content is received from a stream, or generated on
* the fly. In particular, this category includes entities being received from a
* {@link HttpConnection connection}. {@link #isStreaming Streamed} entities are
* generally not {@link #isRepeatable repeatable}.</li>
* <li><b>self-contained</b>: The content is in memory or obtained by means that
* are independent from a connection or other entity. Self-contained entities
* are generally {@link #isRepeatable repeatable}.</li>
* <li><b>wrapping</b>: The content is obtained from another entity.</li>
* </ul>
* This distinction is important for connection management with incoming
* entities. For entities that are created by an application and only sent using
* the HTTP components framework, the difference between streamed and
* self-contained is of little importance. In that case, it is suggested to
* consider non-repeatable entities as streamed, and those that are repeatable
* (without a huge effort) as self-contained.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 645824 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface HttpEntity {
/**
* Tells if the entity is capable to produce its data more than once. A
* repeatable entity's getContent() and writeTo(OutputStream) methods can be
* called more than once whereas a non-repeatable entity's can not.
*
* @return true if the entity is repeatable, false otherwise.
*/
boolean isRepeatable();
/**
* Tells about chunked encoding for this entity. The primary purpose of this
* method is to indicate whether chunked encoding should be used when the entity
* is sent. For entities that are received, it can also indicate whether the
* entity was received with chunked encoding. <br/>
* The behavior of wrapping entities is implementation dependent, but should
* respect the primary purpose.
*
* @return <code>true</code> if chunked encoding is preferred for this entity,
* or <code>false</code> if it is not
*/
boolean isChunked();
/**
* Tells the length of the content, if known.
*
* @return the number of bytes of the content, or a negative number if unknown.
* If the content length is known but exceeds
* {@link java.lang.Long#MAX_VALUE Long.MAX_VALUE}, a negative number is
* returned.
*/
long getContentLength();
/**
* Obtains the Content-Type header, if known. This is the header that should be
* used when sending the entity, or the one that was received with the entity.
* It can include a charset attribute.
*
* @return the Content-Type header for this entity, or <code>null</code> if the
* content type is unknown
*/
Header getContentType();
/**
* Obtains the Content-Encoding header, if known. This is the header that should
* be used when sending the entity, or the one that was received with the
* entity. Wrapping entities that modify the content encoding should adjust this
* header accordingly.
*
* @return the Content-Encoding header for this entity, or <code>null</code> if
* the content encoding is unknown
*/
Header getContentEncoding();
/**
* Creates a new InputStream object of the entity. It is a programming error to
* return the same InputStream object more than once. Entities that are not
* {@link #isRepeatable repeatable} will throw an exception if this method is
* called multiple times.
*
* @return a new input stream that returns the entity data.
*
* @throws IOException if the stream could not be created
* @throws IllegalStateException if this entity is not repeatable and the stream
* has already been obtained previously
*/
InputStream getContent() throws IOException, IllegalStateException;
/**
* Writes the entity content to the output stream.
*
* @param outstream the output stream to write entity content to
*
* @throws IOException if an I/O error occurs
*/
void writeTo(OutputStream outstream) throws IOException;
/**
* Tells whether this entity depends on an underlying stream. Streamed entities
* should return <code>true</code> until the content has been consumed,
* <code>false</code> afterwards. Self-contained entities should return
* <code>false</code>. Wrapping entities should delegate this call to the
* wrapped entity. <br/>
* The content of a streamed entity is consumed when the stream returned by
* {@link #getContent getContent} has been read to EOF, or after
* {@link #consumeContent consumeContent} has been called. If a streamed entity
* can not detect whether the stream has been read to EOF, it should return
* <code>true</code> until {@link #consumeContent consumeContent} is called.
*
* @return <code>true</code> if the entity content is streamed and not yet
* consumed, <code>false</code> otherwise
*/
boolean isStreaming(); // don't expect an exception here
/**
* TODO: The name of this method is misnomer. It will be renamed to #finish() in
* the next major release. <br/>
* This method is called to indicate that the content of this entity is no
* longer required. All entity implementations are expected to release all
* allocated resources as a result of this method invocation. Content streaming
* entities are also expected to dispose of the remaining content, if any.
* Wrapping entities should delegate this call to the wrapped entity. <br/>
* This method is of particular importance for entities being received from a
* {@link HttpConnection connection}. The entity needs to be consumed completely
* in order to re-use the connection with keep-alive.
*
* @throws IOException if an I/O error occurs. This indicates that connection
* keep-alive is not possible.
*/
void consumeContent() throws IOException;
} // interface HttpEntity

View File

@@ -0,0 +1,70 @@
/*
* $Header: $
* $Revision: 618017 $
* $Date: 2008-02-03 08:42:22 -0800 (Sun, 03 Feb 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* A request with an entity.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 618017 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface HttpEntityEnclosingRequest extends HttpRequest {
/**
* Tells if this request should use the expect-continue handshake. The expect
* continue handshake gives the server a chance to decide whether to accept the
* entity enclosing request before the possibly lengthy entity is sent across
* the wire.
*
* @return true if the expect continue handshake should be used, false if not.
*/
boolean expectContinue();
/**
* Hands the entity to the request.
*
* @param entity the entity to send.
*/
void setEntity(HttpEntity entity);
HttpEntity getEntity();
}

View File

@@ -0,0 +1,196 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpMessage.java $
* $Revision: 610823 $
* $Date: 2008-01-10 07:53:53 -0800 (Thu, 10 Jan 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
import org.apache.http.params.HttpParams;
/**
* A generic HTTP message.
* Holds what is common between requests and responses.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 610823 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead.
* Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
* for further details.
*/
@Deprecated
public interface HttpMessage {
/**
* Returns the protocol version this message is compatible with.
*/
ProtocolVersion getProtocolVersion();
/**
* Checks if a certain header is present in this message. Header values are
* ignored.
*
* @param name the header name to check for.
* @return true if at least one header with this name is present.
*/
boolean containsHeader(String name);
/**
* Returns all the headers with a specified name of this message. Header values
* are ignored. Headers are orderd in the sequence they will be sent over a
* connection.
*
* @param name the name of the headers to return.
* @return the headers whose name property equals <code>name</code>.
*/
Header[] getHeaders(String name);
/**
* Returns the first header with a specified name of this message. Header
* values are ignored. If there is more than one matching header in the
* message the first element of {@link #getHeaders(String)} is returned.
* If there is no matching header in the message <code>null</code> is
* returned.
*
* @param name the name of the header to return.
* @return the first header whose name property equals <code>name</code>
* or <code>null</code> if no such header could be found.
*/
Header getFirstHeader(String name);
/**
* Returns the last header with a specified name of this message. Header values
* are ignored. If there is more than one matching header in the message the
* last element of {@link #getHeaders(String)} is returned. If there is no
* matching header in the message <code>null</code> is returned.
*
* @param name the name of the header to return.
* @return the last header whose name property equals <code>name</code>.
* or <code>null</code> if no such header could be found.
*/
Header getLastHeader(String name);
/**
* Returns all the headers of this message. Headers are orderd in the sequence
* they will be sent over a connection.
*
* @return all the headers of this message
*/
Header[] getAllHeaders();
/**
* Adds a header to this message. The header will be appended to the end of
* the list.
*
* @param header the header to append.
*/
void addHeader(Header header);
/**
* Adds a header to this message. The header will be appended to the end of
* the list.
*
* @param name the name of the header.
* @param value the value of the header.
*/
void addHeader(String name, String value);
/**
* Overwrites the first header with the same name. The new header will be appended to
* the end of the list, if no header with the given name can be found.
*
* @param header the header to set.
*/
void setHeader(Header header);
/**
* Overwrites the first header with the same name. The new header will be appended to
* the end of the list, if no header with the given name can be found.
*
* @param name the name of the header.
* @param value the value of the header.
*/
void setHeader(String name, String value);
/**
* Overwrites all the headers in the message.
*
* @param headers the array of headers to set.
*/
void setHeaders(Header[] headers);
/**
* Removes a header from this message.
*
* @param header the header to remove.
*/
void removeHeader(Header header);
/**
* Removes all headers with a certain name from this message.
*
* @param name The name of the headers to remove.
*/
void removeHeaders(String name);
/**
* Returns an iterator of all the headers.
*
* @return Iterator that returns Header objects in the sequence they are
* sent over a connection.
*/
HeaderIterator headerIterator();
/**
* Returns an iterator of the headers with a given name.
*
* @param name the name of the headers over which to iterate, or
* <code>null</code> for all headers
*
* @return Iterator that returns Header objects with the argument name
* in the sequence they are sent over a connection.
*/
HeaderIterator headerIterator(String name);
/**
* Returns the parameters effective for this message as set by
* {@link #setParams(HttpParams)}.
*/
HttpParams getParams();
/**
* Provides parameters to be used for the processing of this message.
* @param params the parameters
*/
void setParams(HttpParams params);
}

View File

@@ -0,0 +1,58 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpRequest.java $
* $Revision: 528428 $
* $Date: 2007-04-13 03:26:04 -0700 (Fri, 13 Apr 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* An HTTP request.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 528428 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface HttpRequest extends HttpMessage {
/**
* Returns the request line of this request.
*
* @return the request line.
*/
RequestLine getRequestLine();
}

View File

@@ -0,0 +1,124 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/NameValuePair.java $
* $Revision: 496070 $
* $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* A simple class encapsulating an attribute/value pair.
* <p>
* This class comforms to the generic grammar and formatting rules outlined in
* the <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">Section
* 2.2</a> and <a href=
* "http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section
* 3.6</a> of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC
* 2616</a>
* </p>
* <h>2.2 Basic Rules</h>
* <p>
* The following rules are used throughout this specification to describe basic
* parsing constructs. The US-ASCII coded character set is defined by ANSI
* X3.4-1986.
* </p>
*
* <pre>
* OCTET = <any 8-bit sequence of data>
* CHAR = <any US-ASCII character (octets 0 - 127)>
* UPALPHA = <any US-ASCII uppercase letter "A".."Z">
* LOALPHA = <any US-ASCII lowercase letter "a".."z">
* ALPHA = UPALPHA | LOALPHA
* DIGIT = <any US-ASCII digit "0".."9">
* CTL = <any US-ASCII control character
* (octets 0 - 31) and DEL (127)>
* CR = <US-ASCII CR, carriage return (13)>
* LF = <US-ASCII LF, linefeed (10)>
* SP = <US-ASCII SP, space (32)>
* HT = <US-ASCII HT, horizontal-tab (9)>
* <"> = <US-ASCII double-quote mark (34)>
* </pre>
* <p>
* Many HTTP/1.1 header field values consist of words separated by LWS or
* special characters. These special characters MUST be in a quoted string to be
* used within a parameter value (as defined in section 3.6).
* <p>
*
* <pre>
* token = 1*<any CHAR except CTLs or separators>
* separators = "(" | ")" | "<" | ">" | "@"
* | "," | ";" | ":" | "\" | <">
* | "/" | "[" | "]" | "?" | "="
* | "{" | "}" | SP | HT
* </pre>
* <p>
* A string of text is parsed as a single word if it is quoted using
* double-quote marks.
* </p>
*
* <pre>
* quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
* qdtext = <any TEXT except <">>
* </pre>
* <p>
* The backslash character ("\") MAY be used as a single-character quoting
* mechanism only within quoted-string and comment constructs.
* </p>
*
* <pre>
* quoted-pair = "\" CHAR
* </pre>
*
* <h>3.6 Transfer Codings</h>
* <p>
* Parameters are in the form of attribute/value pairs.
* </p>
*
* <pre>
* parameter = attribute "=" value
* attribute = token
* value = token | quoted-string
* </pre>
*
* @author <a href="mailto:oleg at ural.com">Oleg Kalnichevski</a>
*
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface NameValuePair {
String getName();
String getValue();
}

View File

@@ -0,0 +1,64 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ParseException.java $
* $Revision: 609106 $
* $Date: 2008-01-05 01:15:42 -0800 (Sat, 05 Jan 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* Indicates a parse error. Parse errors when receiving a message will typically
* trigger {@link ProtocolException}. Parse errors that do not occur during
* protocol execution may be handled differently. This is an unchecked
* exceptions, since there are cases where the data to be parsed has been
* generated and is therefore known to be parseable.
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class ParseException extends RuntimeException {
/**
* Creates a {@link ParseException} without details.
*/
public ParseException() {
}
/**
* Creates a {@link ParseException} with a detail message.
*
* @param message the exception detail message, or <code>null</code>
*/
public ParseException(String message) {
}
}

View File

@@ -0,0 +1,211 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/ProtocolVersion.java $
* $Revision: 609106 $
* $Date: 2008-01-05 01:15:42 -0800 (Sat, 05 Jan 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
import java.io.Serializable;
/**
* Represents a protocol version, as specified in RFC 2616. RFC 2616 specifies
* only HTTP versions, like "HTTP/1.1" and "HTTP/1.0". RFC 3261 specifies a
* message format that is identical to HTTP except for the protocol name. It
* defines a protocol version "SIP/2.0". There are some nitty-gritty differences
* between the interpretation of versions in HTTP and SIP. In those cases, HTTP
* takes precedence.
* <p>
* This class defines a protocol version as a combination of protocol name,
* major version number, and minor version number. Note that {@link #equals} and
* {@link #hashCode} are defined as final here, they cannot be overridden in
* derived classes.
*
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
* @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
*
* @version $Revision: 609106 $
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class ProtocolVersion implements Serializable, Cloneable {
/**
* Create a protocol version designator.
*
* @param protocol the name of the protocol, for example "HTTP"
* @param major the major version number of the protocol
* @param minor the minor version number of the protocol
*/
public ProtocolVersion(String protocol, int major, int minor) {
}
/**
* Returns the name of the protocol.
*
* @return the protocol name
*/
public final String getProtocol() {
return null;
}
/**
* Returns the major version number of the protocol.
*
* @return the major version number.
*/
public final int getMajor() {
return -1;
}
/**
* Returns the minor version number of the HTTP protocol.
*
* @return the minor version number.
*/
public final int getMinor() {
return -1;
}
/**
* Obtains a specific version of this protocol. This can be used by derived
* classes to instantiate themselves instead of the base class, and to define
* constants for commonly used versions. <br/>
* The default implementation in this class returns <code>this</code> if the
* version matches, and creates a new {@link ProtocolVersion} otherwise.
*
* @param major the major version
* @param minor the minor version
*
* @return a protocol version with the same protocol name and the argument
* version
*/
public ProtocolVersion forVersion(int major, int minor) {
return null;
}
/**
* Obtains a hash code consistent with {@link #equals}.
*
* @return the hashcode of this protocol version
*/
public final int hashCode() {
return -1;
}
/**
* Checks equality of this protocol version with an object. The object is equal
* if it is a protocl version with the same protocol name, major version number,
* and minor version number. The specific class of the object is <i>not</i>
* relevant, instances of derived classes with identical attributes are equal to
* instances of the base class and vice versa.
*
* @param obj the object to compare with
*
* @return <code>true</code> if the argument is the same protocol version,
* <code>false</code> otherwise
*/
public final boolean equals(Object obj) {
return false;
}
/**
* Checks whether this protocol can be compared to another one. Only protocol
* versions with the same protocol name can be {@link #compareToVersion
* compared}.
*
* @param that the protocol version to consider
*
* @return <code>true</code> if {@link #compareToVersion compareToVersion} can
* be called with the argument, <code>false</code> otherwise
*/
public boolean isComparable(ProtocolVersion that) {
return false;
}
/**
* Compares this protocol version with another one. Only protocol versions with
* the same protocol name can be compared. This method does <i>not</i> define a
* total ordering, as it would be required for {@link java.lang.Comparable}.
*
* @param that the protocl version to compare with
*
* @return a negative integer, zero, or a positive integer as this version is
* less than, equal to, or greater than the argument version.
*
* @throws IllegalArgumentException if the argument has a different protocol
* name than this object, or if the argument is
* <code>null</code>
*/
public int compareToVersion(ProtocolVersion that) {
return -1;
}
/**
* Tests if this protocol version is greater or equal to the given one.
*
* @param version the version against which to check this version
*
* @return <code>true</code> if this protocol version is {@link #isComparable
* comparable} to the argument and {@link #compareToVersion compares} as
* greater or equal, <code>false</code> otherwise
*/
public final boolean greaterEquals(ProtocolVersion version) {
return false;
}
/**
* Tests if this protocol version is less or equal to the given one.
*
* @param version the version against which to check this version
*
* @return <code>true</code> if this protocol version is {@link #isComparable
* comparable} to the argument and {@link #compareToVersion compares} as
* less or equal, <code>false</code> otherwise
*/
public final boolean lessEquals(ProtocolVersion version) {
return false;
}
/**
* Converts this protocol version to a string.
*
* @return a protocol version string, like "HTTP/1.1"
*/
public String toString() {
return null;
}
public Object clone() throws CloneNotSupportedException {
return null;
}
}

View File

@@ -0,0 +1,58 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/RequestLine.java $
* $Revision: 573864 $
* $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http;
/**
* The first line of an {@link HttpRequest HttpRequest}. It contains the method,
* URI, and HTTP version of the request. For details, see RFC 2616.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 573864 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public interface RequestLine {
String getMethod();
ProtocolVersion getProtocolVersion();
String getUri();
}

View File

@@ -0,0 +1,67 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/methods/HttpEntityEnclosingRequestBase.java $
* $Revision: 674186 $
* $Date: 2008-07-05 05:18:54 -0700 (Sat, 05 Jul 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client.methods;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
/**
* Basic implementation of an HTTP request that can be modified.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 674186 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public abstract class HttpEntityEnclosingRequestBase extends HttpRequestBase implements HttpEntityEnclosingRequest {
public HttpEntityEnclosingRequestBase() {
}
public HttpEntity getEntity() {
return null;
}
public void setEntity(final HttpEntity entity) {
}
public boolean expectContinue() {
return false;
}
}

View File

@@ -0,0 +1,81 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/methods/HttpGet.java $
* $Revision: 664505 $
* $Date: 2008-06-08 06:21:20 -0700 (Sun, 08 Jun 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client.methods;
import java.net.URI;
/**
* HTTP GET method.
* <p>
* The HTTP GET method is defined in section 9.3 of
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: <blockquote> The
* GET method means retrieve whatever information (in the form of an entity) is
* identified by the Request-URI. If the Request-URI refers to a data-producing
* process, it is the produced data which shall be returned as the entity in the
* response and not the source text of the process, unless that text happens to
* be the output of the process. </blockquote>
* </p>
* <p>
* GetMethods will follow redirect requests from the http server by default.
* This behavour can be disabled by calling setFollowRedirects(false).
* </p>
*
* @version $Revision: 664505 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class HttpGet extends HttpRequestBase {
public final static String METHOD_NAME = "GET";
public HttpGet() {
}
public HttpGet(final URI uri) {
}
/**
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpGet(final String uri) {
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}

View File

@@ -0,0 +1,85 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/methods/HttpPost.java $
* $Revision: 664505 $
* $Date: 2008-06-08 06:21:20 -0700 (Sun, 08 Jun 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client.methods;
import java.net.URI;
/**
* HTTP POST method.
* <p>
* The HTTP POST method is defined in section 9.5 of
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: <blockquote> The
* POST method is used to request that the origin server accept the entity
* enclosed in the request as a new subordinate of the resource identified by
* the Request-URI in the Request-Line. POST is designed to allow a uniform
* method to cover the following functions:
* <ul>
* <li>Annotation of existing resources</li>
* <li>Posting a message to a bulletin board, newsgroup, mailing list, or
* similar group of articles</li>
* <li>Providing a block of data, such as the result of submitting a form, to a
* data-handling process</li>
* <li>Extending a database through an append operation</li>
* </ul>
* </blockquote>
* </p>
*
* @version $Revision: 664505 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class HttpPost extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "POST";
public HttpPost() {
}
public HttpPost(final URI uri) {
}
/**
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpPost(final String uri) {
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}

View File

@@ -0,0 +1,76 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/methods/HttpPut.java $
* $Revision: 664505 $
* $Date: 2008-06-08 06:21:20 -0700 (Sun, 08 Jun 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client.methods;
import java.net.URI;
/**
* HTTP PUT method.
* <p>
* The HTTP PUT method is defined in section 9.6 of
* <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>: <blockquote> The
* PUT method requests that the enclosed entity be stored under the supplied
* Request-URI. If the Request-URI refers to an already existing resource, the
* enclosed entity SHOULD be considered as a modified version of the one
* residing on the origin server. </blockquote>
* </p>
*
* @version $Revision: 664505 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class HttpPut extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "PUT";
public HttpPut() {
}
public HttpPut(final URI uri) {
}
/**
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpPut(final String uri) {
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}

View File

@@ -0,0 +1,90 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/client/methods/HttpRequestBase.java $
* $Revision: 674186 $
* $Date: 2008-07-05 05:18:54 -0700 (Sat, 05 Jul 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client.methods;
import java.io.IOException;
import java.net.URI;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
/**
* Basic implementation of an HTTP request that can be modified.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 674186 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public abstract class HttpRequestBase extends AbstractHttpMessage {
public HttpRequestBase() {
}
public abstract String getMethod();
public ProtocolVersion getProtocolVersion() {
return null;
}
public URI getURI() {
return null;
}
public RequestLine getRequestLine() {
return null;
}
public void setURI(final URI uri) {
}
public void abort() {
}
public boolean isAborted() {
return false;
}
// Add method from `org.apache.http.HttpMessage`
public void addHeader(String name, String value) {
}
// Add method from `org.apache.http.HttpMessage`
public void setHeader(String name, String value) {
}
}

View File

@@ -0,0 +1,128 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/AbstractHttpMessage.java $
* $Revision: 620287 $
* $Date: 2008-02-10 07:15:53 -0800 (Sun, 10 Feb 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.message;
import java.util.Iterator;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpMessage;
import org.apache.http.params.HttpParams;
/**
* Basic implementation of an HTTP message that can be modified.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 620287 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public abstract class AbstractHttpMessage implements HttpMessage {
// non-javadoc, see interface HttpMessage
public boolean containsHeader(String name) {
return false;
}
// non-javadoc, see interface HttpMessage
public Header[] getHeaders(final String name) {
return null;
}
// non-javadoc, see interface HttpMessage
public Header getFirstHeader(final String name) {
return null;
}
// non-javadoc, see interface HttpMessage
public Header getLastHeader(final String name) {
return null;
}
// non-javadoc, see interface HttpMessage
public Header[] getAllHeaders() {
return null;
}
// non-javadoc, see interface HttpMessage
public void addHeader(final Header header) {
}
// non-javadoc, see interface HttpMessage
public void addHeader(final String name, final String value) {
}
// non-javadoc, see interface HttpMessage
public void setHeader(final Header header) {
}
// non-javadoc, see interface HttpMessage
public void setHeader(final String name, final String value) {
}
// non-javadoc, see interface HttpMessage
public void setHeaders(final Header[] headers) {
}
// non-javadoc, see interface HttpMessage
public void removeHeader(final Header header) {
}
// non-javadoc, see interface HttpMessage
public void removeHeaders(final String name) {
}
// non-javadoc, see interface HttpMessage
public HeaderIterator headerIterator() {
return null;
}
// non-javadoc, see interface HttpMessage
public HeaderIterator headerIterator(String name) {
return null;
}
// non-javadoc, see interface HttpMessage
public HttpParams getParams() {
return null;
}
// non-javadoc, see interface HttpMessage
public void setParams(final HttpParams params) {
}
}

View File

@@ -0,0 +1,79 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHttpEntityEnclosingRequest.java $
* $Revision: 618017 $
* $Date: 2008-02-03 08:42:22 -0800 (Sun, 03 Feb 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.message;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
/**
* Basic implementation of a request with an entity that can be modified.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 618017 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class BasicHttpEntityEnclosingRequest extends BasicHttpRequest implements HttpEntityEnclosingRequest {
public BasicHttpEntityEnclosingRequest(final String method, final String uri) {
super(method, uri);
}
public BasicHttpEntityEnclosingRequest(final String method, final String uri, final ProtocolVersion ver) {
super(method, uri, ver);
}
public BasicHttpEntityEnclosingRequest(final RequestLine requestline) {
super(requestline);
}
public HttpEntity getEntity() {
return null;
}
public void setEntity(final HttpEntity entity) {
}
public boolean expectContinue() {
return false;
}
}

View File

@@ -0,0 +1,78 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHttpRequest.java $
* $Revision: 573864 $
* $Date: 2007-09-08 08:53:25 -0700 (Sat, 08 Sep 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.message;
import org.apache.http.HttpRequest;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
/**
* Basic implementation of an HTTP request that can be modified.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 573864 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead. Please
* visit <a href=
* "http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this
* webpage</a> for further details.
*/
@Deprecated
public class BasicHttpRequest extends AbstractHttpMessage implements HttpRequest {
public BasicHttpRequest(final String method, final String uri) {
}
public BasicHttpRequest(final String method, final String uri, final ProtocolVersion ver) {
}
public BasicHttpRequest(final RequestLine requestline) {
}
public ProtocolVersion getProtocolVersion() {
return null;
}
public RequestLine getRequestLine() {
return null;
}
// Add method from `org.apache.http.HttpMessage`
public void addHeader(String name, String value) {
}
// Add method from `org.apache.http.HttpMessage`
public void setHeader(String name, String value) {
}
}

View File

@@ -0,0 +1,72 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicRequestLine.java $
* $Revision: 604625 $
* $Date: 2007-12-16 06:11:11 -0800 (Sun, 16 Dec 2007) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.message;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
/**
* The first line of an {@link org.apache.http.HttpRequest HttpRequest}.
* It contains the method, URI, and HTTP version of the request.
* For details, see RFC 2616.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
*
* <!-- empty lines above to avoid 'svn diff' context problems -->
* @version $Revision: 604625 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead.
* Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
* for further details.
*/
@Deprecated
public class BasicRequestLine implements RequestLine, Cloneable {
public BasicRequestLine(final String method, final String uri, final ProtocolVersion version) {
}
public String getMethod() {
return null;
}
public ProtocolVersion getProtocolVersion() {
return null;
}
public String getUri() {
return null;
}
public String toString() {
return null;
}
}

View File

@@ -0,0 +1,176 @@
/*
* $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpParams.java $
* $Revision: 610763 $
* $Date: 2008-01-10 04:01:13 -0800 (Thu, 10 Jan 2008) $
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.params;
/**
* Represents a collection of HTTP protocol and framework parameters.
*
* @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
*
* @version $Revision: 610763 $
*
* @since 4.0
*
* @deprecated Please use {@link java.net.URL#openConnection} instead.
* Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
* for further details.
*/
@Deprecated
public interface HttpParams {
/**
* Obtains the value of the given parameter.
*
* @param name the parent name.
*
* @return an object that represents the value of the parameter,
* <code>null</code> if the parameter is not set or if it
* is explicitly set to <code>null</code>
*
* @see #setParameter(String, Object)
*/
Object getParameter(String name);
/**
* Assigns the value to the parameter with the given name.
*
* @param name parameter name
* @param value parameter value
*/
HttpParams setParameter(String name, Object value);
/**
* Creates a copy of these parameters.
*
* @return a new set of parameters holding the same values as this one
*/
HttpParams copy();
/**
* Removes the parameter with the specified name.
*
* @param name parameter name
*
* @return true if the parameter existed and has been removed, false else.
*/
boolean removeParameter(String name);
/**
* Returns a {@link Long} parameter value with the given name.
* If the parameter is not explicitly set, the default value is returned.
*
* @param name the parent name.
* @param defaultValue the default value.
*
* @return a {@link Long} that represents the value of the parameter.
*
* @see #setLongParameter(String, long)
*/
long getLongParameter(String name, long defaultValue);
/**
* Assigns a {@link Long} to the parameter with the given name
*
* @param name parameter name
* @param value parameter value
*/
HttpParams setLongParameter(String name, long value);
/**
* Returns an {@link Integer} parameter value with the given name.
* If the parameter is not explicitly set, the default value is returned.
*
* @param name the parent name.
* @param defaultValue the default value.
*
* @return a {@link Integer} that represents the value of the parameter.
*
* @see #setIntParameter(String, int)
*/
int getIntParameter(String name, int defaultValue);
/**
* Assigns an {@link Integer} to the parameter with the given name
*
* @param name parameter name
* @param value parameter value
*/
HttpParams setIntParameter(String name, int value);
/**
* Returns a {@link Double} parameter value with the given name.
* If the parameter is not explicitly set, the default value is returned.
*
* @param name the parent name.
* @param defaultValue the default value.
*
* @return a {@link Double} that represents the value of the parameter.
*
* @see #setDoubleParameter(String, double)
*/
double getDoubleParameter(String name, double defaultValue);
/**
* Assigns a {@link Double} to the parameter with the given name
*
* @param name parameter name
* @param value parameter value
*/
HttpParams setDoubleParameter(String name, double value);
/**
* Returns a {@link Boolean} parameter value with the given name.
* If the parameter is not explicitly set, the default value is returned.
*
* @param name the parent name.
* @param defaultValue the default value.
*
* @return a {@link Boolean} that represents the value of the parameter.
*
* @see #setBooleanParameter(String, boolean)
*/
boolean getBooleanParameter(String name, boolean defaultValue);
/**
* Assigns a {@link Boolean} to the parameter with the given name
*
* @param name parameter name
* @param value parameter value
*/
HttpParams setBooleanParameter(String name, boolean value);
/**
* Checks if a boolean parameter is set to <code>true</code>.
*
* @param name parameter name
*
* @return <tt>true</tt> if the parameter is set to value <tt>true</tt>,
* <tt>false</tt> if it is not set or set to <code>false</code>
*/
boolean isParameterTrue(String name);
/**
* Checks if a boolean parameter is not set or <code>false</code>.
*
* @param name parameter name
*
* @return <tt>true</tt> if the parameter is either not set or
* set to value <tt>false</tt>,
* <tt>false</tt> if it is set to <code>true</code>
*/
boolean isParameterFalse(String name);
}

View File

@@ -14,9 +14,8 @@
import javascript
class RootDestructuringPattern extends BindingPattern {
class RootDestructuringPattern extends DestructuringPattern {
RootDestructuringPattern() {
this instanceof DestructuringPattern and
not this = any(PropertyPattern p).getValuePattern() and
not this = any(ArrayPattern p).getAnElement()
}

View File

@@ -67,7 +67,7 @@ predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpLiteralNode r
*/
predicate allBackslashesEscaped(DataFlow::Node nd) {
// `JSON.stringify` escapes backslashes
nd = DataFlow::globalVarRef("JSON").getAMemberCall("stringify")
nd instanceof JsonStringifyCall
or
// check whether `nd` itself escapes backslashes
exists(DataFlow::RegExpLiteralNode rel | isBackslashEscape(nd, rel) |

View File

@@ -34,6 +34,7 @@ import semmle.javascript.InclusionTests
import semmle.javascript.JSDoc
import semmle.javascript.JSON
import semmle.javascript.JsonParsers
import semmle.javascript.JsonStringifiers
import semmle.javascript.JSX
import semmle.javascript.Lines
import semmle.javascript.Locations

View File

@@ -1848,6 +1848,11 @@ class AssignExpr extends @assignexpr, Assignment {
override Expr getUnderlyingValue() { result = getRhs().getUnderlyingValue() }
}
private class TCompoundAssignExpr =
@assignaddexpr or @assignsubexpr or @assignmulexpr or @assigndivexpr or @assignmodexpr or
@assignexpexpr or @assignlshiftexpr or @assignrshiftexpr or @assignurshiftexpr or
@assignorexpr or @assignxorexpr or @assignandexpr;
/**
* A compound assign expression.
*
@@ -1858,7 +1863,7 @@ class AssignExpr extends @assignexpr, Assignment {
* x /= 2
* ```
*/
abstract class CompoundAssignExpr extends Assignment { }
class CompoundAssignExpr extends TCompoundAssignExpr, Assignment { }
/**
* A compound add-assign expression.

View File

@@ -0,0 +1,34 @@
/**
* Provides classes for working with JSON serializers.
*/
import javascript
/**
* A call to a JSON stringifier such as `JSON.stringify` or `require("util").inspect`.
*/
class JsonStringifyCall extends DataFlow::CallNode {
JsonStringifyCall() {
exists(DataFlow::SourceNode callee | this = callee.getACall() |
callee = DataFlow::globalVarRef("JSON").getAPropertyRead("stringify") or
callee = DataFlow::moduleMember("json3", "stringify") or
callee =
DataFlow::moduleImport(["json-stringify-safe", "json-stable-stringify", "stringify-object",
"fast-json-stable-stringify", "fast-safe-stringify", "javascript-stringify",
"js-stringify"]) or
// require("util").inspect() and similar
callee = DataFlow::moduleMember("util", "inspect") or
callee = DataFlow::moduleImport(["pretty-format", "object-inspect"])
)
}
/**
* Gets the data flow node holding the input object to be stringified.
*/
DataFlow::Node getInput() { result = getArgument(0) }
/**
* Gets the data flow node holding the resulting string.
*/
DataFlow::SourceNode getOutput() { result = this }
}

View File

@@ -64,6 +64,13 @@ class Stmt extends @stmt, ExprOrStmt, Documentable {
}
}
private class TControlStmt =
TLoopStmt or @ifstmt or @withstmt or @switchstmt or @trystmt or @catchclause;
private class TLoopStmt = TEnhancedForLoop or @whilestmt or @dowhilestmt or @forstmt;
private class TEnhancedForLoop = @forinstmt or @foreachstmt or @forofstmt;
/**
* A control statement, that is, is a loop, an if statement, a switch statement,
* a with statement, a try statement, or a catch clause.
@@ -82,7 +89,7 @@ class Stmt extends @stmt, ExprOrStmt, Documentable {
* }
* ```
*/
abstract class ControlStmt extends Stmt {
class ControlStmt extends TControlStmt, Stmt {
/** Gets a statement controlled by this control statement. */
abstract Stmt getAControlledStmt();
}
@@ -102,7 +109,7 @@ abstract class ControlStmt extends Stmt {
* } while(++i < lines.length);
* ```
*/
abstract class LoopStmt extends ControlStmt {
class LoopStmt extends TLoopStmt, ControlStmt {
/** Gets the body of this loop. */
abstract Stmt getBody();
@@ -450,6 +457,10 @@ class LabeledStmt extends @labeledstmt, Stmt {
Stmt getStmt() { result = getChildStmt(1) }
}
private class TJumpStmt = TBreakOrContinueStmt or @returnstmt or @throwstmt;
private class TBreakOrContinueStmt = @breakstmt or @continuestmt;
/**
* A statement that disrupts structured control flow, that is, a `continue` statement,
* a `break` statement, a `throw` statement, or a `return` statement.
@@ -463,7 +474,7 @@ class LabeledStmt extends @labeledstmt, Stmt {
* return -1;
* ```
*/
abstract class JumpStmt extends Stmt {
class JumpStmt extends TJumpStmt, Stmt {
/**
* Gets the target of this jump.
*
@@ -490,7 +501,7 @@ abstract class JumpStmt extends Stmt {
* break;
* ```
*/
abstract class BreakOrContinueStmt extends JumpStmt {
class BreakOrContinueStmt extends TBreakOrContinueStmt, JumpStmt {
/** Gets the label this statement refers to, if any. */
string getTargetLabel() { result = getChildExpr(0).(Identifier).getName() }
@@ -801,7 +812,7 @@ class ForStmt extends @forstmt, LoopStmt {
* }
* ```
*/
abstract class EnhancedForLoop extends LoopStmt {
class EnhancedForLoop extends TEnhancedForLoop, LoopStmt {
/**
* Gets the iterator of this `for`-`in` or `for`-`of` loop; this can be either a
* pattern, a property reference, or a variable declaration statement.

View File

@@ -406,6 +406,8 @@ class BindingPattern extends @pattern, Expr {
}
}
private class TDestructuringPattern = @arraypattern or @objectpattern;
/**
* A destructuring pattern, that is, either an array pattern or an object pattern.
*
@@ -418,9 +420,9 @@ class BindingPattern extends @pattern, Expr {
* }
* ```
*/
abstract class DestructuringPattern extends BindingPattern {
class DestructuringPattern extends TDestructuringPattern, BindingPattern {
/** Gets the rest pattern of this destructuring pattern, if any. */
abstract Expr getRest();
Expr getRest() { none() } // Overridden in subtypes.
}
/**

View File

@@ -543,8 +543,8 @@ module TaintTracking {
/**
* A taint propagating data flow edge arising from JSON unparsing.
*/
private class JsonStringifyTaintStep extends AdditionalTaintStep, DataFlow::MethodCallNode {
JsonStringifyTaintStep() { this = DataFlow::globalVarRef("JSON").getAMemberCall("stringify") }
private class JsonStringifyTaintStep extends AdditionalTaintStep, DataFlow::CallNode {
JsonStringifyTaintStep() { this instanceof JsonStringifyCall }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
pred = getArgument(0) and succ = this
@@ -693,18 +693,6 @@ module TaintTracking {
}
}
/**
* A taint step through the Node.JS function `util.inspect(..)`.
*/
class UtilInspectTaintStep extends AdditionalTaintStep, DataFlow::InvokeNode {
UtilInspectTaintStep() { this = DataFlow::moduleImport("util").getAMemberCall("inspect") }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
succ = this and
this.getAnArgument() = pred
}
}
private module RegExpCaptureSteps {
/** Gets a reference to a string derived from the most recent RegExp match, such as `RegExp.$1`. */
private DataFlow::PropRead getAStaticCaptureRef() {

View File

@@ -28,9 +28,7 @@ private class RemoteFlowPassword extends HeuristicSource, RemoteFlowSource {
*/
private class JSONStringifyAsCommandInjectionSource extends HeuristicSource,
CommandInjection::Source {
JSONStringifyAsCommandInjectionSource() {
this = DataFlow::globalVarRef("JSON").getAMemberCall("stringify")
}
JSONStringifyAsCommandInjectionSource() { this instanceof JsonStringifyCall }
override string getSourceType() { result = "a string from JSON.stringify" }
}

View File

@@ -202,10 +202,9 @@ module CleartextLogging {
exists(DataFlow::PropWrite write, DataFlow::PropRead read |
read = write.getRhs()
or
exists(DataFlow::MethodCallNode stringify |
stringify = write.getRhs() and
stringify = DataFlow::globalVarRef("JSON").getAMethodCall("stringify") and
stringify.getArgument(0) = read
exists(JsonStringifyCall stringify |
stringify.getOutput() = write.getRhs() and
stringify.getInput() = read
)
|
not exists(write.getPropertyName()) and

View File

@@ -36,7 +36,7 @@ module ImproperCodeSanitization {
* A call to `JSON.stringify()` seen as a source for improper code sanitization
*/
class JSONStringifyAsSource extends Source {
JSONStringifyAsSource() { this = DataFlow::globalVarRef("JSON").getAMemberCall("stringify") }
JSONStringifyAsSource() { this instanceof JsonStringifyCall }
}
/**

View File

@@ -49,8 +49,7 @@ module PostMessageStar {
exists(DataFlow::InvokeNode toString | toString = trg |
toString.(DataFlow::MethodCallNode).calls(src, "toString")
or
toString = DataFlow::globalVarRef("JSON").getAMemberCall("stringify") and
src = toString.getArgument(0)
src = toString.(JsonStringifyCall).getInput()
) and
inlbl instanceof PartiallyTaintedObject and
outlbl.isTaint()

View File

@@ -68,6 +68,18 @@ typeInferenceMismatch
| exceptions.js:158:13:158:20 | source() | exceptions.js:161:10:161:10 | e |
| importedReactComponent.jsx:4:40:4:47 | source() | exportedReactComponent.jsx:2:10:2:19 | props.text |
| indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:5:8:5:29 | JSON.st ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:9:8:9:47 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:10:8:10:42 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:11:8:11:41 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:12:8:12:52 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:13:8:13:45 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:14:8:14:46 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:15:8:15:38 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:16:8:16:38 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:17:8:17:39 | require ... source) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:18:8:18:40 | require ... source) |
| json-stringify.js:3:15:3:22 | source() | json-stringify.js:8:8:8:31 | jsonStr ... (taint) |
| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x |
| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y |
| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) |

View File

@@ -0,0 +1,19 @@
function foo() {
let source = source();
let taint = source();
sink(JSON.stringify(source)); // NOT OK
var jsonStringifySafe = require("json-stringify-safe");
sink(jsonStringifySafe(taint)); // NOT OK
sink(require("json-stable-stringify")(source)); // NOT OK
sink(require("stringify-object")(source)); // NOT OK
sink(require("json3").stringify(source)); // NOT OK
sink(require("fast-json-stable-stringify")(source)); // NOT OK
sink(require("fast-safe-stringify")(source)); // NOT OK
sink(require("javascript-stringify")(source)); // NOT OK
sink(require("js-stringify")(source)); // NOT OK
sink(require("util").inspect(source)); // NOT OK
sink(require("pretty-format")(source)); // NOT OK
sink(require("object-inspect")(source)); // NOT OK
}