Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 98204a1

Browse files
committed
Fix the problem
1 parent c5577cb commit 98204a1

44 files changed

Lines changed: 1073 additions & 386 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import semmle.code.java.dataflow.DataFlow
33
import semmle.code.java.dataflow.FlowSources
44
import DataFlow::PathGraph
55

6-
/** Json string type data */
6+
/** Json string type data. */
77
abstract class JsonpStringSource extends DataFlow::Node { }
88

99
/** Convert to String using Gson library. */
Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
11
import com.alibaba.fastjson.JSONObject;
22
import com.fasterxml.jackson.databind.ObjectMapper;
33
import com.google.gson.Gson;
4+
import java.io.BufferedReader;
5+
import java.io.IOException;
6+
import java.io.InputStreamReader;
47
import java.io.PrintWriter;
58
import java.util.HashMap;
6-
import java.util.Random;
79
import javax.servlet.http.HttpServletRequest;
810
import javax.servlet.http.HttpServletResponse;
911
import org.springframework.stereotype.Controller;
1012
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.RequestMapping;
14+
import org.springframework.web.bind.annotation.RequestMethod;
15+
import org.springframework.web.bind.annotation.RequestParam;
1116
import org.springframework.web.bind.annotation.ResponseBody;
17+
import org.springframework.web.multipart.MultipartFile;
1218

1319
@Controller
1420
public class JsonpInjection {
15-
private static HashMap hashMap = new HashMap();
21+
22+
private static HashMap hashMap = new HashMap();
1623

1724
static {
1825
hashMap.put("username","admin");
1926
hashMap.put("password","123456");
2027
}
2128

29+
private String name = null;
30+
2231

2332
@GetMapping(value = "jsonp1")
2433
@ResponseBody
2534
public String bad1(HttpServletRequest request) {
2635
String resultStr = null;
2736
String jsonpCallback = request.getParameter("jsonpCallback");
28-
2937
Gson gson = new Gson();
3038
String result = gson.toJson(hashMap);
3139
resultStr = jsonpCallback + "(" + result + ")";
@@ -37,9 +45,7 @@ public String bad1(HttpServletRequest request) {
3745
public String bad2(HttpServletRequest request) {
3846
String resultStr = null;
3947
String jsonpCallback = request.getParameter("jsonpCallback");
40-
4148
resultStr = jsonpCallback + "(" + JSONObject.toJSONString(hashMap) + ")";
42-
4349
return resultStr;
4450
}
4551

@@ -67,7 +73,6 @@ public String bad4(HttpServletRequest request) {
6773
@ResponseBody
6874
public void bad5(HttpServletRequest request,
6975
HttpServletResponse response) throws Exception {
70-
response.setContentType("application/json");
7176
String jsonpCallback = request.getParameter("jsonpCallback");
7277
PrintWriter pw = null;
7378
Gson gson = new Gson();
@@ -83,7 +88,6 @@ public void bad5(HttpServletRequest request,
8388
@ResponseBody
8489
public void bad6(HttpServletRequest request,
8590
HttpServletResponse response) throws Exception {
86-
response.setContentType("application/json");
8791
String jsonpCallback = request.getParameter("jsonpCallback");
8892
PrintWriter pw = null;
8993
ObjectMapper mapper = new ObjectMapper();
@@ -94,60 +98,96 @@ public void bad6(HttpServletRequest request,
9498
pw.println(resultStr);
9599
}
96100

97-
@GetMapping(value = "jsonp7")
101+
@RequestMapping(value = "jsonp7", method = RequestMethod.GET)
98102
@ResponseBody
99-
public String good(HttpServletRequest request) {
103+
public String bad7(HttpServletRequest request) {
100104
String resultStr = null;
101105
String jsonpCallback = request.getParameter("jsonpCallback");
102-
103-
String val = "";
104-
Random random = new Random();
105-
for (int i = 0; i < 10; i++) {
106-
val += String.valueOf(random.nextInt(10));
107-
}
108-
// good
109-
jsonpCallback = jsonpCallback + "_" + val;
110-
String jsonStr = getJsonStr(hashMap);
111-
resultStr = jsonpCallback + "(" + jsonStr + ")";
106+
Gson gson = new Gson();
107+
String result = gson.toJson(hashMap);
108+
resultStr = jsonpCallback + "(" + result + ")";
112109
return resultStr;
113110
}
114111

112+
115113
@GetMapping(value = "jsonp8")
116114
@ResponseBody
117115
public String good1(HttpServletRequest request) {
118116
String resultStr = null;
119-
String jsonpCallback = request.getParameter("jsonpCallback");
120-
121117
String token = request.getParameter("token");
122-
123-
// good
124118
if (verifToken(token)){
125-
System.out.println(token);
119+
String jsonpCallback = request.getParameter("jsonpCallback");
126120
String jsonStr = getJsonStr(hashMap);
127121
resultStr = jsonpCallback + "(" + jsonStr + ")";
128122
return resultStr;
129123
}
130-
131124
return "error";
132125
}
133126

127+
134128
@GetMapping(value = "jsonp9")
135129
@ResponseBody
136130
public String good2(HttpServletRequest request) {
137131
String resultStr = null;
132+
String token = request.getParameter("token");
133+
boolean result = verifToken(token);
134+
if (result){
135+
return "";
136+
}
138137
String jsonpCallback = request.getParameter("jsonpCallback");
138+
String jsonStr = getJsonStr(hashMap);
139+
resultStr = jsonpCallback + "(" + jsonStr + ")";
140+
return resultStr;
141+
}
139142

140-
String referer = request.getHeader("Referer");
143+
@RequestMapping(value = "jsonp10")
144+
@ResponseBody
145+
public String good3(HttpServletRequest request) {
146+
JSONObject parameterObj = readToJSONObect(request);
147+
String resultStr = null;
148+
String jsonpCallback = request.getParameter("jsonpCallback");
149+
String restr = JSONObject.toJSONString(hashMap);
150+
resultStr = jsonpCallback + "(" + restr + ");";
151+
return resultStr;
152+
}
141153

142-
boolean result = verifReferer(referer);
143-
// good
144-
if (result){
145-
String jsonStr = getJsonStr(hashMap);
146-
resultStr = jsonpCallback + "(" + jsonStr + ")";
147-
return resultStr;
154+
@RequestMapping(value = "jsonp11")
155+
@ResponseBody
156+
public String good4(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
157+
if(null == file){
158+
return "upload file error";
148159
}
160+
String fileName = file.getOriginalFilename();
161+
System.out.println("file operations");
162+
String resultStr = null;
163+
String jsonpCallback = request.getParameter("jsonpCallback");
164+
String restr = JSONObject.toJSONString(hashMap);
165+
resultStr = jsonpCallback + "(" + restr + ");";
166+
return resultStr;
167+
}
149168

150-
return "error";
169+
public static JSONObject readToJSONObect(HttpServletRequest request){
170+
String jsonText = readPostContent(request);
171+
JSONObject jsonObj = JSONObject.parseObject(jsonText, JSONObject.class);
172+
return jsonObj;
173+
}
174+
175+
public static String readPostContent(HttpServletRequest request){
176+
BufferedReader in= null;
177+
String content = null;
178+
String line = null;
179+
try {
180+
in = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8"));
181+
StringBuilder buf = new StringBuilder();
182+
while ((line = in.readLine()) != null) {
183+
buf.append(line);
184+
}
185+
content = buf.toString();
186+
} catch (IOException e) {
187+
e.printStackTrace();
188+
}
189+
String uri = request.getRequestURI();
190+
return content;
151191
}
152192

153193
public static String getJsonStr(Object result) {
@@ -160,11 +200,4 @@ public static boolean verifToken(String token){
160200
}
161201
return true;
162202
}
163-
164-
public static boolean verifReferer(String referer){
165-
if (!referer.startsWith("http://test.com/")){
166-
return false;
167-
}
168-
return true;
169-
}
170203
}

java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
"qhelp.dtd">
44
<qhelp>
55
<overview>
6-
<p>The software uses external input as the function name to wrap JSON data and return it to the client as a request response. When there is a cross-domain problem,
7-
there is a problem of sensitive information leakage.</p>
6+
<p>The software uses external input as the function name to wrap JSON data and returns it to the client as a request response.
7+
When there is a cross-domain problem, the problem of sensitive information leakage may occur.</p>
88

99
</overview>
1010
<recommendation>
1111

12-
<p>Adding `Referer` or random `token` verification processing can effectively prevent the leakage of sensitive information.</p>
12+
<p>Adding <code>Referer</code>/<code>Origin</code> or random <code>token</code> verification processing can effectively prevent the leakage of sensitive information.</p>
1313

1414
</recommendation>
1515
<example>
1616

17-
<p>The following example shows the case of no verification processing and verification processing for the external input function name.</p>
17+
<p>The following examples show the bad case and the good case respectively. Bad case, such as <code>bad1</code> to <code>bad7</code>,
18+
will cause information leakage problems when there are cross-domain problems. In a good case, for example, in the <code>good1</code>
19+
method and the <code>good2</code> method, use the <code>verifToken</code> method to do the random <code>token</code> Verification can
20+
solve the problem of information leakage caused by cross-domain.</p>
1821

1922
<sample src="JsonpInjection.java" />
2023

java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,41 @@ import java
1414
import JsonpInjectionLib
1515
import semmle.code.java.dataflow.FlowSources
1616
import semmle.code.java.deadcode.WebEntryPoints
17-
import semmle.code.java.security.XSS
1817
import DataFlow::PathGraph
1918

2019
/** Determine whether there is a verification method for the remote streaming source data flow path method. */
2120
predicate existsFilterVerificationMethod() {
22-
exists(MethodAccess ma,Node existsNode, Method m|
21+
exists(MethodAccess ma, Node existsNode, Method m |
2322
ma.getMethod() instanceof VerificationMethodClass and
2423
existsNode.asExpr() = ma and
25-
m = getAnMethod(existsNode.getEnclosingCallable()) and
24+
m = getACallingCallableOrSelf(existsNode.getEnclosingCallable()) and
2625
isDoFilterMethod(m)
2726
)
2827
}
2928

3029
/** Determine whether there is a verification method for the remote streaming source data flow path method. */
3130
predicate existsServletVerificationMethod(Node checkNode) {
32-
exists(MethodAccess ma,Node existsNode|
31+
exists(MethodAccess ma, Node existsNode |
3332
ma.getMethod() instanceof VerificationMethodClass and
3433
existsNode.asExpr() = ma and
35-
getAnMethod(existsNode.getEnclosingCallable()) = getAnMethod(checkNode.getEnclosingCallable())
34+
getACallingCallableOrSelf(existsNode.getEnclosingCallable()) =
35+
getACallingCallableOrSelf(checkNode.getEnclosingCallable())
3636
)
3737
}
3838

3939
/** Taint-tracking configuration tracing flow from get method request sources to output jsonp data. */
4040
class RequestResponseFlowConfig extends TaintTracking::Configuration {
4141
RequestResponseFlowConfig() { this = "RequestResponseFlowConfig" }
4242

43-
override predicate isSource(DataFlow::Node source) {
44-
source instanceof RemoteFlowSource and
45-
getAnMethod(source.getEnclosingCallable()) instanceof RequestGetMethod
46-
}
43+
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
4744

4845
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
4946

47+
/** Eliminate the method of calling the node is not the get method. */
48+
override predicate isSanitizer(DataFlow::Node node) {
49+
not getACallingCallableOrSelf(node.getEnclosingCallable()) instanceof RequestGetMethod
50+
}
51+
5052
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
5153
exists(MethodAccess ma |
5254
isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma
@@ -60,5 +62,5 @@ where
6062
not existsFilterVerificationMethod() and
6163
conf.hasFlowPath(source, sink) and
6264
exists(JsonpInjectionFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode()))
63-
select sink.getNode(), source, sink, "Jsonp Injection query might include code from $@.",
64-
source.getNode(), "this user input"
65+
select sink.getNode(), source, sink, "Jsonp response might include code from $@.", source.getNode(),
66+
"this user input"

0 commit comments

Comments
 (0)