mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
*)update
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
@@ -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 }
|
||||
}
|
||||
Reference in New Issue
Block a user