Skip to content

Commit 0d99385

Browse files
committed
update mybatis sql injection
1 parent 7b187f2 commit 0d99385

File tree

13 files changed

+173
-101
lines changed

13 files changed

+173
-101
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<groupId>sec</groupId>
88
<artifactId>java-sec-code</artifactId>
99
<version>1.0.0</version>
10-
<packaging>jar</packaging>
10+
<packaging>war</packaging>
1111

1212
<properties>
1313
<maven.compiler.source>1.8</maven.compiler.source> <!-- mvn clean package-->

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

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
66
import org.springframework.stereotype.Controller;
7-
import org.springframework.web.bind.annotation.GetMapping;
8-
import org.springframework.web.bind.annotation.PostMapping;
9-
import org.springframework.web.bind.annotation.RequestMapping;
10-
import org.springframework.web.bind.annotation.RequestParam;
7+
import org.springframework.web.bind.annotation.*;
118
import org.springframework.web.multipart.MultipartFile;
129
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
1310

@@ -21,6 +18,8 @@
2118
import java.nio.file.Paths;
2219
import java.util.UUID;
2320

21+
import org.joychou.security.SecurityUtil;
22+
2423

2524
/**
2625
* @author JoyChou ([email protected])
@@ -35,6 +34,7 @@ public class FileUpload {
3534
// Save the uploaded file to this folder
3635
private static String UPLOADED_FOLDER = "/tmp/";
3736
private final Logger logger= LoggerFactory.getLogger(this.getClass());
37+
private final String mimeChars = "/abcdefghijklmnopqrstuvwxyz-.0123456789";
3838

3939
@GetMapping("/")
4040
public String index() {
@@ -73,55 +73,62 @@ public String singleFileUpload(@RequestParam("file") MultipartFile file,
7373
return "redirect:/file/status";
7474
}
7575

76+
7677
// only upload picture
7778
@PostMapping("/upload/picture")
78-
public String uploadPicture(@RequestParam("file") MultipartFile multifile,
79-
RedirectAttributes redirectAttributes) throws Exception{
79+
@ResponseBody
80+
public String uploadPicture(@RequestParam("file") MultipartFile multifile) throws Exception{
8081
if (multifile.isEmpty()) {
81-
// 赋值给uploadStatus.html里的动态参数message
82-
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
83-
return "redirect:/file/status";
82+
return "Please select a file to upload";
8483
}
8584

8685
String fileName = multifile.getOriginalFilename();
8786
String Suffix = fileName.substring(fileName.lastIndexOf(".")); // 获取文件后缀名
8887
String mimeType = multifile.getContentType(); // 获取MIME类型
8988
File excelFile = convert(multifile);
9089

91-
// 判断文件后缀名是否在白名单内
92-
String picSuffixList[] = {".jpg", ".png", ".jpeg", ".gif", ".bmp"}; // 后缀名白名单
93-
Boolean suffixFlag = false;
90+
91+
// 判断文件后缀名是否在白名单内 校验1
92+
String picSuffixList[] = {".jpg", ".png", ".jpeg", ".gif", ".bmp", ".ico"};
93+
boolean suffixFlag = false;
9494
for (String white_suffix : picSuffixList) {
9595
if (Suffix.toLowerCase().equals(white_suffix)) {
9696
suffixFlag = true;
9797
break;
9898
}
9999
}
100-
101100
if (!suffixFlag) {
102101
logger.error("[-] Suffix error: " + Suffix);
102+
deleteFile(excelFile);
103+
return "Upload failed. Illeagl picture.";
103104
}
104105

105-
String mimeTypeBlackList[] = {"text/html"}; // 不允许传html
106106

107-
Boolean mimeBlackFlag = false;
107+
// 判断MIME类型是否在黑名单内 校验2
108+
String mimeTypeBlackList[] = {
109+
"text/html",
110+
"text/javascript",
111+
"application/javascript",
112+
"application/ecmascript",
113+
"text/xml",
114+
"application/xml"
115+
};
108116
for (String blackMimeType : mimeTypeBlackList) {
109-
if (mimeType.equalsIgnoreCase(blackMimeType) ) {
110-
mimeBlackFlag = true;
117+
// 用contains是为了防止text/html;charset=UTF-8绕过
118+
if (SecurityUtil.replaceSpecialStr(mimeType).toLowerCase().contains(blackMimeType) ) {
111119
logger.error("[-] Mime type error: " + mimeType);
112-
break;
120+
deleteFile(excelFile);
121+
return "Upload failed. Illeagl picture.";
113122
}
114123
}
115124

125+
// 判断文件内容是否是图片 校验3
116126
boolean isImageFlag = isImage(excelFile);
117127

118-
if( !isImageFlag ){
128+
if( !isImage(excelFile) ){
119129
logger.error("[-] File is not Image");
120-
}
121-
if ( !suffixFlag || mimeBlackFlag || !isImageFlag ) {
122-
redirectAttributes.addFlashAttribute("message", "illeagl picture");
123130
deleteFile(excelFile);
124-
return "redirect:/file/status";
131+
return "Upload failed. Illeagl picture.";
125132
}
126133

127134

@@ -130,24 +137,16 @@ public String uploadPicture(@RequestParam("file") MultipartFile multifile,
130137
byte[] bytes = multifile.getBytes();
131138
Path path = Paths.get(UPLOADED_FOLDER + multifile.getOriginalFilename());
132139
Files.write(path, bytes);
133-
134-
redirectAttributes.addFlashAttribute("message",
135-
"You successfully uploaded '" + UPLOADED_FOLDER + multifile.getOriginalFilename() + "'");
136-
137140
} catch (IOException e) {
138-
redirectAttributes.addFlashAttribute("message", "upload failed");
139-
e.printStackTrace();
141+
logger.error(e.toString());
140142
deleteFile(excelFile);
141-
return "redirect:/file/status";
143+
return "Upload failed";
142144
}
143145

144146
deleteFile(excelFile);
145-
return "redirect:/file/status";
146-
}
147-
148-
@GetMapping("/status")
149-
public String uploadStatus() {
150-
return "uploadStatus";
147+
logger.info("[+] Safe file. Suffix: {}, MIME: {}", Suffix, mimeType);
148+
logger.info("[+] Successfully uploaded {}{}", UPLOADED_FOLDER, multifile.getOriginalFilename());
149+
return "Upload success";
151150
}
152151

153152
private void deleteFile(File... files) {

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

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
import org.joychou.mapper.UserMapper;
55
import org.joychou.dao.User;
6+
import org.joychou.security.SecurityUtil;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
69
import org.springframework.beans.factory.annotation.Autowired;
710
import org.springframework.beans.factory.annotation.Value;
811
import org.springframework.web.bind.annotation.*;
@@ -12,21 +15,24 @@
1215

1316

1417
/**
15-
* @author JoyChou ([email protected])
16-
* @date 2018.08.22
17-
* @desc SQL Injection
18+
* SQL Injection
19+
* @author JoyChou @2018.08.22
1820
*/
1921

2022
@SuppressWarnings("Duplicates")
2123
@RestController
2224
@RequestMapping("/sqli")
2325
public class SQLI {
2426

27+
private static Logger logger = LoggerFactory.getLogger(SQLI.class);
2528
private static String driver = "com.mysql.jdbc.Driver";
29+
2630
@Value("${spring.datasource.url}")
2731
private String url;
32+
2833
@Value("${spring.datasource.username}")
2934
private String user;
35+
3036
@Value("${spring.datasource.password}")
3137
private String password;
3238

@@ -35,12 +41,12 @@ public class SQLI {
3541

3642

3743
/**
38-
* Vul Code.
44+
* Vuln Code.
3945
* http://localhost:8080/sqli/jdbc/vul?username=joychou
4046
*
4147
* @param username username
4248
*/
43-
@RequestMapping("/jdbc/vul")
49+
@RequestMapping("/jdbc/vuln")
4450
public String jdbc_sqli_vul(@RequestParam("username") String username){
4551
String result = "";
4652
try {
@@ -50,37 +56,28 @@ public String jdbc_sqli_vul(@RequestParam("username") String username){
5056
if(!con.isClosed())
5157
System.out.println("Connecting to Database successfully.");
5258

53-
// sqli vuln code 漏洞代码
59+
// sqli vuln code
5460
Statement statement = con.createStatement();
5561
String sql = "select * from users where username = '" + username + "'";
56-
System.out.println(sql);
62+
logger.info(sql);
5763
ResultSet rs = statement.executeQuery(sql);
5864

59-
60-
System.out.println("-----------------");
61-
6265
while(rs.next()){
6366
String res_name = rs.getString("username");
6467
String res_pwd = rs.getString("password");
6568
result += res_name + ": " + res_pwd + "\n";
66-
System.out.println(res_name + ": " + res_pwd);
67-
69+
logger.info(res_name + ": " + res_pwd);
6870
}
6971
rs.close();
7072
con.close();
7173

7274

7375
}catch (ClassNotFoundException e) {
74-
System.out.println("Sorry,can`t find the Driver!");
75-
e.printStackTrace();
76+
logger.error("Sorry,can`t find the Driver!");
7677
}catch (SQLException e) {
77-
e.printStackTrace();
78+
logger.error(e.toString());
7879
}catch (Exception e) {
79-
e.printStackTrace();
80-
81-
}finally{
82-
System.out.println("-----------------");
83-
System.out.println("Connect database done.");
80+
logger.error(e.toString());
8481
}
8582
return result;
8683
}
@@ -103,62 +100,60 @@ public String jdbc_sqli_sec(@RequestParam("username") String username){
103100
if(!con.isClosed())
104101
System.out.println("Connecting to Database successfully.");
105102

106-
107103
// fix code
108104
String sql = "select * from users where username = ?";
109105
PreparedStatement st = con.prepareStatement(sql);
110106
st.setString(1, username);
111-
System.out.println(st.toString()); // sql after prepare statement
107+
logger.info(st.toString()); // sql after prepare statement
112108
ResultSet rs = st.executeQuery();
113109

114-
System.out.println("-----------------");
115-
116110
while(rs.next()){
117111
String res_name = rs.getString("username");
118112
String res_pwd = rs.getString("password");
119113
result += res_name + ": " + res_pwd + "\n";
120-
System.out.println(res_name + ": " + res_pwd);
121-
114+
logger.info(res_name + ": " + res_pwd);
122115
}
116+
123117
rs.close();
124118
con.close();
125119

126-
127120
}catch (ClassNotFoundException e) {
128-
System.out.println("Sorry,can`t find the Driver!");
121+
logger.error("Sorry,can`t find the Driver!");
129122
e.printStackTrace();
130123
}catch (SQLException e) {
131-
e.printStackTrace();
124+
logger.error(e.toString());
132125
}catch (Exception e) {
133-
e.printStackTrace();
134-
135-
}finally{
136-
System.out.println("-----------------");
137-
System.out.println("Connect database done.");
126+
logger.error(e.toString());
138127
}
139128
return result;
140129
}
141130

142131
/**
143-
* vul code
144-
* http://localhost:8080/sqli/mybatis/vul01?username=joychou' or '1'='1
132+
* vuln code
133+
* http://localhost:8080/sqli/mybatis/vuln01?username=joychou' or '1'='1
145134
*
146135
* @param username username
147136
*/
148-
@GetMapping("/mybatis/vul01")
149-
public List<User> mybatis_vul1(@RequestParam("username") String username) {
150-
return userMapper.findByUserNameVul(username);
137+
@GetMapping("/mybatis/vuln01")
138+
public List<User> mybatisVuln01(@RequestParam("username") String username) {
139+
return userMapper.findByUserNameVuln01(username);
151140
}
152141

153142
/**
154143
* vul code
155-
* http://localhost:8080/sqli/mybatis/vul02?username=joychou' or '1'='1' %23
144+
* http://localhost:8080/sqli/mybatis/vuln02?username=joychou' or '1'='1' %23
156145
*
157146
* @param username username
158147
*/
159-
@GetMapping("/mybatis/vul02")
160-
public List<User> mybatis_vul2(@RequestParam("username") String username) {
161-
return userMapper.findByUserNameVul2(username);
148+
@GetMapping("/mybatis/vuln02")
149+
public List<User> mybatisVuln02(@RequestParam("username") String username) {
150+
return userMapper.findByUserNameVuln02(username);
151+
}
152+
153+
// http://localhost:8080/sqli/mybatis/orderby/vuln03?sort=1 desc%23
154+
@GetMapping("/mybatis/orderby/vuln03")
155+
public List<User> mybatisVuln03(@RequestParam("sort") String sort) {
156+
return userMapper.findByUserNameVuln03(sort);
162157
}
163158

164159

@@ -169,7 +164,7 @@ public List<User> mybatis_vul2(@RequestParam("username") String username) {
169164
* @param username username
170165
*/
171166
@GetMapping("/mybatis/sec01")
172-
public User mybatis_sec1(@RequestParam("username") String username) {
167+
public User mybatisSec01(@RequestParam("username") String username) {
173168
return userMapper.findByUserName(username);
174169
}
175170

@@ -180,7 +175,7 @@ public User mybatis_sec1(@RequestParam("username") String username) {
180175
* @param id id
181176
*/
182177
@GetMapping("/mybatis/sec02")
183-
public User mybatis_sec2(@RequestParam("id") Integer id) {
178+
public User mybatisSec02(@RequestParam("id") Integer id) {
184179
return userMapper.findById(id);
185180
}
186181

@@ -190,9 +185,14 @@ public User mybatis_sec2(@RequestParam("id") Integer id) {
190185
* http://localhost:8080/sqli/mybatis/sec03
191186
**/
192187
@GetMapping("/mybatis/sec03")
193-
public User mybatis_sec3() {
188+
public User mybatisSec03() {
194189
return userMapper.OrderByUsername();
195190
}
196191

197192

193+
@GetMapping("/mybatis/orderby/sec04")
194+
public List<User> mybatisOrderBySec04(@RequestParam("sort") String sort) {
195+
return userMapper.findByUserNameVuln03(SecurityUtil.sqlFilter(sort));
196+
}
197+
198198
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,10 @@ public static String ssrf_HttpClient(@RequestParam String url) {
195195

196196

197197
/**
198-
* Safe code.
199-
* http://localhost:8080/ssrf/commonsHttpClient/sec?url=http://www.baidu.com
198+
* https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient
199+
* UserAgent: Jakarta Commons-HttpClient/3.1 (2007.08 publish)
200200
*
201+
* http://localhost:8080/ssrf/commonsHttpClient/sec?url=http://www.baidu.com
201202
*/
202203
@RequestMapping("/commonsHttpClient/sec")
203204
@ResponseBody

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,5 @@ public String sec_array_indexOf(@RequestParam("url") String url) throws Exceptio
212212
}
213213
return "Bad url.";
214214
}
215+
215216
}

src/main/java/org/joychou/dao/User.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ public void setId(Integer id) {
1515
this.id = id;
1616
}
1717

18-
1918
public String getUsername() {
2019
return username;
2120
}
2221
public void setUsername(String username) {
2322
this.username = username;
2423
}
2524

26-
2725
public String getPassword() {
2826
return password;
2927
}

0 commit comments

Comments
 (0)