lishihuan大约 9 分钟

场景漏洞整改记录

https://blog.csdn.net/qq_39560975/article/details/131956264open in new window

https://www.hacking8.com/mst-sec-lecture-notes/3.htmlopen in new window

https://github.com/wizardforcel/mst-sec-lecture-notes/blob/master/漏洞篇 SSRF.mdopen in new window

https://github.com/JoyChou93/java-sec-code/blob/master/README_zh.mdopen in new window

https://wiki.wgpsec.org/knowledge/web/unauthorized.htmlopen in new window

原型链污染

https://blog.csdn.net/m0_69435261/article/details/132054575open in new window

1)实验一

let foo = {bar :1}
console.info(foo.bar)
//foo是一个object foo.__proto__ === object.prototype
foo.__proto__.bar = 2
console.info(foo.bar)
let zoo = {}
console.info(zoo.bar)

污染过程:

因为前面我们修改了foo的原型foo.proto.bar = 2,而foo是一个Object类的实例,所以实际上是修改了Object这个类,给这个类增加了一个属性bar,值为2。

后来,我们又用Object类创建了一个zoo对象let zoo = {},zoo对象自然也有一个bar属性

http://www.mi1k7ea.com/2019/10/20/浅析JavaScript原型链污染攻击/open in new window

Deserialization of Untrusted Data:不可信数据的反序列化

引入 Web 安全扫描工具进行持续检测

例如:OWASP ZAP、Nessus、Burp Suite 可定期扫描 XSS/SSRF/SQLi 等漏洞。

OWASP ZAP 自动化扫描 XSS、SSRF、SQLi 等

如何测试反射型 XSS(Reflected XSS)

🧩 步骤一:识别可疑入口点

找出你项目中接受 URL 参数或表单参数 并将其直接 输出到页面 的接口。

比如:

http://localhost:8012/onlinePreview?url=http://example.com

如果服务在页面中展示了这个 URL 参数(如文件名称、错误信息、标题等),就可能有反射型 XSS。


🧩 步骤二:构造恶意 URL 进行测试

使用简单的脚本 Payload 作为参数输入:

php-template


复制编辑
<script>alert('XSS')</script>

URL 编码之后的版本(推荐方式):

perl


复制编辑
%3Cscript%3Ealert('XSS')%3C%2Fscript%3E

✅ 示例测试链接(假设接口是 /onlinePreview?url=

perl


复制编辑
http://localhost:8012/onlinePreview?url=%3Cscript%3Ealert('XSS')%3C%2Fscript%3E

将这个链接直接在浏览器打开。


🧩 步骤三:观察页面行为

  • 如果弹出一个 JS alert() 窗口,即说明存在反射型 XSS。
  • 如果页面中显示了你注入的 <script> 字符串原样(未编码),也说明存在潜在风险。
  • 如果页面返回了 400/500 错误,说明后台做了过滤或解析失败,但还不能确定安全。

🔍 示例分析:测试页面内容

如果你输入如下 URL:

perl


复制编辑
http://localhost:8012/onlinePreview?url=%3Cscript%3Ealert(1)%3C/script%3E

页面返回:

html


复制编辑
预览失败:<script>alert(1)</script>

⚠️ 说明反射成功,脚本被直接执行了 → 存在 反射型 XSS 漏洞


✅ 如何修复反射型 XSS

你应该在输出内容到 HTML 页面时进行 HTML 实体转义

  • <<
  • >>
  • ""
  • ''

示例(Java):

java复制编辑// Apache Commons Text
String safeInput = StringEscapeUtils.escapeHtml4(userInput);

🛠️ 实用工具辅助测试

工具功能
Burp Suite拦截请求并插入 Payload
OWASP ZAP自动化扫描反射型 XSS
XSS Hunter记录所有成功执行的 XSS 实例
Browser DevTools查看是否有 <script> 被插入页面

📌 总结:反射型 XSS 测试四步法

步骤操作
1. 找参数入口确认 URL 是否直接反射参数内容
2. 构造 Payload注入 <script>alert(1)</script>
3. 打开页面观察是否弹框或页面变化
4. 查看响应HTML 中是否有未转义的脚本

针对SSRF 和CSP

安全措施建议
输入验证手动编写或使用拦截器/过滤器过滤 XSS
SSRF 防御对 URL 参数进行白名单、IP 检查
CSP 策略设置 CSP 响应头限制资源来源
Cookie 安全即使无登录,也建议设置 HttpOnly / Secure
安全框架轻量使用使用 Spring Security 配置请求规则和安全头部(不启用认证)

通过以下几种方式来验证 Cookie 安全属性(HttpOnly、Secure、SameSite)是否生效。这里提供从开发者工具、Postman、浏览器脚本等不同角度的验证方法。


✅ 一、使用浏览器开发者工具验证(最直观)

  1. 打开你的工具页面(比如 http://localhost:8012)。
  2. F12 打开浏览器开发者工具 → 切到 Application / 存储(Storage) → Cookies。
  3. 找到你设置的 Cookie(比如 myToken 或其他)。
  4. 检查以下字段:
字段名是否应设置
HttpOnly✅ 是
Secure✅ 是(如果在 HTTPS 下测试)
SameSite✅ 是,值为 Strict(或你设置的其他值)

⚠️ 注意:

  • Secure 只有在 https:// 下才会显示。你可以用代理工具(如 ngrokopen in new window 或配置本地 HTTPS)来测试。
  • 如果这些属性没显示,说明你的过滤器可能没生效或设置被覆盖。

打开浏览器控制台(Console),执行:

js


复制编辑
document.cookie
  • 如果你设置了 HttpOnly,该 Cookie 不会出现在结果中。
  • 如果 Cookie 被显示了,说明 HttpOnly 设置失败或没生效

  1. 打开 Postmanopen in new window 或 curl 工具。

  2. 请求你设置 Cookie 的接口,比如:

    bash
    
    
    复制编辑
    GET http://localhost:8012/test-set-cookie
    
  3. 查看 响应头(Headers) 中的 Set-Cookie 字段。

你应该能看到类似这样的返回:

http


复制编辑
Set-Cookie: myToken=abc123; HttpOnly; Secure; SameSite=Strict

✅ 四、使用 curl 验证(终端方式)

bash


复制编辑
curl -i http://localhost:8012/test-set-cookie

示例输出:

http


复制编辑
Set-Cookie: myToken=abc123; HttpOnly; Secure; SameSite=Strict

✅ 五、测试建议接口(辅助验证)

你可以创建一个简单的控制器来设置 Cookie 测试:

java复制编辑@RestController
public class CookieTestController {

    @GetMapping("/test-set-cookie")
    public String testCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie("myToken", "abc123");
        cookie.setPath("/");
        cookie.setMaxAge(3600);
        response.addCookie(cookie);
        return "Cookie sent.";
    }
}

用它来触发 Cookie 的写入,然后在浏览器/Postman 中观察 Set-Cookie 响应头。


🧪 验证总结表

验证方式可验证的属性推荐级别
浏览器 DevToolsHttpOnly / Secure / SameSite⭐⭐⭐⭐
document.cookieHttpOnly 是否阻止访问⭐⭐⭐
Postman / curl响应头中的 Set-Cookie 内容⭐⭐⭐⭐⭐
控制器接口辅助测试手动控制 cookie 发出行为⭐⭐⭐⭐⭐

SSRF

https://melons.top/2019/12/15/SSRF/open in new window

https://xz.aliyun.com/t/7405?time__1311=n4%2BxnD0G0%3DitKiIK0KDsA3OrDcnYDuG0hQrnYD&alichlgref=https%3A%2F%2Fwww.google.com.hk%2Fopen in new window

aHR0cHM6Ly9iYWlkdS5jb20= --> http://baidu.com

如果能访问并且访问到百度,则表示 存在SSRF漏洞

http://localhost:8012/getCorsFile?urlPath=aHR0cHM6Ly9iYWlkdS5jb20=
urlPath=aHR0cDovLzEyNy4wLjAuMTo4MDgw` → `http://127.0.0.1:8080

Unchecked Input for Loop Condition 循环条件的输入未被检查

  • 原来的写法
    private String downloadJson() throws Exception {
        final StringBuilder jsonContent = new StringBuilder();

        final URLConnection urlConnection = URLConnectionHelper.createConnectionToURL(downloadUrl, requestHeaders);
        final InputStreamReader streamReader = new InputStreamReader(urlConnection.getInputStream());
        final BufferedReader bufferedReader = new BufferedReader(streamReader);

        final char data[] = new char[1024];
        int count;
        while ((count = bufferedReader.read(data)) != -1) {
            jsonContent.append(data, 0, count);
        }
        bufferedReader.close();

        return jsonContent.toString();
    }
  • 修改后的写法,设置一个最大的循环次数,超出给出告警
private String downloadJson() throws Exception {
    // 设置一个最大读取次数,例如10000次,可以根据实际情况调整这个值
    final int MAX_READ_TIMES = 10000;

    final StringBuilder jsonContent = new StringBuilder();
    final URLConnection urlConnection = URLConnectionHelper.createConnectionToURL(downloadUrl, requestHeaders);
    final InputStreamReader streamReader = new InputStreamReader(urlConnection.getInputStream());
    final BufferedReader bufferedReader = new BufferedReader(streamReader);

    final char data[] = new char[1024];
    int count;
    int readTimes = 0; // 添加一个变量来记录读取的次数

    while ((count = bufferedReader.read(data)) != -1) {
        jsonContent.append(data, 0, count);

        // 如果读取的次数超过最大读取次数,那么抛出一个异常并退出循环
        if (++readTimes > MAX_READ_TIMES) {
            throw new Exception("Exceeded maximum read times");
        }
    }

    bufferedReader.close();
    return jsonContent.toString();
}

XSS

目前以kkFileView为例,端口 8012

https://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.htmlopen in new window

https://blog.csdn.net/2401_86951100/article/details/142155389open in new window

漏洞测试

http://"> <svg onload="window.onerror=eval;throw='alert(1)';"></test.png

这是一个典型的 XSS 攻击向量

  • "><svg ...> 试图逃出属性并注入 SVG 标签。
  • onload="window.onerror=eval;throw='alert(1)';" 利用了 SVG 的 onload 属性,触发 eval 执行 alert(1)
  • 最终构成一个恶意 payload:
html


复制编辑
<img src="http://"><svg onload="window.onerror=eval;throw='alert(1)';">/test.png">

它的目的是:一旦浏览器尝试渲染这个 URL,就会执行 alert(1),这验证了是否能注入并执行脚本

这是明显的 XSS 尝试,请确保:

  1. Base64 解码后的 URL 内容进行白名单校验。
  2. 只允许加载可信的、明确允许的文件服务器资源。
  3. 禁止外部域名、SVG、data:、javascript: 等 URL。
  4. 输出使用 htmlEscape / StringEscapeUtils.escapeHtml4() 之类的处理。

如何防护?

后端防护措施:

  1. url 白名单校验

只允许以 http://、https:// 开头的真实文件地址,不能包含 <、>、"、' 等特殊字符。

  1. 文件类型校验

只允许图片、文档等安全类型的文件后缀(如 png、jpg、pdf 等),禁止 svg、html、js 等类型。

  1. HTML 转义

所有输出到页面的内容都要做 htmlEscape,防止注入。

前端防护措施:

  • 不要直接拼接用户输入到 HTML 结构里,必要时用 textContent 或 innerText,而不是 innerHTML。
@GetMapping( "/onlinePreview")
    public String onlinePreview(String url, Model model, HttpServletRequest req) {
        String fileUrl;
        try {
            fileUrl = WebUtils.decodeUrl(url);
        } catch (Exception ex) {
            String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
            return otherFilePreview.notSupportedFile(model, errorMsg);
        }
        
        
        // 1. 只允许 http/https 开头
        if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://")) {
            return otherFilePreview.notSupportedFile(model, "不支持的文件来源,只允许 http/https 协议");
        }
        // 2. 只允许白名单后缀
        String lowerUrl = fileUrl.toLowerCase();
        String[] allowedExts = {".png", ".jpg", ".jpeg", ".gif", ".bmp", ".pdf", ".docx", ".xlsx", ".pptx", ".txt", ".zip", ".rar", ".mp4", ".mp3", ".xls", ".ppt"};
        boolean allowed = false;
        for (String ext : allowedExts) {
            if (lowerUrl.endsWith(ext)) {
                allowed = true;
                break;
            }
        }
        if (!allowed) {
            return otherFilePreview.notSupportedFile(model, "不支持预览的文件类型");
        }
        //.......
    }

除了 html以下类型的文件上传后如果被访问,极易带来安全风险,建议全部禁止上传:


1. 网页脚本类

  • htmlhtm(网页文件,可能被直接访问执行)
  • js(JavaScript 脚本)
  • css(样式表,部分攻击可利用)
  • xml(部分情况下可被 XEE 攻击)

2. 服务端脚本/可执行文件

  • phpaspaspxjspjspxpyrbplcgi(服务端脚本,上传后如被服务器解析,极易被利用)
  • exedllcombatshcmdmsijar(可执行文件,可能被下载后运行或被服务器执行)

3. 配置/敏感信息文件

  • propertiesymlyamlinienvconfconfig(配置文件,可能泄露敏感信息)
  • jsondbsqlitesql(数据库、数据文件)

4. 脚本/宏/二进制

  • vbswsfwshps1(Windows 脚本)
  • classpycpyo(编译后脚本)
  • xslxslt(可被 XSLT 注入攻击)

5. 其他高危类型

  • svg(SVG 可嵌入 JS)
  • swf(Flash,已废弃但仍有风险)
  • chm(Windows 帮助文件,可执行脚本)
  • hta(HTML 应用程序)
  • mhtmhtml(网页归档文件)

推荐禁止上传的后缀配置

prohibit = html,htm,js,css,php,asp,aspx,jsp,jspx,py,rb,pl,cgi,exe,dll,com,bat,sh,cmd,msi,jar,vbs,wsf,wsh,ps1,class,pyc,pyo,xsl,xslt,svg,swf,chm,hta,mht,mhtml,properties,yml,yaml,ini,env,conf,config,json,db,sqlite,sql

额外建议

  • 图片、文档、压缩包等常用类型可适当放开,但要确保不会被服务器当作脚本解析。
  • 如有特殊需求,建议只允许白名单类型上传,比如只允许 jpg,png,pdf,docx,xlsx,zip 等。

如需帮你设置“只允许”某些类型上传,或有其他安全需求,欢迎继续提问!