Skip to content

Commit d8b017e

Browse files
authored
Merge pull request github#6036 from atorralba/atorralba/spring-beans
Java: Flow summaries for Spring's Bean Properties classes
2 parents b8b6f05 + a3e1b13 commit d8b017e

File tree

11 files changed

+651
-0
lines changed

11 files changed

+651
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Added additional taint steps modeling the Spring classes `PropertyValue`, `PropertyValues` and `MutablePropertyValues`. (`org.springframework.beans.*`).

java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ private module Frameworks {
8787
private import semmle.code.java.frameworks.spring.SpringHttp
8888
private import semmle.code.java.frameworks.spring.SpringUtil
8989
private import semmle.code.java.frameworks.spring.SpringWebClient
90+
private import semmle.code.java.frameworks.spring.SpringBeans
9091
private import semmle.code.java.security.ResponseSplitting
9192
private import semmle.code.java.security.InformationLeak
9293
private import semmle.code.java.security.XSS

java/ql/src/semmle/code/java/frameworks/spring/Spring.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import semmle.code.java.frameworks.spring.SpringAttribute
66
import semmle.code.java.frameworks.spring.SpringAutowire
77
import semmle.code.java.frameworks.spring.SpringBean
88
import semmle.code.java.frameworks.spring.SpringBeanFile
9+
import semmle.code.java.frameworks.spring.SpringBeans
910
import semmle.code.java.frameworks.spring.SpringBeanRefType
1011
import semmle.code.java.frameworks.spring.SpringComponentScan
1112
import semmle.code.java.frameworks.spring.SpringConstructorArg
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Provides classes and predicates for working with Spring classes and interfaces from
3+
* `org.springframework.beans`.
4+
*/
5+
6+
import java
7+
private import semmle.code.java.dataflow.ExternalFlow
8+
9+
/**
10+
* Provides models for the `org.springframework.beans` package.
11+
*/
12+
private class FlowSummaries extends SummaryModelCsv {
13+
override predicate row(string row) {
14+
row =
15+
[
16+
"org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[0];MapKey of Argument[-1];value",
17+
"org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[1];MapValue of Argument[-1];value",
18+
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue);;Argument[0];Argument[-1];value",
19+
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;MapKey of Argument[0];MapKey of Argument[-1];value",
20+
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[1];MapValue of Argument[-1];value",
21+
"org.springframework.beans;PropertyValue;false;getName;;;MapKey of Argument[-1];ReturnValue;value",
22+
"org.springframework.beans;PropertyValue;false;getValue;;;MapValue of Argument[-1];ReturnValue;value",
23+
"org.springframework.beans;PropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
24+
"org.springframework.beans;PropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
25+
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
26+
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value",
27+
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
28+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[0];Element of Argument[-1];value",
29+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[-1];ReturnValue;value",
30+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
31+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
32+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapKey of Argument[0];MapKey of Element of Argument[-1];value",
33+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapValue of Argument[0];MapValue of Element of Argument[-1];value",
34+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[-1];ReturnValue;value",
35+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Element of Argument[0];Element of Argument[-1];value",
36+
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[-1];ReturnValue;value",
37+
"org.springframework.beans;MutablePropertyValues;true;get;;;MapValue of Element of Argument[-1];ReturnValue;value",
38+
"org.springframework.beans;MutablePropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
39+
"org.springframework.beans;MutablePropertyValues;true;getPropertyValueList;;;Element of Argument[-1];Element of ReturnValue;value",
40+
"org.springframework.beans;MutablePropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
41+
"org.springframework.beans;MutablePropertyValues;true;setPropertyValueAt;;;Argument[0];Element of Argument[-1];value"
42+
]
43+
}
44+
}
Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
package generatedtest;
2+
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
import org.springframework.beans.MutablePropertyValues;
7+
import org.springframework.beans.PropertyValue;
8+
import org.springframework.beans.PropertyValues;
9+
10+
11+
public class Test {
12+
Object getMapKey(PropertyValue container) {
13+
return container.getName();
14+
}
15+
16+
Object getMapValue(PropertyValue container) {
17+
return container.getValue();
18+
}
19+
20+
PropertyValue getElement(Iterable<PropertyValue> container) {
21+
return container.iterator().next();
22+
}
23+
24+
PropertyValue getArrayElement(PropertyValue[] container) {
25+
return container[0];
26+
}
27+
28+
PropertyValue newWithMapKey(String element) {
29+
return new PropertyValue(element, null);
30+
}
31+
32+
PropertyValue newWithMapValue(String element) {
33+
return new PropertyValue("", element);
34+
}
35+
36+
MutablePropertyValues newWithElement(PropertyValue element) {
37+
MutablePropertyValues pv = new MutablePropertyValues();
38+
pv.addPropertyValue(element);
39+
return pv;
40+
}
41+
42+
String source() {
43+
return null;
44+
}
45+
46+
void sink(Object o) {}
47+
48+
public void test() {
49+
// @formatter:off
50+
// "org.springframework.beans;PropertyValue;false;;(String,Object);;Argument[0];MapKey of Argument[-1];value",
51+
{
52+
PropertyValue v = new PropertyValue((String) source(), null);
53+
sink(getMapKey(v)); // $hasValueFlow
54+
sink(getMapValue(v)); // Safe
55+
}
56+
// "org.springframework.beans;PropertyValue;false;;(String,Object);;Argument[1];MapValue of Argument[-1];value",
57+
{
58+
PropertyValue v = new PropertyValue("", source());
59+
sink(getMapKey(v)); // Safe
60+
sink(getMapValue(v)); // $hasValueFlow
61+
}
62+
// "org.springframework.beans;PropertyValue;false;;(PropertyValue);;Argument[0];Argument[-1];value",
63+
{
64+
PropertyValue v1 = new PropertyValue((String) source(), null);
65+
PropertyValue v2 = new PropertyValue(v1);
66+
sink(getMapKey(v2)); // $hasValueFlow
67+
sink(getMapValue(v2)); // Safe
68+
69+
PropertyValue v3 = new PropertyValue("safe", source());
70+
PropertyValue v4 = new PropertyValue(v3);
71+
sink(getMapKey(v4)); // Safe
72+
sink(getMapValue(v4)); // $hasValueFlow
73+
}
74+
// "org.springframework.beans;PropertyValue;false;;(PropertyValue,Object);;MapKey of Argument[0];MapKey of Argument[-1];value",
75+
{
76+
PropertyValue v1 = new PropertyValue((String) source(), source());
77+
PropertyValue v2 = new PropertyValue(v1, null);
78+
sink(getMapKey(v2)); // $hasValueFlow
79+
sink(getMapValue(v2)); // Safe
80+
}
81+
// "org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[1];MapValue of Argument[-1];value",
82+
{
83+
PropertyValue v1 = new PropertyValue("safe", null);
84+
PropertyValue v2 = new PropertyValue(v1, source());
85+
sink(getMapKey(v2)); // Safe
86+
sink(getMapValue(v2)); // $hasValueFlow
87+
}
88+
// "org.springframework.beans;PropertyValue;false;getName;;;MapKey of Argument[-1];ReturnValue;value",
89+
{
90+
PropertyValue v = new PropertyValue((String) source(), null);
91+
sink(v.getName()); // $hasValueFlow
92+
sink(v.getValue()); // Safe
93+
}
94+
// "org.springframework.beans;PropertyValue;false;getValue;;;MapValue of Argument[-1];ReturnValue;value",
95+
{
96+
PropertyValue v = new PropertyValue("safe", source());
97+
sink(v.getName()); // Safe
98+
sink(v.getValue()); // $hasValueFlow
99+
}
100+
// "org.springframework.beans;PropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
101+
{
102+
PropertyValues pv = newWithElement(newWithMapValue(source()));
103+
sink(pv.getPropertyValue("safe").getValue()); // $hasValueFlow
104+
}
105+
// "org.springframework.beans;PropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
106+
{
107+
PropertyValues pv = newWithElement(newWithMapValue(source()));
108+
PropertyValue[] vs = pv.getPropertyValues();
109+
sink(getMapKey(getArrayElement(vs))); // Safe
110+
sink(getMapValue(getArrayElement(vs))); // $hasValueFlow
111+
}
112+
// "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
113+
{
114+
MutablePropertyValues pv = new MutablePropertyValues();
115+
pv.add((String) source(), null);
116+
sink(getMapKey(getElement(pv))); // $hasValueFlow
117+
sink(getMapValue(getElement(pv))); // Safe
118+
}
119+
// "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value",
120+
{
121+
MutablePropertyValues pv = new MutablePropertyValues();
122+
sink(getMapKey(getElement(pv.add(source(), null)))); // $hasValueFlow
123+
sink(getMapValue(getElement(pv.add(source(), null)))); // Safe
124+
}
125+
{
126+
MutablePropertyValues pv = new MutablePropertyValues();
127+
sink(getMapKey(getElement(pv.add("safe", source())))); // Safe
128+
sink(getMapValue(getElement(pv.add("safe", source())))); // $hasValueFlow
129+
}
130+
// "org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
131+
{
132+
MutablePropertyValues pv = new MutablePropertyValues();
133+
pv.add("safe", source());
134+
sink(getMapKey(getElement(pv))); // Safe
135+
sink(getMapValue(getElement(pv))); // $hasValueFlow
136+
}
137+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[0];Element of Argument[-1];value",
138+
{
139+
MutablePropertyValues pv1 = new MutablePropertyValues();
140+
PropertyValue v1 = newWithMapKey(source());
141+
pv1.addPropertyValue(v1);
142+
sink(getMapKey(getElement(pv1))); // $hasValueFlow
143+
sink(getMapValue(getElement(pv1))); // Safe
144+
145+
MutablePropertyValues pv2 = new MutablePropertyValues();
146+
PropertyValue v2 = newWithMapValue(source());
147+
pv2.addPropertyValue(v2);
148+
sink(getMapKey(getElement(pv2))); // Safe
149+
sink(getMapValue(getElement(pv2))); // $hasValueFlow
150+
}
151+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[-1];ReturnValue;value",
152+
{
153+
MutablePropertyValues pv1 = new MutablePropertyValues();
154+
PropertyValue v1 = newWithMapKey(source());
155+
PropertyValues pv2 = pv1.addPropertyValue(v1);
156+
sink(getMapKey(getElement(pv2))); // $hasValueFlow
157+
sink(getMapValue(getElement(pv2))); // Safe
158+
159+
MutablePropertyValues pv3 = new MutablePropertyValues();
160+
PropertyValue v2 = newWithMapValue(source());
161+
PropertyValues pv4 = pv3.addPropertyValue(v2);
162+
sink(getMapKey(getElement(pv4))); // Safe
163+
sink(getMapValue(getElement(pv4))); // $hasValueFlow
164+
}
165+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
166+
{
167+
MutablePropertyValues pv = new MutablePropertyValues();
168+
pv.addPropertyValue((String)source(), null);
169+
sink(getMapKey(getElement(pv))); // $hasValueFlow
170+
sink(getMapValue(getElement(pv))); // Safe
171+
}
172+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
173+
{
174+
MutablePropertyValues pv = new MutablePropertyValues();
175+
pv.addPropertyValue("safe", source());
176+
sink(getMapKey(getElement(pv))); // Safe
177+
sink(getMapValue(getElement(pv))); // $hasValueFlow
178+
}
179+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapKey of Argument[0];MapKey of Element of Argument[-1];value",
180+
{
181+
MutablePropertyValues pv = new MutablePropertyValues();
182+
Map<String, Object> values = new HashMap<String, Object>();
183+
values.put(source(), null);
184+
pv.addPropertyValues(values);
185+
sink(getMapKey(getElement(pv))); // $hasValueFlow
186+
sink(getMapValue(getElement(pv))); // Safe
187+
}
188+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapValue of Argument[0];MapValue of Element of Argument[-1];value",
189+
{
190+
MutablePropertyValues pv = new MutablePropertyValues();
191+
Map<String, Object> values = new HashMap<String, Object>();
192+
values.put("", source());
193+
pv.addPropertyValues(values);
194+
sink(getMapKey(getElement(pv))); // Safe
195+
sink(getMapValue(getElement(pv))); // $hasValueFlow
196+
}
197+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[-1];ReturnValue;value",
198+
{
199+
MutablePropertyValues pv = new MutablePropertyValues();
200+
Map<String, Object> values = new HashMap<String, Object>();
201+
values.put("", source());
202+
PropertyValues pv2 = pv.addPropertyValues(values);
203+
sink(getMapKey(getElement(pv2))); // Safe
204+
sink(getMapValue(getElement(pv2))); // $hasValueFlow
205+
}
206+
{
207+
MutablePropertyValues pv = new MutablePropertyValues();
208+
Map<String, Object> values = new HashMap<String, Object>();
209+
values.put(source(), null);
210+
PropertyValues pv2 = pv.addPropertyValues(values);
211+
sink(getMapKey(getElement(pv2))); // $hasValueFlow
212+
sink(getMapValue(getElement(pv2))); // Safe
213+
}
214+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Element of Argument[0];Element of Argument[-1];value",
215+
{
216+
MutablePropertyValues pv = new MutablePropertyValues();
217+
PropertyValues values = newWithElement(newWithMapKey(source()));
218+
pv.addPropertyValues(values);
219+
sink(getMapKey(getElement(pv))); // $hasValueFlow
220+
sink(getMapValue(getElement(pv))); // Safe
221+
}
222+
{
223+
MutablePropertyValues pv = new MutablePropertyValues();
224+
PropertyValues values = newWithElement(newWithMapValue(source()));
225+
pv.addPropertyValues(values);
226+
sink(getMapKey(getElement(pv))); // Safe
227+
sink(getMapValue(getElement(pv))); // $hasValueFlow
228+
}
229+
// "org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[-1];ReturnValue;value",
230+
{
231+
MutablePropertyValues pv = new MutablePropertyValues();
232+
PropertyValues values = newWithElement(newWithMapKey(source()));
233+
PropertyValues pv2 = pv.addPropertyValues(values);
234+
sink(getMapKey(getElement(pv2))); // $hasValueFlow
235+
sink(getMapValue(getElement(pv2))); // Safe
236+
}
237+
{
238+
MutablePropertyValues pv = new MutablePropertyValues();
239+
PropertyValues values = newWithElement(newWithMapValue(source()));
240+
PropertyValues pv2 = pv.addPropertyValues(values);
241+
sink(getMapKey(getElement(pv2))); // Safe
242+
sink(getMapValue(getElement(pv2))); // $hasValueFlow
243+
}
244+
// "org.springframework.beans;MutablePropertyValues;true;get;;;MapValue of Element of Argument[-1];ReturnValue;value",
245+
{
246+
MutablePropertyValues pv = newWithElement(newWithMapValue(source()));
247+
sink(pv.get("something")); // $hasValueFlow
248+
}
249+
// "org.springframework.beans;MutablePropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
250+
{
251+
MutablePropertyValues pv1 = newWithElement(newWithMapKey(source()));
252+
sink(pv1.getPropertyValue("something").getName()); // $hasValueFlow
253+
sink(pv1.getPropertyValue("something").getValue()); // Safe
254+
255+
MutablePropertyValues pv2 = newWithElement(newWithMapValue(source()));
256+
sink(pv2.getPropertyValue("something").getName()); // Safe
257+
sink(pv2.getPropertyValue("something").getValue()); // $hasValueFlow
258+
}
259+
// "org.springframework.beans;MutablePropertyValues;true;getPropertyValueList;;;Element of Argument[-1];Element of ReturnValue;value",
260+
{
261+
MutablePropertyValues pv1 = newWithElement(newWithMapKey(source()));
262+
List<PropertyValue> pvl1 = pv1.getPropertyValueList();
263+
sink(getMapKey(getElement(pvl1))); // $hasValueFlow
264+
sink(getMapValue(getElement(pvl1))); // Safe
265+
266+
MutablePropertyValues pv2 = newWithElement(newWithMapValue(source()));
267+
List<PropertyValue> pvl2 = pv2.getPropertyValueList();
268+
sink(getMapKey(getElement(pvl2))); // Safe
269+
sink(getMapValue(getElement(pvl2))); // $hasValueFlow
270+
}
271+
// "org.springframework.beans;MutablePropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
272+
{
273+
MutablePropertyValues pv1 = newWithElement(newWithMapKey(source()));
274+
PropertyValue[] pvl1 = pv1.getPropertyValues();
275+
sink(getMapKey(getArrayElement(pvl1))); // $hasValueFlow
276+
sink(getMapValue(getArrayElement(pvl1))); // Safe
277+
278+
MutablePropertyValues pv2 = newWithElement(newWithMapValue(source()));
279+
PropertyValue[] pvl2 = pv2.getPropertyValues();
280+
sink(getMapKey(getArrayElement(pvl2))); // Safe
281+
sink(getMapValue(getArrayElement(pvl2))); // $hasValueFlow
282+
}
283+
// "org.springframework.beans;MutablePropertyValues;true;setPropertyValueAt;;;Argument[0];Element of Argument[-1];value"
284+
{
285+
MutablePropertyValues pv1 = new MutablePropertyValues();
286+
PropertyValue v1 = newWithMapKey(source());
287+
pv1.setPropertyValueAt(v1, 0);
288+
sink(getMapKey(getElement(pv1))); // $hasValueFlow
289+
sink(getMapValue(getElement(pv1))); // Safe
290+
291+
MutablePropertyValues pv2 = new MutablePropertyValues();
292+
PropertyValue v2 = newWithMapValue(source());
293+
pv2.setPropertyValueAt(v2, 0);
294+
sink(getMapKey(getElement(pv2))); // Safe
295+
sink(getMapValue(getElement(pv2))); // $hasValueFlow
296+
}
297+
// @formatter:on
298+
}
299+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8

java/ql/test/library-tests/frameworks/spring/beans/test.expected

Whitespace-only changes.

0 commit comments

Comments
 (0)