Skip to content

Commit db6bff2

Browse files
committed
Bug fix.The method of fix ssrf can cause dos.
1 parent 0d99385 commit db6bff2

File tree

5 files changed

+47
-56
lines changed

5 files changed

+47
-56
lines changed

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

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@
2323

2424

2525
import javax.imageio.ImageIO;
26-
import javax.servlet.http.HttpServletRequest;
2726
import javax.servlet.http.HttpServletResponse;
2827
import java.io.*;
2928
import java.net.*;
3029

3130

3231
/**
33-
* @author JoyChou ([email protected])
34-
* @date 2017.12.28
35-
* @desc Java ssrf vuls code.
32+
* Java SSRF vuln or security code.
33+
*
34+
* @author JoyChou @2017-12-28
3635
*/
3736

3837
@RestController
@@ -42,62 +41,59 @@ public class SSRF {
4241
private static Logger logger = LoggerFactory.getLogger(SSRF.class);
4342

4443
@RequestMapping("/urlConnection")
45-
public static String ssrf_URLConnection(HttpServletRequest request)
44+
public static String ssrf_URLConnection(@RequestParam String url)
4645
{
4746
try {
48-
String url = request.getParameter("url");
4947
URL u = new URL(url);
5048
URLConnection urlConnection = u.openConnection();
5149
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //send request
5250
String inputLine;
53-
StringBuffer html = new StringBuffer();
51+
StringBuilder html = new StringBuilder();
5452

5553
while ((inputLine = in.readLine()) != null) {
5654
html.append(inputLine);
5755
}
5856
in.close();
5957
return html.toString();
6058
}catch(Exception e) {
61-
e.printStackTrace();
59+
logger.error(e.toString());
6260
return "fail";
6361
}
6462
}
6563

6664

6765
@RequestMapping("/HttpURLConnection")
6866
@ResponseBody
69-
public static String ssrf_httpURLConnection(HttpServletRequest request)
67+
public static String ssrf_httpURLConnection(@RequestParam String url)
7068
{
7169
try {
72-
String url = request.getParameter("url");
7370
URL u = new URL(url);
7471
URLConnection urlConnection = u.openConnection();
7572
HttpURLConnection httpUrl = (HttpURLConnection)urlConnection;
7673
BufferedReader in = new BufferedReader(new InputStreamReader(httpUrl.getInputStream())); //send request
7774
String inputLine;
78-
StringBuffer html = new StringBuffer();
75+
StringBuilder html = new StringBuilder();
7976

8077
while ((inputLine = in.readLine()) != null) {
8178
html.append(inputLine);
8279
}
8380
in.close();
8481
return html.toString();
8582
}catch(Exception e) {
86-
e.printStackTrace();
83+
logger.error(e.toString());
8784
return "fail";
8885
}
8986
}
9087

9188

9289
@RequestMapping("/Request")
9390
@ResponseBody
94-
public static String ssrf_Request(HttpServletRequest request)
91+
public static String ssrf_Request(@RequestParam String url)
9592
{
9693
try {
97-
String url = request.getParameter("url");
9894
return Request.Get(url).execute().returnContent().toString();
9995
}catch(Exception e) {
100-
e.printStackTrace();
96+
logger.error(e.toString());
10197
return "fail";
10298
}
10399
}
@@ -113,10 +109,9 @@ public static String ssrf_Request(HttpServletRequest request)
113109
*/
114110
@RequestMapping("/openStream")
115111
@ResponseBody
116-
public static void ssrf_openStream (HttpServletRequest request, HttpServletResponse response) throws IOException {
112+
public static void ssrf_openStream (@RequestParam String url, HttpServletResponse response) throws IOException {
117113
InputStream inputStream = null;
118114
OutputStream outputStream = null;
119-
String url = request.getParameter("url");
120115
try {
121116
String downLoadImgFileName = Files.getNameWithoutExtension(url) + "." + Files.getFileExtension(url);
122117
// download
@@ -132,7 +127,7 @@ public static void ssrf_openStream (HttpServletRequest request, HttpServletRespo
132127
}
133128

134129
}catch (Exception e) {
135-
e.printStackTrace();
130+
logger.error(e.toString());
136131
}finally {
137132
if (inputStream != null) {
138133
inputStream.close();
@@ -147,20 +142,19 @@ public static void ssrf_openStream (HttpServletRequest request, HttpServletRespo
147142

148143
@RequestMapping("/ImageIO")
149144
@ResponseBody
150-
public static void ssrf_ImageIO(HttpServletRequest request) {
151-
String url = request.getParameter("url");
145+
public static void ssrf_ImageIO(@RequestParam String url) {
152146
try {
153147
URL u = new URL(url);
154148
ImageIO.read(u); // send request
155149
} catch (Exception e) {
150+
logger.error(e.toString());
156151
}
157152
}
158153

159154

160155
@RequestMapping("/okhttp")
161156
@ResponseBody
162-
public static void ssrf_okhttp(HttpServletRequest request) throws IOException {
163-
String url = request.getParameter("url");
157+
public static void ssrf_okhttp(@RequestParam String url) throws IOException {
164158
OkHttpClient client = new OkHttpClient();
165159
com.squareup.okhttp.Request ok_http = new com.squareup.okhttp.Request.Builder().url(url).build();
166160
client.newCall(ok_http).execute();
@@ -180,8 +174,8 @@ public static String ssrf_HttpClient(@RequestParam String url) {
180174
try {
181175
HttpResponse httpResponse = client.execute(httpGet); // send request
182176
BufferedReader rd = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
183-
StringBuffer result = new StringBuffer();
184-
String line = "";
177+
StringBuilder result = new StringBuilder();
178+
String line = null;
185179
while ((line = rd.readLine()) != null) {
186180
result.append(line);
187181
}
@@ -236,8 +230,8 @@ public static String commonsHttpClient(@RequestParam String url) {
236230

237231
/**
238232
* jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。
239-
* http://localhost:8080/ssrf/Jsoup?url=http://www.baidu.com
240233
*
234+
* http://localhost:8080/ssrf/Jsoup?url=http://www.baidu.com
241235
*/
242236
@RequestMapping("/Jsoup")
243237
@ResponseBody
@@ -251,9 +245,11 @@ public static String Jsoup(@RequestParam String url) {
251245
.cookie("name", "joychou") // request请求带的cookie
252246
.followRedirects(false)
253247
.execute().parse();
248+
logger.info(doc.html());
254249
} catch (MalformedURLException e) {
255250
return "exception: " + e.toString();
256-
} catch (Exception e) {
251+
} catch (IOException e) {
252+
logger.error(e.toString());
257253
return "exception: " + e.toString();
258254
}
259255

@@ -271,7 +267,7 @@ public static String Jsoup(@RequestParam String url) {
271267
public static String IOUtils(@RequestParam String url) {
272268
try {
273269
// IOUtils.toByteArray内部用URLConnection进行了封装
274-
byte[] b = IOUtils.toByteArray(URI.create(url));
270+
IOUtils.toByteArray(URI.create(url));
275271
} catch (Exception e) {
276272
return "exception: " + e.toString();
277273
}

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
11
package org.joychou.controller;
22

33
import org.apache.commons.lang.StringUtils;
4-
import org.joychou.dao.User;
5-
import org.joychou.mapper.UserMapper;
6-
import org.springframework.beans.factory.annotation.Autowired;
7-
import org.springframework.beans.factory.annotation.Value;
84
import org.springframework.stereotype.Controller;
95
import org.springframework.web.bind.annotation.CookieValue;
106
import org.springframework.web.bind.annotation.RequestMapping;
117
import org.springframework.web.bind.annotation.ResponseBody;
128

13-
import javax.annotation.Resource;
149
import javax.servlet.http.Cookie;
15-
import javax.servlet.http.HttpServletRequest;
1610
import javax.servlet.http.HttpServletResponse;
17-
import java.sql.Connection;
18-
import java.sql.DriverManager;
19-
import java.sql.Statement;
11+
2012

2113
/**
22-
* @author JoyChou ([email protected])
23-
* @date 2018.01.02
24-
* @desc XSS vuls code
14+
* @author JoyChou @2018-01-02
2515
*/
26-
2716
@Controller
2817
@RequestMapping("/xss")
2918
public class XSS {
3019

3120
/**
32-
* Vul Code.
21+
* Vuln Code.
3322
* ReflectXSS
3423
* http://localhost:8080/xss/reflect?xss=<script>alert(1)</script>
3524
*
@@ -71,6 +60,7 @@ public String show(@CookieValue("xss") String xss)
7160
{
7261
return xss;
7362
}
63+
7464
/**
7565
* safe Code.
7666
* http://localhost:8080/xss/safe
@@ -82,7 +72,7 @@ public static String safe(String xss){
8272
return encode(xss);
8373
}
8474

85-
public static String encode(String origin) {
75+
private static String encode(String origin) {
8676
origin = StringUtils.replace(origin, "&", "&amp;");
8777
origin = StringUtils.replace(origin, "<", "&lt;");
8878
origin = StringUtils.replace(origin, ">", "&gt;");

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,24 @@
88
import org.slf4j.Logger;
99
import org.slf4j.LoggerFactory;
1010

11-
public class SSRFChecker {
11+
class SSRFChecker {
1212

13-
private static int connectTime = 5*1000; // 设置连接超时时间5s
1413
private static Logger logger = LoggerFactory.getLogger(SSRFChecker.class);
14+
1515
/**
1616
* 解析url的ip,判断ip是否是内网ip,所以TTL设置为0的情况不适用。
1717
* url只允许https或者http,并且设置默认连接超时时间。
1818
* 该修复方案会主动请求重定向后的链接。最好用Hook方式获取到所有url后,进行判断,代码待续…
1919
*
2020
* @param url check的url
21+
* @param checkTimes 设置重定向检测的最大次数,建议设置为10次
2122
* @return 安全返回true,危险返回false
2223
*/
23-
public static Boolean checkSSRF(String url) {
24+
static Boolean checkSSRF(String url, int checkTimes) {
2425

2526
HttpURLConnection connection;
27+
int connectTime = 5*1000; // 设置连接超时时间5s
28+
int i = 1;
2629
String finalUrl = url;
2730
try {
2831
do {
@@ -45,7 +48,11 @@ public static Boolean checkSSRF(String url) {
4548
if (null == redirectedUrl)
4649
break;
4750
finalUrl = redirectedUrl;
48-
// System.out.println("redirected url: " + finalUrl);
51+
i += 1; // 重定向次数加1
52+
logger.info("redirected url: " + finalUrl);
53+
if(i == checkTimes) {
54+
return false;
55+
}
4956
} else
5057
break;
5158
} while (connection.getResponseCode() != HttpURLConnection.HTTP_OK);
@@ -62,7 +69,7 @@ public static Boolean checkSSRF(String url) {
6269
*
6370
* @return 如果是内网IP,返回true;非内网IP,返回false。
6471
*/
65-
public static Boolean isInnerIPByUrl(String url) {
72+
static Boolean isInnerIPByUrl(String url) {
6673
String host = url2host(url);
6774
if (host.equals("")) {
6875
return true; // 异常URL当成内网IP等非法URL处理

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,8 @@ public static String checkUrlByGuava(String url, String[] urlwhitelist){
9191
* @return 安全返回true,危险返回false
9292
*/
9393
public static Boolean checkSSRF(String url) {
94-
if (SSRFChecker.checkSSRF(url)) {
95-
return true;
96-
} else {
97-
return false;
98-
}
94+
int checkTimes = 10;
95+
return SSRFChecker.checkSSRF(url, checkTimes);
9996
}
10097

10198

@@ -143,7 +140,7 @@ public static String pathFilter(String filepath) {
143140
}
144141
}
145142

146-
if (temp.indexOf("..") != -1 || temp.charAt(0) == '/') {
143+
if (temp.contains("..") || temp.charAt(0) == '/') {
147144
return null;
148145
}
149146

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
4343
public boolean matches(HttpServletRequest request) {
4444

4545
// 配置需要CSRF校验的请求方式,
46-
HashSet<String> allowedMethods = new HashSet<String>(Arrays.asList(csrfMethod));
46+
HashSet<String> allowedMethods = new HashSet<>(Arrays.asList(csrfMethod));
4747
// return false表示不校验csrf
4848
if (!csrfEnabled) {
4949
return false;
@@ -74,7 +74,8 @@ protected void configure(HttpSecurity http) throws Exception {
7474
.successHandler(new LoginSuccessHandler())
7575
.failureHandler(new LoginFailureHandler()).and()
7676
.logout().logoutUrl("/logout").permitAll().and()
77-
.rememberMe(); // tomcat默认JSESSION会话有效时间为30分钟,所以30分钟不操作会话将过期。为了解决这一问题,引入rememberMe功能。
77+
// tomcat默认JSESSION会话有效时间为30分钟,所以30分钟不操作会话将过期。为了解决这一问题,引入rememberMe功能。
78+
.rememberMe();
7879
}
7980

8081
/**
@@ -84,7 +85,7 @@ protected void configure(HttpSecurity http) throws Exception {
8485
CorsConfigurationSource corsConfigurationSource()
8586
{
8687
// Set cors origin white list
87-
ArrayList<String> allowOrigins = new ArrayList<String>();
88+
ArrayList<String> allowOrigins = new ArrayList<>();
8889
allowOrigins.add("joychou.org");
8990
allowOrigins.add("https://test.joychou.me"); // 区分http和https,并且默认不会拦截同域请求。
9091

0 commit comments

Comments
 (0)