-
Notifications
You must be signed in to change notification settings - Fork 649
/
Jsonp.java
141 lines (121 loc) · 5.01 KB
/
Jsonp.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package org.joychou.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.joychou.util.LoginUtils;
import org.joychou.security.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.joychou.config.WebConfig;
import org.joychou.util.WebUtils;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
/**
* @author JoyChou (joychou@joychou.org) @ 2018.10.24
* https://github.com/JoyChou93/java-sec-code/wiki/JSONP
*/
@Slf4j
@RestController
@RequestMapping("/jsonp")
public class Jsonp {
private String callback = WebConfig.getBusinessCallback();
@Autowired
CookieCsrfTokenRepository cookieCsrfTokenRepository;
/**
* Set the response content-type to application/javascript.
* <p>
* http://localhost:8080/jsonp/vuln/referer?callback_=test
*/
@RequestMapping(value = "/vuln/referer", produces = "application/javascript")
public String referer(HttpServletRequest request) {
String callback = request.getParameter(this.callback);
return WebUtils.json2Jsonp(callback, LoginUtils.getUserInfo2JsonStr(request));
}
/**
* Direct access does not check Referer, non-direct access check referer.
* Developer like to do jsonp testing like this.
* <p>
* http://localhost:8080/jsonp/vuln/emptyReferer?callback_=test
*/
@RequestMapping(value = "/vuln/emptyReferer", produces = "application/javascript")
public String emptyReferer(HttpServletRequest request) {
String referer = request.getHeader("referer");
if (null != referer && SecurityUtil.checkURL(referer) == null) {
return "error";
}
String callback = request.getParameter(this.callback);
return WebUtils.json2Jsonp(callback, LoginUtils.getUserInfo2JsonStr(request));
}
/**
* Adding callback or _callback on parameter can automatically return jsonp data.
* http://localhost:8080/jsonp/object2jsonp?callback=test
* http://localhost:8080/jsonp/object2jsonp?_callback=test
*
* @return Only return object, AbstractJsonpResponseBodyAdvice can be used successfully.
* Such as JSONOjbect or JavaBean. String type cannot be used.
*/
@RequestMapping(value = "/object2jsonp", produces = MediaType.APPLICATION_JSON_VALUE)
public JSONObject advice(HttpServletRequest request) {
return JSON.parseObject(LoginUtils.getUserInfo2JsonStr(request));
}
/**
* http://localhost:8080/jsonp/vuln/mappingJackson2JsonView?callback=test
* Reference: https://p0sec.net/index.php/archives/122/ from p0
* Affected version: java-sec-code test case version: 4.3.6
* - Spring Framework 5.0 to 5.0.6
* - Spring Framework 4.1 to 4.3.17
*/
@RequestMapping(value = "/vuln/mappingJackson2JsonView", produces = MediaType.APPLICATION_JSON_VALUE)
public ModelAndView mappingJackson2JsonView(HttpServletRequest req) {
ModelAndView view = new ModelAndView(new MappingJackson2JsonView());
Principal principal = req.getUserPrincipal();
view.addObject("username", principal.getName());
return view;
}
/**
* Safe code.
* http://localhost:8080/jsonp/sec?callback_=test
*/
@RequestMapping(value = "/sec/checkReferer", produces = "application/javascript")
public String safecode(HttpServletRequest request) {
String referer = request.getHeader("referer");
if (SecurityUtil.checkURL(referer) == null) {
return "error";
}
String callback = request.getParameter(this.callback);
return WebUtils.json2Jsonp(callback, LoginUtils.getUserInfo2JsonStr(request));
}
/**
* http://localhost:8080/jsonp/getToken?fastjsonpCallback=aa
*
* object to jsonp
*/
@GetMapping("/getToken")
public CsrfToken getCsrfToken1(CsrfToken token) {
return token;
}
/**
* http://localhost:8080/jsonp/fastjsonp/getToken?fastjsonpCallback=aa
*
* fastjsonp to jsonp
*/
@GetMapping(value = "/fastjsonp/getToken", produces = "application/javascript")
public String getCsrfToken2(HttpServletRequest request) {
CsrfToken csrfToken = cookieCsrfTokenRepository.loadToken(request); // get csrf token
String callback = request.getParameter("fastjsonpCallback");
if (StringUtils.isNotBlank(callback)) {
JSONPObject jsonpObj = new JSONPObject(callback);
jsonpObj.addParameter(csrfToken);
return jsonpObj.toString();
} else {
return csrfToken.toString();
}
}
}