This commit is contained in:
haby0
2021-02-24 20:59:51 +08:00
parent 872a000a33
commit 6fe8bafc7d
7 changed files with 0 additions and 446 deletions

View File

@@ -1,119 +0,0 @@
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class JsonHijacking {
private static HashMap hashMap = new HashMap();
static {
hashMap.put("username","admin");
hashMap.put("password","123456");
}
@GetMapping(value = "jsonp1")
@ResponseBody
public String bad1(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
Gson gson = new Gson();
String result = gson.toJson(hashMap);
resultStr = jsonpCallback + "(" + result + ")";
return resultStr;
}
@GetMapping(value = "jsonp2")
@ResponseBody
public String bad2(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
resultStr = jsonpCallback + "(" + JSONObject.toJSONString(hashMap) + ")";
return resultStr;
}
@GetMapping(value = "jsonp3")
@ResponseBody
public String bad3(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String jsonStr = getJsonStr(hashMap);
resultStr = jsonpCallback + "(" + jsonStr + ")";
return resultStr;
}
@GetMapping(value = "jsonp4")
@ResponseBody
public String bad4(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String restr = JSONObject.toJSONString(hashMap);
resultStr = jsonpCallback + "(" + restr + ");";
return resultStr;
}
@GetMapping(value = "jsonp5")
@ResponseBody
public void bad5(HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType("application/json");
String jsonpCallback = request.getParameter("jsonpCallback");
PrintWriter pw = null;
Gson gson = new Gson();
String result = gson.toJson(hashMap);
String resultStr = null;
pw = response.getWriter();
resultStr = jsonpCallback + "(" + result + ")";
pw.println(resultStr);
}
@GetMapping(value = "jsonp6")
@ResponseBody
public void bad6(HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType("application/json");
String jsonpCallback = request.getParameter("jsonpCallback");
PrintWriter pw = null;
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(hashMap);
String resultStr = null;
pw = response.getWriter();
resultStr = jsonpCallback + "(" + result + ")";
pw.println(resultStr);
}
@GetMapping(value = "jsonp7")
@ResponseBody
public String good(HttpServletRequest request) {
String resultStr = null;
String jsonpCallback = request.getParameter("jsonpCallback");
String val = "";
Random random = new Random();
for (int i = 0; i < 10; i++) {
val += String.valueOf(random.nextInt(10));
}
// good
jsonpCallback = jsonpCallback + "_" + val;
String jsonStr = getJsonStr(hashMap);
resultStr = jsonpCallback + "(" + jsonStr + ")";
return resultStr;
}
public static String getJsonStr(Object result) {
return JSONObject.toJSONString(result);
}
}

View File

@@ -1,35 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<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,
there is a problem of sensitive information leakage.</p>
</overview>
<recommendation>
<p>The function name verification processing for external input can effectively prevent the leakage of sensitive information.</p>
</recommendation>
<example>
<p>The following example shows the case of no verification processing and verification processing for the external input function name.</p>
<sample src="JsonHijacking.java" />
</example>
<references>
<li>
OWASPLondon20161124_JSON_Hijacking_Gareth_Heyes:
<a href="https://owasp.org/www-chapter-london/assets/slides/OWASPLondon20161124_JSON_Hijacking_Gareth_Heyes.pdf">JSON hijacking</a>.
</li>
<li>
Practical JSONP Injection:
<a href="https://securitycafe.ro/2017/01/18/practical-jsonp-injection">
Completely controllable from the URL (GET variable)
</a>.
</li>
</references>
</qhelp>

View File

@@ -1,32 +0,0 @@
/**
* @name JSON Hijacking
* @description User-controlled callback function names that are not verified are vulnerable
* to json hijacking attacks.
* @kind path-problem
* @problem.severity error
* @precision high
* @id java/Json-hijacking
* @tags security
* external/cwe/cwe-352
*/
import java
import JsonHijackingLib
import semmle.code.java.dataflow.FlowSources
import DataFlow::PathGraph
/** Taint-tracking configuration tracing flow from remote sources to output jsonp data. */
class JsonHijackingConfig extends TaintTracking::Configuration {
JsonHijackingConfig() { this = "JsonHijackingConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof JsonHijackingSink }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, JsonHijackingConfig conf
where
conf.hasFlowPath(source, sink) and
exists(JsonHijackingFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode()))
select sink.getNode(), source, sink, "Json Hijacking query might include code from $@.",
source.getNode(), "this user input"

View File

@@ -1,92 +0,0 @@
import java
import DataFlow
import JsonStringLib
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.frameworks.spring.SpringController
/** A data flow sink for unvalidated user input that is used to jsonp. */
abstract class JsonHijackingSink extends DataFlow::Node { }
/** Use ```print```, ```println```, ```write``` to output result. */
private class WriterPrintln extends JsonHijackingSink {
WriterPrintln() {
exists(MethodAccess ma |
ma.getMethod().getName().regexpMatch("print|println|write") and
ma.getMethod()
.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName("java.io", "PrintWriter") and
ma.getArgument(0) = this.asExpr()
)
}
}
/** Spring Request Method return result. */
private class SpringReturn extends JsonHijackingSink {
SpringReturn() {
exists(ReturnStmt rs, Method m | m = rs.getEnclosingCallable() |
m instanceof SpringRequestMappingMethod and
rs.getResult() = this.asExpr()
)
}
}
/** A concatenate expression using `(` and `)` or `);`. */
class JsonHijackingExpr extends AddExpr {
JsonHijackingExpr() {
getRightOperand().toString().regexpMatch("\"\\)\"|\"\\);\"") and
getLeftOperand()
.(AddExpr)
.getLeftOperand()
.(AddExpr)
.getRightOperand()
.toString()
.regexpMatch("\"\\(\"")
}
/** Get the jsonp function name of this expression */
Expr getFunctionName() {
result = getLeftOperand().(AddExpr).getLeftOperand().(AddExpr).getLeftOperand()
}
/** Get the json data of this expression */
Expr getJsonExpr() { result = getLeftOperand().(AddExpr).getRightOperand() }
}
/** A data flow configuration tracing flow from remote sources to jsonp function name. */
class RemoteFlowConfig extends DataFlow2::Configuration {
RemoteFlowConfig() { this = "RemoteFlowConfig" }
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
exists(JsonHijackingExpr jhe | jhe.getFunctionName() = sink.asExpr())
}
}
/** A data flow configuration tracing flow from json data to splicing jsonp data. */
class JsonDataFlowConfig extends DataFlow2::Configuration {
JsonDataFlowConfig() { this = "JsonDataFlowConfig" }
override predicate isSource(DataFlow::Node src) { src instanceof JsonpStringSource }
override predicate isSink(DataFlow::Node sink) {
exists(JsonHijackingExpr jhe | jhe.getJsonExpr() = sink.asExpr())
}
}
/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */
class JsonHijackingFlowConfig extends TaintTracking::Configuration {
JsonHijackingFlowConfig() { this = "JsonHijackingFlowConfig" }
override predicate isSource(DataFlow::Node src) {
exists(JsonHijackingExpr jhe, JsonDataFlowConfig jdfc, RemoteFlowConfig rfc |
jhe = src.asExpr() and
jdfc.hasFlowTo(DataFlow::exprNode(jhe.getJsonExpr())) and
rfc.hasFlowTo(DataFlow::exprNode(jhe.getFunctionName()))
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof JsonHijackingSink }
}