当前位置: 首页 > news >正文

后端接口防止XSS漏洞攻击

        有这样一个场景,首先构建一个docx文件并插入超链接(恶意的链接),上传到文件服务器后获取对应的文件filekey。现在我们提供一个预览接口,通过filekey便可以预览,在根据filekey转html文档返回给页面的时候由于插入的超链接成功触发XSS攻击;

        初始预览接口代码示例如下:

@GetMapping(value = "/wordConvertHtml/{fileKey}")@ApiImplicitParam(name = "fileKey", value = "文件唯一key", required = true)public void wordConvertHtml(@PathVariable String fileKey, HttpServletResponse response) throws IOException {OutputStream bos = null;try {InputStreamVO inputStreamVO = commonFileService.getInputStreamWithAuthCheck(fileKey);Document doc = new Document(inputStreamVO.getInputStream());HtmlSaveOptions opts = new HtmlSaveOptions(SaveFormat.HTML);opts.setExportXhtmlTransitional(true);opts.setExportImagesAsBase64(true);opts.setExportPageSetup(true);opts.setPrettyFormat(true);}catch (FileCorruptedException e) {log.error("word转换HTML发生特定异常:{}", e);// 给前端提示特殊信息PrintWriter out = new PrintWriter(bos);out.println("文件含有特殊格式,系统不兼容。");out.flush();out.close();} catch (Exception e) {log.error("word转换HTML异常", e);// 给前端提示信息response.setContentType("text/html; charset=UTF-8");PrintWriter out = new PrintWriter(bos);out.println(e.getMessage());out.flush();out.close();} finally {if (bos != null) {bos.close();}}}

处理方式:

       添加更全面的安全头设置:确保所有可能返回HTML内容的路径都设置了适当的安全头

1.Content-Security-Policy (CSP)

response.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'none'; style-src 'unsafe-inline'; img-src data:;");

这是一个重要的安全特性,用于防止跨站脚本攻击(XSS)、点击劫持等攻击:

  • default-src 'none': 默认情况下不允许从任何源加载资源
  • script-src 'none': 不允许执行任何JavaScript代码
  • style-src 'unsafe-inline': 允许内联样式(如<style>标签和style属性)
  • img-src data:: 只允许通过data URI加载图片

这种配置可以有效防止恶意脚本注入,同时允许内联样式和内嵌图片显示。

2.X-Content-Type-Options

response.setHeader("X-Content-Type-Options", "nosniff");

防止浏览器尝试猜测或"嗅探"响应的内容类型:

  • 浏览器会严格按照服务器提供的Content-Type头来处理内容
  • 防止某些类型的攻击,比如将JavaScript文件当作图片显示

3.X-Frame-Options

response.setHeader("X-Frame-Options", "DENY");

防止页面被嵌入到iframe中,用于防止点击劫持攻击:

  • DENY: 页面不能被嵌入到任何iframe中
  • 这可以防止恶意网站将你的页面嵌入到他们的网站中进行钓鱼攻击

4.X-XSS-Protection

response.setHeader("X-XSS-Protection", "1; mode=block");

启用浏览器的内置XSS过滤器:

  • 1: 启用XSS过滤
  • mode=block: 当检测到XSS攻击时,浏览器会阻止整个页面加载,而不是仅仅过滤掉可疑内容

最后统一对错误进行处理,这样安全等级会更高。


@GetMapping(value = "/wordConvertHtml/{fileKey}")
@ApiImplicitParam(name = "fileKey", value = "文件唯一key", required = true)
public void wordConvertHtml(@PathVariable String fileKey, HttpServletResponse response) throws IOException {OutputStream bos = null;try {bos = response.getOutputStream();response.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline';");response.setHeader("X-Content-Type-Options", "nosniff");response.setHeader("X-Frame-Options", "DENY");response.setHeader("X-XSS-Protection", "1; mode=block");InputStreamVO inputStreamVO = commonFileService.getInputStreamWithAuthCheck(fileKey);Document doc = new Document(inputStreamVO.getInputStream());HtmlSaveOptions opts = new HtmlSaveOptions(SaveFormat.HTML);opts.setExportXhtmlTransitional(true);opts.setExportImagesAsBase64(true);opts.setExportPageSetup(true);opts.setPrettyFormat(true);doc.save(bos, opts);} catch (FileCorruptedException e) {log.error("word转换HTML发生特定异常:{}", e);// 给前端提示特殊信息// 设置安全响应头response.setContentType("text/html; charset=UTF-8");response.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'none';");response.setHeader("X-Content-Type-Options", "nosniff");response.setHeader("X-Frame-Options", "DENY");PrintWriter out = new PrintWriter(bos);out.println("文件含有特殊格式,系统不兼容。");out.flush();out.close();} catch (Exception e) {log.error("word转换HTML异常", e);// 给前端提示信息// 设置安全响应头response.setContentType("text/html; charset=UTF-8");response.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'none';");response.setHeader("X-Content-Type-Options", "nosniff");response.setHeader("X-Frame-Options", "DENY");PrintWriter out = new PrintWriter(bos);out.println(HtmlUtils.htmlEscape(e.getMessage()));out.flush();out.close();} finally {if (bos != null) {bos.close();}}
}


文章转载自:

http://nugs6S2P.xqtqm.cn
http://PH1DHHe2.xqtqm.cn
http://8tBX03xL.xqtqm.cn
http://rkwPL2Hg.xqtqm.cn
http://XMiA2ERV.xqtqm.cn
http://4K6s12UF.xqtqm.cn
http://2mHtKBBn.xqtqm.cn
http://rqECROLf.xqtqm.cn
http://sxay1N83.xqtqm.cn
http://a2eYt5tn.xqtqm.cn
http://IZwRZQYd.xqtqm.cn
http://am7Dk3ww.xqtqm.cn
http://lMShDuXJ.xqtqm.cn
http://F0R9pnmP.xqtqm.cn
http://4WXmcA8q.xqtqm.cn
http://7rJf8Q17.xqtqm.cn
http://3PnqXMNE.xqtqm.cn
http://P5pMAlcn.xqtqm.cn
http://iRr7jC5u.xqtqm.cn
http://AdxlFESR.xqtqm.cn
http://aQSwUE0N.xqtqm.cn
http://fdYnGiYd.xqtqm.cn
http://Hq7PrHN5.xqtqm.cn
http://3rbsZT11.xqtqm.cn
http://UCyRG1xY.xqtqm.cn
http://GZpJg1Qx.xqtqm.cn
http://Oi0ShBnB.xqtqm.cn
http://qLyflMgd.xqtqm.cn
http://cpRZWzEF.xqtqm.cn
http://LtLJdeuB.xqtqm.cn
http://www.dtcms.com/a/375001.html

相关文章:

  • Hadoop(十一)
  • 【Linux基础知识系列:第一百二十五篇】理解Linux中的init与systemd
  • iOS原生开发和Flutter开发的看法
  • 【ArkTS-装饰器】
  • XSS漏洞检测和利用
  • Vue3 生命周期函数
  • Flask/Django 生产部署:Gunicorn vs Nginx,Windows 与 Linux 实战指引
  • 从 Row 到 WaterFlow:鸿蒙应用开发ArkUI布局全家桶教程
  • 开发避坑指南(44):Mybatis-plus QueryWrapper and()拼接嵌套复杂条件的技巧
  • 消息队列(MQ)初级入门:详解RabbitMQ与Kafka
  • R语言对excel中多个sheet子表批量进行地理探测器计算
  • 开讲啦| MBSE公开课:第六集 MBSE远期目标与总结(完结)
  • 实习项目包装--HTTP 协议和 Web API
  • linux升级系统,重启出现Minimal BASH-like line editingis supported
  • ARM架构---指令集分类、内核组成,RAM与ROM的分类、工作模式、异常处理机制、立即数、s后缀、指令说明、汇编和 C 函数的相互调用
  • Qwen3微调教程:从零开始训练你的定制语言模型
  • 本地一键部署IndexTTS2,生成情绪饱满的语音,支持Windows和Mac
  • VMware虚拟机CentOS磁盘扩容完整指南(解决growpart报错 LVM扩容)
  • 【增删改查操作】
  • MySQL 多表操作与复杂查询:深入理解多表关系和高级查询
  • 网络相关知识整理
  • 提升网站用户体验的方法 | 网站优化与用户界面设计
  • CSS的文本样式
  • Flex布局——详解
  • 深度解析CSS单位与媒体查询:构建现代化响应式布局的核心技术
  • 项目组件抽离封装思路
  • Elasticsearch面试精讲 Day 13:索引生命周期管理ILM
  • 【MySQL】从零开始了解数据库开发 --- 数据类型
  • ElasticSearch复习指南:从零搭建一个商品搜索案例
  • 宋红康 JVM 笔记 Day15|垃圾回收相关算法