0x01 XSS
package com.example.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class XSSServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String content = req.getParameter("content");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.write(content);
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>XSSServlet</servlet-name>
<servlet-class>com.example.servlet.XSSServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XSSServlet</servlet-name>
<url-pattern>/test.jsp</url-pattern>
</servlet-mapping>
</web-app>
2.1 将特殊字符实体化编码
public String xssWrapper1(String content) {//利用实体化编码将特殊字符转义
content = StringUtils.replace(content, "&", "&");
content = StringUtils.replace(content, "<", "<");
content = StringUtils.replace(content, ">", ">");
content = StringUtils.replace(content, """, """);
content = StringUtils.replace(content, "'", "'");
content = StringUtils.replace(content, "/", "/");
return content;
}
public String xssWrapper2(String content) {
//利用spring自带的编码格式对字符进行编码
return HtmlUtils.htmlEscape(content);
}
0x02 SSRF
package com.example.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
public class SSRFServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String file = req.getParameter("file");
String s = URLConnection(file);
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.write(s);
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
public static String URLConnection(String url) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String content;
StringBuffer html = new StringBuffer();
while ((content = reader.readLine()) != null) {
html.append(content);
}
reader.close();
return html.toString();
} catch (Exception e) {
return e.getMessage();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>SSRFServlet</servlet-name>
<servlet-class>com.example.servlet.SSRFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SSRFServlet</servlet-name>
<url-pattern>/test.jsp</url-pattern>
</servlet-mapping>
</web-app>
1.3.1 任意文件读取
1.3.2.1 地址存活
1.3.2.2地址不存活
【必须】避免直接访问不可信地址
服务器访问不可信地址时,禁止访问私有地址段及内网域名。
建议通过URL解析函数进行解析,获取host或者domain后通过DNS获取其IP,然后和内网地址进行比较。
对已校验通过地址进行访问时,应关闭跟进跳转功能。
原文始发于微信公众号(锦行信息安全):Java代审6:XSS和SSRF