Skip to content

Commit 604a5fc

Browse files
authored
Merge pull request #8639 from atorralba/atorralba/spring-beans-improvements
Java: Improve Spring models
2 parents 52a417b + 9833fa2 commit 604a5fc

39 files changed

+1031
-1132
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added data-flow models for the Spring Framework component `spring-beans`.

java/ql/lib/semmle/code/java/frameworks/spring/SpringBeans.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ private class FlowSummaries extends SummaryModelCsv {
2222
"org.springframework.beans;PropertyValue;false;getValue;;;Argument[-1].MapValue;ReturnValue;value",
2323
"org.springframework.beans;PropertyValues;true;getPropertyValue;;;Argument[-1].Element;ReturnValue;value",
2424
"org.springframework.beans;PropertyValues;true;getPropertyValues;;;Argument[-1].Element;ReturnValue.ArrayElement;value",
25+
"org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(List);;Argument[0].Element;Argument[-1].Element;value",
26+
"org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapKey;Argument[-1].Element.MapKey;value",
27+
"org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(Map);;Argument[0].MapValue;Argument[-1].Element.MapValue;value",
28+
"org.springframework.beans;MutablePropertyValues;true;MutablePropertyValues;(PropertyValues);;Argument[0].Element;Argument[-1].Element;value",
2529
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value",
2630
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value",
2731
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];Argument[-1].Element.MapValue;value",

java/ql/lib/semmle/code/java/frameworks/spring/SpringWeb.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
import java
66

77
/** An interface for web requests in the Spring framework. */
8-
class SpringWebRequest extends Class {
8+
class SpringWebRequest extends Interface {
99
SpringWebRequest() {
1010
this.hasQualifiedName("org.springframework.web.context.request", "WebRequest")
1111
}
1212
}
1313

1414
/** An interface for web requests in the Spring framework. */
15-
class SpringNativeWebRequest extends Class {
15+
class SpringNativeWebRequest extends Interface {
1616
SpringNativeWebRequest() {
1717
this.hasQualifiedName("org.springframework.web.context.request", "NativeWebRequest")
1818
}

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

Lines changed: 260 additions & 275 deletions
Large diffs are not rendered by default.
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import java.io.InputStream;
2+
import java.io.OutputStream;
3+
import java.io.Reader;
4+
import java.io.Writer;
5+
import java.security.Principal;
6+
import java.time.ZoneId;
7+
import java.util.Locale;
8+
import java.util.TimeZone;
9+
import javax.servlet.http.HttpSession;
10+
import javax.servlet.http.PushBuilder;
11+
import javax.servlet.ServletRequest;
12+
import org.springframework.data.domain.Pageable;
13+
import org.springframework.http.HttpEntity;
14+
import org.springframework.http.HttpMethod;
15+
import org.springframework.stereotype.Controller;
16+
import org.springframework.validation.Errors;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.RequestParam;
19+
import org.springframework.web.util.UriComponentsBuilder;
20+
import org.springframework.web.context.request.WebRequest;
21+
import org.springframework.web.context.request.NativeWebRequest;
22+
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
23+
import org.springframework.web.bind.support.SessionStatus;
24+
import org.springframework.web.bind.annotation.MatrixVariable;
25+
import org.springframework.web.bind.annotation.RequestHeader;
26+
import org.springframework.web.bind.annotation.CookieValue;
27+
import org.springframework.web.bind.annotation.RequestPart;
28+
import org.springframework.web.bind.annotation.PathVariable;
29+
import org.springframework.web.bind.annotation.RequestBody;
30+
import org.springframework.web.bind.annotation.RequestAttribute;
31+
import org.springframework.web.bind.annotation.SessionAttribute;
32+
33+
public class Test {
34+
35+
static void sink(Object o) {}
36+
37+
@Controller
38+
static class NotTaintedTest {
39+
@RequestMapping("/")
40+
public void get(WebRequest src) {
41+
sink(src);
42+
}
43+
44+
@RequestMapping("/")
45+
public void get(NativeWebRequest src) {
46+
sink(src);
47+
}
48+
49+
@RequestMapping("/")
50+
public void get(ServletRequest src) {
51+
sink(src);
52+
}
53+
54+
@RequestMapping("/")
55+
public void get(HttpSession src) {
56+
sink(src);
57+
}
58+
59+
@RequestMapping("/")
60+
public void get(PushBuilder src) {
61+
sink(src);
62+
}
63+
64+
@RequestMapping("/")
65+
public void get(Principal src) {
66+
sink(src);
67+
}
68+
69+
@RequestMapping("/")
70+
public void get(HttpMethod src) {
71+
sink(src);
72+
}
73+
74+
@RequestMapping("/")
75+
public void get(Locale src) {
76+
sink(src);
77+
}
78+
79+
@RequestMapping("/")
80+
public void get(TimeZone src) {
81+
sink(src);
82+
}
83+
84+
@RequestMapping("/")
85+
public void get(ZoneId src) {
86+
sink(src);
87+
}
88+
89+
@RequestMapping("/")
90+
public void get(OutputStream src) {
91+
sink(src);
92+
}
93+
94+
@RequestMapping("/")
95+
public void get(Writer src) {
96+
sink(src);
97+
}
98+
99+
@RequestMapping("/")
100+
public void get(RedirectAttributes src) {
101+
sink(src);
102+
}
103+
104+
@RequestMapping("/")
105+
public void get(Errors src) {
106+
sink(src);
107+
}
108+
109+
@RequestMapping("/")
110+
public void get(SessionStatus src) {
111+
sink(src);
112+
}
113+
114+
@RequestMapping("/")
115+
public void get(UriComponentsBuilder src) {
116+
sink(src);
117+
}
118+
119+
@RequestMapping("/")
120+
public void get(Pageable src) {
121+
sink(src);
122+
}
123+
}
124+
125+
@Controller
126+
static class ExplicitlyTaintedTest {
127+
@RequestMapping("/")
128+
public void get(InputStream src) {
129+
sink(src); // $hasValueFlow
130+
}
131+
132+
@RequestMapping("/")
133+
public void get(Reader src) {
134+
sink(src); // $hasValueFlow
135+
}
136+
137+
@RequestMapping("/")
138+
public void matrixVariable(@MatrixVariable Object src) {
139+
sink(src); // $hasValueFlow
140+
}
141+
142+
@RequestMapping("/")
143+
public void requestParam(@RequestParam Object src) {
144+
sink(src); // $hasValueFlow
145+
}
146+
147+
@RequestMapping("/")
148+
public void requestHeader(@RequestHeader Object src) {
149+
sink(src); // $hasValueFlow
150+
}
151+
152+
@RequestMapping("/")
153+
public void cookieValue(@CookieValue Object src) {
154+
sink(src); // $hasValueFlow
155+
}
156+
157+
@RequestMapping("/")
158+
public void requestPart(@RequestPart Object src) {
159+
sink(src); // $hasValueFlow
160+
}
161+
162+
@RequestMapping("/")
163+
public void pathVariable(@PathVariable Object src) {
164+
sink(src); // $hasValueFlow
165+
}
166+
167+
@RequestMapping("/")
168+
public void requestBody(@RequestBody Object src) {
169+
sink(src); // $hasValueFlow
170+
}
171+
172+
@RequestMapping("/")
173+
public void get(HttpEntity src) {
174+
sink(src); // $hasValueFlow
175+
}
176+
177+
@RequestMapping("/")
178+
public void requestAttribute(@RequestAttribute Object src) {
179+
sink(src); // $hasValueFlow
180+
}
181+
182+
@RequestMapping("/")
183+
public void sessionAttribute(@SessionAttribute Object src) {
184+
sink(src); // $hasValueFlow
185+
}
186+
}
187+
188+
@Controller
189+
static class ImplicitlyTaintedTest {
190+
static class Pojo {
191+
}
192+
193+
@RequestMapping("/")
194+
public void get(String src) {
195+
sink(src); // $hasValueFlow
196+
}
197+
198+
@RequestMapping("/")
199+
public void get1(Pojo src) {
200+
sink(src); // $hasValueFlow
201+
}
202+
}
203+
}
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:${testdir}/../../../../stubs/javax-servlet-2.5

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

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
import TestUtilities.InlineFlowTest
4+
5+
class ValueFlowConf extends DataFlow::Configuration {
6+
ValueFlowConf() { this = "ValueFlowConf" }
7+
8+
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
9+
10+
override predicate isSink(DataFlow::Node sink) {
11+
sink.asExpr().(Argument).getCall().getCallee().hasName("sink")
12+
}
13+
}
14+
15+
class Test extends InlineFlowTest {
16+
override DataFlow::Configuration getValueFlowConfig() { result = any(ValueFlowConf config) }
17+
}

java/ql/test/stubs/springframework-5.3.8/org/springframework/context/support/DefaultMessageSourceResolvable.java

Lines changed: 19 additions & 71 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

java/ql/test/stubs/springframework-5.3.8/org/springframework/data/domain/Pageable.java

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)