Skip to content

Commit bb94a99

Browse files
committed
fixes #31
1 parent 37925a8 commit bb94a99

File tree

5 files changed

+52
-26
lines changed

5 files changed

+52
-26
lines changed

java-sec-code.iml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,6 @@
215215
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
216216
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
217217
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
218+
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.16" level="project" />
218219
</component>
219220
</module>

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

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@
3131
public class FileUpload {
3232

3333
// Save the uploaded file to this folder
34-
private static String UPLOADED_FOLDER = "/tmp/";
34+
private static final String UPLOADED_FOLDER = "/tmp/";
3535
private final Logger logger = LoggerFactory.getLogger(this.getClass());
36+
private static String randomFilePath = "";
3637

37-
@GetMapping("/")
38+
// uplaod any file
39+
@GetMapping("/any")
3840
public String index() {
3941
return "upload"; // return upload.html page
4042
}
4143

44+
// only allow to upload pictures
4245
@GetMapping("/pic")
4346
public String uploadPic() {
4447
return "uploadPic"; // return uploadPic.html page
@@ -64,13 +67,16 @@ public String singleFileUpload(@RequestParam("file") MultipartFile file,
6467

6568
} catch (IOException e) {
6669
redirectAttributes.addFlashAttribute("message", "upload failed");
67-
e.printStackTrace();
68-
return "redirect:/file/status";
70+
logger.error(e.toString());
6971
}
7072

7173
return "redirect:/file/status";
7274
}
7375

76+
@GetMapping("/status")
77+
public String uploadStatus() {
78+
return "uploadStatus";
79+
}
7480

7581
// only upload picture
7682
@PostMapping("/upload/picture")
@@ -83,11 +89,12 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile) throw
8389
String fileName = multifile.getOriginalFilename();
8490
String Suffix = fileName.substring(fileName.lastIndexOf(".")); // 获取文件后缀名
8591
String mimeType = multifile.getContentType(); // 获取MIME类型
92+
String filePath = UPLOADED_FOLDER + fileName;
8693
File excelFile = convert(multifile);
8794

8895

8996
// 判断文件后缀名是否在白名单内 校验1
90-
String picSuffixList[] = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
97+
String[] picSuffixList = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
9198
boolean suffixFlag = false;
9299
for (String white_suffix : picSuffixList) {
93100
if (Suffix.toLowerCase().equals(white_suffix)) {
@@ -97,13 +104,13 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile) throw
97104
}
98105
if (!suffixFlag) {
99106
logger.error("[-] Suffix error: " + Suffix);
100-
deleteFile(excelFile);
107+
deleteFile(filePath);
101108
return "Upload failed. Illeagl picture.";
102109
}
103110

104111

105112
// 判断MIME类型是否在黑名单内 校验2
106-
String mimeTypeBlackList[] = {
113+
String[] mimeTypeBlackList = {
107114
"text/html",
108115
"text/javascript",
109116
"application/javascript",
@@ -115,17 +122,18 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile) throw
115122
// 用contains是为了防止text/html;charset=UTF-8绕过
116123
if (SecurityUtil.replaceSpecialStr(mimeType).toLowerCase().contains(blackMimeType)) {
117124
logger.error("[-] Mime type error: " + mimeType);
118-
deleteFile(excelFile);
125+
deleteFile(filePath);
119126
return "Upload failed. Illeagl picture.";
120127
}
121128
}
122129

123130
// 判断文件内容是否是图片 校验3
124131
boolean isImageFlag = isImage(excelFile);
132+
deleteFile(randomFilePath);
125133

126134
if (!isImageFlag) {
127135
logger.error("[-] File is not Image");
128-
deleteFile(excelFile);
136+
deleteFile(filePath);
129137
return "Upload failed. Illeagl picture.";
130138
}
131139

@@ -137,37 +145,39 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile) throw
137145
Files.write(path, bytes);
138146
} catch (IOException e) {
139147
logger.error(e.toString());
140-
deleteFile(excelFile);
148+
deleteFile(filePath);
141149
return "Upload failed";
142150
}
143151

144-
deleteFile(excelFile);
145152
logger.info("[+] Safe file. Suffix: {}, MIME: {}", Suffix, mimeType);
146-
logger.info("[+] Successfully uploaded {}{}", UPLOADED_FOLDER, multifile.getOriginalFilename());
147-
return "Upload success";
153+
logger.info("[+] Successfully uploaded {}", filePath);
154+
return String.format("You successfully uploaded '%s'", filePath);
148155
}
149156

150-
private void deleteFile(File... files) {
151-
for (File file : files) {
152-
if (file.exists()) {
153-
boolean ret = file.delete();
154-
if (ret) {
155-
logger.debug("File delete successfully!");
156-
}
157+
private void deleteFile(String filePath) {
158+
File delFile = new File(filePath);
159+
if(delFile.isFile() && delFile.exists()) {
160+
if (delFile.delete()) {
161+
logger.info("[+] " + filePath + " delete successfully!");
162+
return;
157163
}
158164
}
165+
logger.info(filePath + " delete failed!");
159166
}
160167

161168
/**
169+
* 为了使用ImageIO.read()
170+
*
162171
* 不建议使用transferTo,因为原始的MultipartFile会被覆盖
163172
* https://stackoverflow.com/questions/24339990/how-to-convert-a-multipart-file-to-file
164173
*/
165174
private File convert(MultipartFile multiFile) throws Exception {
166175
String fileName = multiFile.getOriginalFilename();
167176
String suffix = fileName.substring(fileName.lastIndexOf("."));
168177
UUID uuid = Generators.timeBasedGenerator().generate();
169-
170-
File convFile = new File(UPLOADED_FOLDER + uuid + suffix);
178+
randomFilePath = UPLOADED_FOLDER + uuid + suffix;
179+
// 随机生成一个同后缀名的文件
180+
File convFile = new File(randomFilePath);
171181
boolean ret = convFile.createNewFile();
172182
if (!ret) {
173183
return null;
@@ -183,6 +193,6 @@ private File convert(MultipartFile multiFile) throws Exception {
183193
*/
184194
private static boolean isImage(File file) throws IOException {
185195
BufferedImage bi = ImageIO.read(file);
186-
return bi == null;
196+
return bi != null;
187197
}
188198
}

src/main/resources/application.properties

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ mybatis.mapper-locations=classpath:mapper/*.xml
77
# mybatis SQL log
88
logging.level.org.joychou.mapper=debug
99

10-
# Spring Boot Actuator Vulnerable Config
10+
# Spring Boot Actuator Config
1111
management.security.enabled=false
12+
endpoints.enabled=false
13+
14+
1215
# logging.config=classpath:logback-online.xml
1316

1417
# 业务的callback参数,不支持多个
1518
joychou.business.callback = callback_
1619

20+
1721
### check referer configuration begins ###
1822
joychou.security.referer.enabled = false
1923
joychou.security.referer.host = joychou.org, joychou.com
@@ -38,5 +42,5 @@ joychou.security.jsonp.referer.check.enabled = true
3842
joychou.security.jsonp.callback = callback, _callback
3943
### jsonp configuration ends ###
4044

41-
45+
# swagger
4246
swagger.enable = true

src/main/resources/templates/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<a th:href="@{/swagger-ui.html}">Swagger</a>&nbsp;&nbsp;
1212
<a th:href="@{/codeinject?filepath=/tmp;cat /etc/passwd}">CmdInject</a>&nbsp;&nbsp;
1313
<a th:href="@{/jsonp/getToken?_callback=test}">JSONP</a>&nbsp;&nbsp;
14-
<a th:href="@{/file/pic}">FileUpload</a>&nbsp;&nbsp;
14+
<a th:href="@{/file/pic}">Picture Upload</a>&nbsp;&nbsp;
15+
<a th:href="@{/file/any}">File Upload</a>&nbsp;&nbsp;
1516
<a th:href="@{cors/sec/originFilter}">Cors</a>&nbsp;&nbsp;
1617
<a th:href="@{/path_traversal/vul?filepath=../../../../../etc/passwd}">PathTraversal</a>&nbsp;&nbsp;
1718
<a th:href="@{sqli/mybatis/vuln01?username=joychou' or '1'='1}">SqlInject</a>&nbsp;&nbsp;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en" xmlns:th="http://www.thymeleaf.org">
3+
<body>
4+
5+
<div th:if="${message}">
6+
<h4 th:text="${message}"/>
7+
</div>
8+
9+
</body>
10+
</html>

0 commit comments

Comments
 (0)