Skip to content

Commit 9dd930e

Browse files
committed
update some bugs
年前最后一次commit
1 parent 85eb3b9 commit 9dd930e

File tree

10 files changed

+293
-128
lines changed

10 files changed

+293
-128
lines changed

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

+48-9
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,59 @@
1212
@Component
1313
public class WebConfig {
1414

15-
private static Boolean referSecEnabled = false;
1615
private static String[] callbacks;
16+
private static Boolean jsonpReferCheckEnabled = false;
17+
private static String[] jsonpRefererHost;
1718
private static String[] referWhitelist;
1819
private static String[] referUris;
20+
private static Boolean referSecEnabled = false;
21+
private static String businessCallback;
1922

20-
@Value("${joychou.security.referer.enabled}")
21-
public void setReferSecEnabled(Boolean referSecEnabled){
22-
WebConfig.referSecEnabled = referSecEnabled;
23+
/**
24+
* application.properties里object自动转jsonp的referer校验开关
25+
* @param jsonpReferCheckEnabled jsonp校验开关
26+
*/
27+
@Value("${joychou.security.jsonp.referer.check.enabled}")
28+
public void setJsonpReferCheckEnabled(Boolean jsonpReferCheckEnabled){
29+
WebConfig.jsonpReferCheckEnabled = jsonpReferCheckEnabled;
2330
}
24-
public static Boolean getReferSecEnabled(){
25-
return referSecEnabled;
31+
public static Boolean getJsonpReferCheckEnabled(){
32+
return jsonpReferCheckEnabled;
2633
}
2734

2835

2936
@Value("${joychou.security.jsonp.callback}")
30-
public void setCallbacks(String[] callbacks){
37+
public void setJsonpCallbacks(String[] callbacks){
3138
WebConfig.callbacks = callbacks;
3239
}
33-
public static String[] getCallbacks(){
40+
public static String[] getJsonpCallbacks(){
3441
return callbacks;
3542
}
3643

3744

38-
@Value("${joychou.security.referer.hostwhitelist}")
45+
/**
46+
* application.properties里object自动转jsonp的referer白名单域名
47+
* @param jsonpRefererHost 白名单域名,仅支持一级域名
48+
*/
49+
@Value("${joychou.security.jsonp.referer.host}")
50+
public void setJsonpReferWhitelist(String[] jsonpRefererHost){
51+
WebConfig.jsonpRefererHost = jsonpRefererHost;
52+
}
53+
public static String[] getJsonpReferWhitelist(){
54+
return jsonpRefererHost;
55+
}
56+
57+
58+
@Value("${joychou.security.referer.enabled}")
59+
public void setReferSecEnabled(Boolean referSecEnabled){
60+
WebConfig.referSecEnabled = referSecEnabled;
61+
}
62+
public static Boolean getReferSecEnabled(){
63+
return referSecEnabled;
64+
}
65+
66+
67+
@Value("${joychou.security.referer.host}")
3968
public void setReferWhitelist(String[] referWhitelist){
4069
WebConfig.referWhitelist = referWhitelist;
4170
}
@@ -52,4 +81,14 @@ public void setReferUris(String[] referUris)
5281
public static String[] getReferUris(){
5382
return referUris;
5483
}
84+
85+
86+
@Value("${joychou.business.callback}")
87+
public void setBusinessCallback(String businessCallback){
88+
WebConfig.businessCallback = businessCallback;
89+
}
90+
public static String getBusinessCallback(){
91+
return businessCallback;
92+
}
93+
5594
}

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

+30-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.joychou.controller;
22

33
import com.fasterxml.uuid.Generators;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
46
import org.springframework.stereotype.Controller;
57
import org.springframework.web.bind.annotation.GetMapping;
68
import org.springframework.web.bind.annotation.PostMapping;
@@ -23,7 +25,7 @@
2325
/**
2426
* @author JoyChou ([email protected])
2527
* @date 2018.08.15
26-
* @desc Java file upload
28+
* @desc File upload
2729
*/
2830

2931
@Controller
@@ -32,6 +34,7 @@ public class FileUpload {
3234

3335
// Save the uploaded file to this folder
3436
private static String UPLOADED_FOLDER = "/tmp/";
37+
private final Logger logger= LoggerFactory.getLogger(this.getClass());
3538

3639
@GetMapping("/")
3740
public String index() {
@@ -80,22 +83,42 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile,
8083
return "redirect:/file/status";
8184
}
8285

83-
// get suffix
8486
String fileName = multifile.getOriginalFilename();
85-
String Suffix = fileName.substring(fileName.lastIndexOf("."));
86-
87+
String Suffix = fileName.substring(fileName.lastIndexOf(".")); // 获取文件后缀名
88+
String mimeType = multifile.getContentType(); // 获取MIME类型
8789
File excelFile = convert(multifile);
8890

89-
// security check
90-
String picSuffixList[] = {".jpg", ".png", ".jpeg", ".gif", ".bmp"};
91+
// 判断文件后缀名是否在白名单内
92+
String picSuffixList[] = {".jpg", ".png", ".jpeg", ".gif", ".bmp"}; // 后缀名白名单
9193
Boolean suffixFlag = false;
9294
for (String white_suffix : picSuffixList) {
9395
if (Suffix.toLowerCase().equals(white_suffix)) {
9496
suffixFlag = true;
9597
break;
9698
}
9799
}
98-
if ( !suffixFlag || !isImage(excelFile) ) {
100+
101+
if (!suffixFlag) {
102+
logger.error("[-] Suffix error: " + Suffix);
103+
}
104+
105+
String mimeTypeBlackList[] = {"text/html"}; // 不允许传html
106+
107+
Boolean mimeBlackFlag = false;
108+
for (String blackMimeType : mimeTypeBlackList) {
109+
if (mimeType.equalsIgnoreCase(blackMimeType) ) {
110+
mimeBlackFlag = true;
111+
logger.error("[-] Mime type error: " + mimeType);
112+
break;
113+
}
114+
}
115+
116+
boolean isImageFlag = isImage(excelFile);
117+
118+
if( !isImageFlag ){
119+
logger.error("[-] File is not Image");
120+
}
121+
if ( !suffixFlag || mimeBlackFlag || !isImageFlag ) {
99122
redirectAttributes.addFlashAttribute("message", "illeagl picture");
100123
deleteFile(excelFile);
101124
return "redirect:/file/status";

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

+45-58
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package org.joychou.controller;
22

33

4-
import org.springframework.stereotype.Controller;
5-
import org.springframework.web.bind.annotation.RequestMapping;
6-
import org.springframework.web.bind.annotation.ResponseBody;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.web.bind.annotation.*;
77

8-
import javax.servlet.http.HttpServletRequest;
98
import java.net.URI;
109
import java.net.URL;
1110
import java.util.ArrayList;
@@ -20,22 +19,20 @@
2019
* @version 2018.08.23
2120
*/
2221

23-
@Controller
22+
@RestController
2423
@RequestMapping("/url")
2524
public class URLWhiteList {
2625

2726

2827
private String domainwhitelist[] = {"joychou.org", "joychou.com"};
29-
28+
private static final Logger logger = LoggerFactory.getLogger(URLWhiteList.class);
3029
/**
3130
* bypass poc: bypassjoychou.org
32-
* http://localhost:8080/url/endswith?url=http://aaajoychou.org
31+
* http://localhost:8080/url/vuln/endswith?url=http://aaajoychou.org
3332
*
3433
*/
35-
@RequestMapping("/endswith")
36-
@ResponseBody
37-
public String endsWith(HttpServletRequest request) throws Exception{
38-
String url = request.getParameter("url");
34+
@GetMapping("/vuln/endsWith")
35+
public String endsWith(@RequestParam("url") String url) throws Exception{
3936
URL u = new URL(url);
4037
String host = u.getHost().toLowerCase();
4138

@@ -47,15 +44,15 @@ public String endsWith(HttpServletRequest request) throws Exception{
4744
return "Bad url.";
4845
}
4946

47+
5048
/**
5149
* bypass poc: joychou.org.bypass.com or bypassjoychou.org.
52-
* http://localhost:8080/url/contains?url=http://joychou.org.bypass.com http://bypassjoychou.org
50+
* http://localhost:8080/url/vuln/contains?url=http://joychou.org.bypass.com
51+
* http://localhost:8080/url/vuln/contains?url=http://bypassjoychou.org
5352
*
5453
*/
55-
@RequestMapping("/contains")
56-
@ResponseBody
57-
public String contains(HttpServletRequest request) throws Exception{
58-
String url = request.getParameter("url");
54+
@GetMapping("/vuln/contains")
55+
public String contains(@RequestParam("url") String url) throws Exception{
5956
URL u = new URL(url);
6057
String host = u.getHost().toLowerCase();
6158

@@ -70,13 +67,11 @@ public String contains(HttpServletRequest request) throws Exception{
7067

7168
/**
7269
* bypass poc: bypassjoychou.org. It's the same with endsWith.
73-
* http://localhost:8080/url/regex?url=http://aaajoychou.org
70+
* http://localhost:8080/url/vuln/regex?url=http://aaajoychou.org
7471
*
7572
*/
76-
@RequestMapping("/regex")
77-
@ResponseBody
78-
public String regex(HttpServletRequest request) throws Exception{
79-
String url = request.getParameter("url");
73+
@GetMapping("/vuln/regex")
74+
public String regex(@RequestParam("url") String url) throws Exception{
8075
URL u = new URL(url);
8176
String host = u.getHost().toLowerCase();
8277

@@ -92,15 +87,14 @@ public String regex(HttpServletRequest request) throws Exception{
9287

9388
/**
9489
* bypass poc: joychou.org.bypass.com or bypassjoychou.org. It's the same with contains.
95-
* http://localhost:8080/url/indexof?url=http://joychou.org.bypass.com http://bypassjoychou.org
90+
* http://localhost:8080/url/vuln/indexOf?url=http://joychou.org.bypass.com http://bypassjoychou.org
9691
*
9792
*/
98-
@RequestMapping("/indexof")
99-
@ResponseBody
100-
public String indexOf(HttpServletRequest request) throws Exception{
101-
String url = request.getParameter("url");
93+
@GetMapping("/vuln/indexOf")
94+
public String indexOf(@RequestParam("url") String url) throws Exception{
10295
URL u = new URL(url);
10396
String host = u.getHost();
97+
10498
// If indexOf returns -1, it means that no string was found.
10599
for (String domain: domainwhitelist){
106100
if (host.indexOf(domain) != -1) {
@@ -113,24 +107,22 @@ public String indexOf(HttpServletRequest request) throws Exception{
113107
/**
114108
* The bypass of using java.net.URL to getHost.
115109
*
116-
* Bypass poc1: curl -v 'http://localhost:8080/url/url_bypass?url=http://evel.com%[email protected]/a.html'
117-
* Bypass poc2: curl -v 'http://localhost:8080/url/url_bypass?url=http://evil.com%5cwww.joychou.org/a.html'
110+
* Bypass poc1: curl -v 'http://localhost:8080/url/vuln/url_bypass?url=http://evel.com%[email protected]/a.html'
111+
* Bypass poc2: curl -v 'http://localhost:8080/url/vuln/url_bypass?url=http://evil.com%5cwww.joychou.org/a.html'
118112
*
119113
* Detail: https://github.com/JoyChou93/java-sec-code/wiki/URL-whtielist-Bypass
120114
*/
121-
@RequestMapping("/url_bypass")
122-
@ResponseBody
123-
public String url_bypass(HttpServletRequest request) throws Exception{
124-
String url = request.getParameter("url");
125-
System.out.println("url: " + url);
115+
@GetMapping("/vuln/url_bypass")
116+
public String url_bypass(@RequestParam("url") String url) throws Exception{
117+
logger.info("url: " + url);
126118
URL u = new URL(url);
127119

128120
if (!u.getProtocol().startsWith("http") && !u.getProtocol().startsWith("https")) {
129121
return "Url is not http or https";
130122
}
131123

132124
String host = u.getHost().toLowerCase();
133-
System.out.println("host: " + host);
125+
logger.info("host: " + host);
134126

135127
// endsWith .
136128
for (String domain: domainwhitelist){
@@ -145,18 +137,16 @@ public String url_bypass(HttpServletRequest request) throws Exception{
145137

146138

147139
/**
148-
* First-level host whitelist.
149-
* http://localhost:8080/url/seccode1?url=http://aa.taobao.com
140+
* 一级域名白名单 First-level host whitelist.
141+
* http://localhost:8080/url/sec/endswith?url=http://aa.joychou.org
150142
*
151143
*/
152-
@RequestMapping("/seccode1")
153-
@ResponseBody
154-
public String seccode1(HttpServletRequest request) throws Exception{
144+
@GetMapping("/sec/endswith")
145+
public String sec_endswith(@RequestParam("url") String url) throws Exception{
155146

156-
String whiteDomainlists[] = {"taobao.com", "tmall.com"};
157-
String url = request.getParameter("url");
147+
String whiteDomainlists[] = {"joychou.org", "joychou.com"};
158148

159-
URI uri = new URI(url);
149+
URI uri = new URI(url); // 必须用URI
160150
if (!url.startsWith("http://") && !url.startsWith("https://")) {
161151
return "SecurityUtil is not http or https";
162152
}
@@ -174,15 +164,13 @@ public String seccode1(HttpServletRequest request) throws Exception{
174164
}
175165

176166
/**
177-
* Muti-level host whitelist.
178-
* http://localhost:8080/url/seccode2?url=http://ccc.bbb.taobao.com
167+
* 多级域名白名单 Multi-level host whitelist.
168+
* http://localhost:8080/url/sec/multi_level_hos?url=http://ccc.bbb.joychou.org
179169
*
180170
*/
181-
@RequestMapping("/seccode2")
182-
@ResponseBody
183-
public String seccode2(HttpServletRequest request) throws Exception{
184-
String whiteDomainlists[] = {"aaa.taobao.com", "ccc.bbb.taobao.com"};
185-
String url = request.getParameter("url");
171+
@GetMapping("/sec/multi_level_host")
172+
public String sec_multi_level_host(@RequestParam("url") String url) throws Exception{
173+
String whiteDomainlists[] = {"aaa.joychou.org", "ccc.bbb.joychou.org"};
186174

187175
URI uri = new URI(url);
188176
if (!url.startsWith("http://") && !url.startsWith("https://")) {
@@ -199,21 +187,20 @@ public String seccode2(HttpServletRequest request) throws Exception{
199187
return "Bad url.";
200188
}
201189

190+
202191
/**
203-
* Muti-level host whitelist.
204-
* http://localhost:8080/url/seccode3?url=http://ccc.bbb.taobao.com
192+
* 多级域名白名单 Multi-level host whitelist.
193+
* http://localhost:8080/url/sec/array_indexOf?url=http://ccc.bbb.joychou.org
205194
*
206195
*/
207-
@RequestMapping("/seccode3")
208-
@ResponseBody
209-
public String seccode3(HttpServletRequest request) throws Exception{
196+
@GetMapping("/sec/array_indexOf")
197+
public String sec_array_indexOf(@RequestParam("url") String url) throws Exception{
210198

211199
// Define muti-level host whitelist.
212-
ArrayList<String> whiteDomainlists = new ArrayList<String>();
213-
whiteDomainlists.add("bbb.taobao.com");
214-
whiteDomainlists.add("ccc.bbb.taobao.com");
200+
ArrayList<String> whiteDomainlists = new ArrayList<>();
201+
whiteDomainlists.add("bbb.joychou.org");
202+
whiteDomainlists.add("ccc.bbb.joychou.org");
215203

216-
String url = request.getParameter("url");
217204
URI uri = new URI(url);
218205

219206
if (!url.startsWith("http://") && !url.startsWith("https://")) {

0 commit comments

Comments
 (0)