mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
Fix the problem
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/** Json string type data */
|
||||
abstract class JsonpStringSource extends DataFlow::Node { }
|
||||
|
||||
/** Convert to String using Gson library. */
|
||||
private class GsonString extends JsonpStringSource {
|
||||
GsonString() {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m.hasName("toJson") and
|
||||
m.getDeclaringType().getASupertype*().hasQualifiedName("com.google.gson", "Gson") and
|
||||
this.asExpr() = ma
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert to String using Fastjson library. */
|
||||
private class FastjsonString extends JsonpStringSource {
|
||||
FastjsonString() {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m.hasName("toJSONString") and
|
||||
m.getDeclaringType().getASupertype*().hasQualifiedName("com.alibaba.fastjson", "JSON") and
|
||||
this.asExpr() = ma
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert to String using Jackson library. */
|
||||
private class JacksonString extends JsonpStringSource {
|
||||
JacksonString() {
|
||||
exists(MethodAccess ma, Method m | ma.getMethod() = m |
|
||||
m.hasName("writeValueAsString") and
|
||||
m.getDeclaringType()
|
||||
.getASupertype*()
|
||||
.hasQualifiedName("com.fasterxml.jackson.databind", "ObjectMapper") and
|
||||
this.asExpr() = ma
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
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 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 JsonpController {
|
||||
private static HashMap hashMap = new HashMap();
|
||||
|
||||
static {
|
||||
hashMap.put("username","admin");
|
||||
hashMap.put("password","123456");
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = "jsonp1", produces="text/javascript")
|
||||
@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 {
|
||||
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 {
|
||||
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 good1(HttpServletRequest request) {
|
||||
String resultStr = null;
|
||||
|
||||
String token = request.getParameter("token");
|
||||
|
||||
if (verifToken(token)){
|
||||
String jsonpCallback = request.getParameter("jsonpCallback");
|
||||
String jsonStr = getJsonStr(hashMap);
|
||||
resultStr = jsonpCallback + "(" + jsonStr + ")";
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
public static String getJsonStr(Object result) {
|
||||
return JSONObject.toJSONString(result);
|
||||
}
|
||||
|
||||
public static boolean verifToken(String token){
|
||||
if (token != "xxxx"){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean verifReferer(String referer){
|
||||
if (!referer.startsWith("http://test.com/")){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
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 JsonpInjection {
|
||||
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;
|
||||
}
|
||||
|
||||
@GetMapping(value = "jsonp8")
|
||||
@ResponseBody
|
||||
public String good1(HttpServletRequest request) {
|
||||
String resultStr = null;
|
||||
String jsonpCallback = request.getParameter("jsonpCallback");
|
||||
|
||||
String token = request.getParameter("token");
|
||||
|
||||
// good
|
||||
if (verifToken(token)){
|
||||
System.out.println(token);
|
||||
String jsonStr = getJsonStr(hashMap);
|
||||
resultStr = jsonpCallback + "(" + jsonStr + ")";
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
@GetMapping(value = "jsonp9")
|
||||
@ResponseBody
|
||||
public String good2(HttpServletRequest request) {
|
||||
String resultStr = null;
|
||||
String jsonpCallback = request.getParameter("jsonpCallback");
|
||||
|
||||
String referer = request.getHeader("Referer");
|
||||
|
||||
boolean result = verifReferer(referer);
|
||||
// good
|
||||
if (result){
|
||||
String jsonStr = getJsonStr(hashMap);
|
||||
resultStr = jsonpCallback + "(" + jsonStr + ")";
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
public static String getJsonStr(Object result) {
|
||||
return JSONObject.toJSONString(result);
|
||||
}
|
||||
|
||||
public static boolean verifToken(String token){
|
||||
if (token != "xxxx"){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean verifReferer(String referer){
|
||||
if (!referer.startsWith("http://test.com/")){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<!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>Adding `Referer` or random `token` verification processing 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="JsonpInjection.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>
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @name JSONP Injection
|
||||
* @description User-controlled callback function names that are not verified are vulnerable
|
||||
* to jsonp injection attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id java/JSONP-Injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-352
|
||||
*/
|
||||
|
||||
import java
|
||||
import JsonpInjectionLib
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.deadcode.WebEntryPoints
|
||||
import semmle.code.java.security.XSS
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/** Determine whether there is a verification method for the remote streaming source data flow path method. */
|
||||
predicate existsFilterVerificationMethod() {
|
||||
exists(MethodAccess ma,Node existsNode, Method m|
|
||||
ma.getMethod() instanceof VerificationMethodClass and
|
||||
existsNode.asExpr() = ma and
|
||||
m = getAnMethod(existsNode.getEnclosingCallable()) and
|
||||
isDoFilterMethod(m)
|
||||
)
|
||||
}
|
||||
|
||||
/** Determine whether there is a verification method for the remote streaming source data flow path method. */
|
||||
predicate existsServletVerificationMethod(Node checkNode) {
|
||||
exists(MethodAccess ma,Node existsNode|
|
||||
ma.getMethod() instanceof VerificationMethodClass and
|
||||
existsNode.asExpr() = ma and
|
||||
getAnMethod(existsNode.getEnclosingCallable()) = getAnMethod(checkNode.getEnclosingCallable())
|
||||
)
|
||||
}
|
||||
|
||||
/** Taint-tracking configuration tracing flow from get method request sources to output jsonp data. */
|
||||
class RequestResponseFlowConfig extends TaintTracking::Configuration {
|
||||
RequestResponseFlowConfig() { this = "RequestResponseFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSource and
|
||||
getAnMethod(source.getEnclosingCallable()) instanceof RequestGetMethod
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(MethodAccess ma |
|
||||
isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, RequestResponseFlowConfig conf
|
||||
where
|
||||
not existsServletVerificationMethod(source.getNode()) and
|
||||
not existsFilterVerificationMethod() and
|
||||
conf.hasFlowPath(source, sink) and
|
||||
exists(JsonpInjectionFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode()))
|
||||
select sink.getNode(), source, sink, "Jsonp Injection query might include code from $@.",
|
||||
source.getNode(), "this user input"
|
||||
@@ -0,0 +1,130 @@
|
||||
import java
|
||||
import DataFlow
|
||||
import JsonStringLib
|
||||
import semmle.code.java.security.XSS
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.frameworks.spring.SpringController
|
||||
|
||||
/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */
|
||||
class VerificationMethodFlowConfig extends TaintTracking::Configuration {
|
||||
VerificationMethodFlowConfig() { this = "VerificationMethodFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodAccess ma, BarrierGuard bg |
|
||||
ma.getMethod().getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and
|
||||
bg = ma and
|
||||
sink.asExpr() = ma.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The parameter name of the method is `token`, `auth`, `referer`, `origin`. */
|
||||
class VerificationMethodClass extends Method {
|
||||
VerificationMethodClass() {
|
||||
exists(MethodAccess ma, BarrierGuard bg, VerificationMethodFlowConfig vmfc, Node node |
|
||||
this = ma.getMethod() and
|
||||
this.getAParameter().getName().regexpMatch("(?i).*(token|auth|referer|origin).*") and
|
||||
bg = ma and
|
||||
node.asExpr() = ma.getAnArgument() and
|
||||
vmfc.hasFlowTo(node)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Get Callable by recursive method. */
|
||||
Callable getAnMethod(Callable call) {
|
||||
result = call
|
||||
or
|
||||
result = getAnMethod(call.getAReference().getEnclosingCallable())
|
||||
}
|
||||
|
||||
abstract class RequestGetMethod extends Method { }
|
||||
|
||||
/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */
|
||||
private class ServletGetMethod extends RequestGetMethod {
|
||||
ServletGetMethod() {
|
||||
exists(Method m |
|
||||
m = this and
|
||||
isServletRequestMethod(m) and
|
||||
m.getName() = "doGet"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `m` is a method of some override of `HttpServlet.doGet`. */
|
||||
private class SpringControllerGetMethod extends RequestGetMethod {
|
||||
SpringControllerGetMethod() {
|
||||
exists(Annotation a |
|
||||
a = this.getAnAnnotation() and
|
||||
a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "GetMapping")
|
||||
)
|
||||
or
|
||||
exists(Annotation a |
|
||||
a = this.getAnAnnotation() and
|
||||
a.getType().hasQualifiedName("org.springframework.web.bind.annotation", "RequestMapping") and
|
||||
a.getValue("method").toString().regexpMatch("RequestMethod.GET|\\{...\\}")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A concatenate expression using `(` and `)` or `);`. */
|
||||
class JsonpInjectionExpr extends AddExpr {
|
||||
JsonpInjectionExpr() {
|
||||
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(JsonpInjectionExpr 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(JsonpInjectionExpr jhe | jhe.getJsonExpr() = sink.asExpr())
|
||||
}
|
||||
}
|
||||
|
||||
/** Taint-tracking configuration tracing flow from user-controllable function name jsonp data to output jsonp data. */
|
||||
class JsonpInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
JsonpInjectionFlowConfig() { this = "JsonpInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
exists(JsonpInjectionExpr 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 XssSink }
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JsonpInjectionServlet1 extends HttpServlet {
|
||||
|
||||
private static HashMap hashMap = new HashMap();
|
||||
|
||||
static {
|
||||
hashMap.put("username","admin");
|
||||
hashMap.put("password","123456");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String key = "test";
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
doPost(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
resp.setContentType("application/json");
|
||||
String jsonpCallback = req.getParameter("jsonpCallback");
|
||||
PrintWriter pw = null;
|
||||
Gson gson = new Gson();
|
||||
String jsonResult = gson.toJson(hashMap);
|
||||
|
||||
String referer = req.getHeader("Referer");
|
||||
|
||||
boolean result = verifReferer(referer);
|
||||
|
||||
// good
|
||||
if (result){
|
||||
String resultStr = null;
|
||||
pw = resp.getWriter();
|
||||
resultStr = jsonpCallback + "(" + jsonResult + ")";
|
||||
pw.println(resultStr);
|
||||
pw.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean verifReferer(String referer){
|
||||
if (!referer.startsWith("http://test.com/")){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
this.key = config.getInitParameter("key");
|
||||
System.out.println("初始化" + this.key);
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import com.google.gson.Gson;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class JsonpInjectionServlet2 extends HttpServlet {
|
||||
|
||||
private static HashMap hashMap = new HashMap();
|
||||
|
||||
static {
|
||||
hashMap.put("username","admin");
|
||||
hashMap.put("password","123456");
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String key = "test";
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
doPost(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
resp.setContentType("application/json");
|
||||
String jsonpCallback = req.getParameter("jsonpCallback");
|
||||
PrintWriter pw = null;
|
||||
Gson gson = new Gson();
|
||||
String result = gson.toJson(hashMap);
|
||||
|
||||
String resultStr = null;
|
||||
pw = resp.getWriter();
|
||||
resultStr = jsonpCallback + "(" + result + ")";
|
||||
pw.println(resultStr);
|
||||
pw.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
this.key = config.getInitParameter("key");
|
||||
System.out.println("初始化" + this.key);
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import java.io.IOException;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class RefererFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
String refefer = request.getHeader("Referer");
|
||||
boolean result = verifReferer(refefer);
|
||||
if (result){
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
response.sendError(444, "Referer xxx.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public static boolean verifReferer(String referer){
|
||||
if (StringUtils.isEmpty(referer)){
|
||||
return false;
|
||||
}
|
||||
if (referer.startsWith("http://www.baidu.com/")){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user