Skip to content

Commit 08cba7d

Browse files
authored
Merge pull request #13713 from pwntester/java/struts2_source_taint_inheriting
[Java] Implement field taint inheritance for Struts2 unmarshalled objects
2 parents a020189 + c3a2ae2 commit 08cba7d

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved the modeling of Struts 2 sources of untrusted data by tainting the whole object graph of the objects unmarshaled from an HTTP request.
5+

java/ql/lib/semmle/code/java/Serializability.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import java
66
private import frameworks.jackson.JacksonSerializability
77
private import frameworks.google.GsonSerializability
88
private import frameworks.google.GoogleHttpClientApi
9+
private import frameworks.struts.Struts2Serializability
910

1011
/**
1112
* A serializable field may be read without code referencing it,

java/ql/lib/semmle/code/java/dataflow/FlowSources.qll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,10 @@ private class GuiceRequestParameterSource extends RemoteFlowSource {
143143
override string getSourceType() { result = "Guice request parameter" }
144144
}
145145

146-
private class Struts2ActionSupportClassFieldReadSource extends RemoteFlowSource {
147-
Struts2ActionSupportClassFieldReadSource() {
148-
exists(Struts2ActionSupportClass c |
149-
c.getASetterMethod().getField() = this.asExpr().(FieldRead).getField()
150-
)
146+
private class Struts2ActionSupportClassFieldSource extends RemoteFlowSource {
147+
Struts2ActionSupportClassFieldSource() {
148+
this.(DataFlow::FieldValueNode).getField() =
149+
any(Struts2ActionSupportClass c).getASetterMethod().getField()
151150
}
152151

153152
override string getSourceType() { result = "Struts2 ActionSupport field" }
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Provides classes and predicates for working with objects bound from Http requests in the context of
3+
* the Struts2 web framework.
4+
*/
5+
6+
import java
7+
private import semmle.code.java.Serializability
8+
private import semmle.code.java.dataflow.DataFlow
9+
private import semmle.code.java.dataflow.FlowSteps
10+
private import semmle.code.java.frameworks.struts.StrutsActions
11+
12+
/** A type whose values may be unmarshalled from an Http request by the Struts2 framework. */
13+
abstract class Struts2DeserializableType extends Type { }
14+
15+
/** A type whose values are explicitly unmarshalled by from an Http request by the Struts2 framework. */
16+
private class ExplicitlyReadStruts2DeserializableType extends Struts2DeserializableType {
17+
ExplicitlyReadStruts2DeserializableType() {
18+
exists(Struts2ActionSupportClass c |
19+
usesType(c.getASetterMethod().getField().getType(), this) and
20+
not this instanceof TypeClass and
21+
not this instanceof TypeObject
22+
)
23+
}
24+
}
25+
26+
/** A type used in a `Struts2ActionField` declaration. */
27+
private class FieldReferencedStruts2DeserializableType extends Struts2DeserializableType {
28+
FieldReferencedStruts2DeserializableType() {
29+
exists(Struts2ActionField f | usesType(f.getType(), this))
30+
}
31+
}
32+
33+
/** A field that may be unmarshalled from an Http request using the Struts2 framework. */
34+
private class Struts2ActionField extends DeserializableField {
35+
Struts2ActionField() {
36+
exists(Struts2DeserializableType superType |
37+
superType = this.getDeclaringType().getAnAncestor() and
38+
not superType instanceof TypeObject and
39+
superType.fromSource() and
40+
(
41+
this.isPublic()
42+
or
43+
exists(SetterMethod setter | setter.getField() = this and setter.isPublic())
44+
)
45+
)
46+
}
47+
}
48+
49+
/** A field that should convey the taint from its qualifier to itself. */
50+
private class Struts2ActionFieldInheritTaint extends DataFlow::FieldContent, TaintInheritingContent {
51+
Struts2ActionFieldInheritTaint() { this.getField() instanceof Struts2ActionField }
52+
}

0 commit comments

Comments
 (0)