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

微信小程序 XSS 防护知识整理

场景1:用户输入表单(如评论框)

错误做法:直接渲染未过滤的用户输入
// WXML
<view>{{ userInput }}</view>// JS(用户输入了恶意内容)
Page({data: { userInput: '<script>alert("XSS攻击")</script>' }
})

结果:小程序会自动转义,页面显示为文本:<script>alert("XSS攻击")</script>,不会执行脚本。
防护原理:数据绑定 ({{ }}) 默认转义 HTML 特殊字符(如 <&lt;)。


场景2:动态渲染富文本(如用户发布的文章)

错误做法:直接用 rich-text 渲染未过滤的内容
// WXML
<rich-text nodes="{{ userContent }}"></rich-text>// JS(用户输入了危险内容)
Page({data: {userContent: '<img src="x" onerror="alert(1)">' // 包含恶意 onerror 事件}
})

结果:小程序 rich-text 组件会自动过滤 onerror 属性,最终渲染成 <img src="x">
防护原理rich-text 组件内置黑名单,过滤 scriptiframe 和危险属性(如 onclickonerror)。


场景3:使用 web-view 嵌入外部网页

错误做法:加载不可信的第三方网页
<web-view src="{{ externalUrl }}"></web-view>// JS(外部链接被篡改)
Page({data: {externalUrl: 'https://恶意网站.com?attack=...'}
})

风险:外部网页可能含有 XSS 攻击代码,通过 web-view 传播。
正确做法

  1. 限制 web-view 只能加载白名单域名(在小程序后台配置)。
  2. src 参数做合法性校验:
// 校验 URL 是否合法
if (!isValidUrl(externalUrl)) {externalUrl = ''; // 拒绝加载
}

场景4:调用接口获取数据

错误做法:信任后端返回的未过滤数据
// 假设后端返回数据:{ content: '<script>恶意代码</script>' }
wx.request({url: 'api/getData',success: (res) => {this.setData({ content: res.data.content }); // 直接渲染}
})

结果:虽然小程序默认转义,但如果数据用于不安全场景(如 web-view),仍可能引发风险。
正确做法

  1. 后端返回前对数据做 XSS 过滤。
  2. 前端对关键内容二次过滤:
// 使用微信提供的安全过滤函数(示例)
const safeContent = filterXSS(res.data.content);
this.setData({ content: safeContent });

场景5:用户昵称/简介中的特殊字符

错误做法:允许用户输入任意字符
// 用户输入昵称:<img src=x onerror=alert(1)>
Page({data: { nickname: userInput }
})

结果:渲染到页面时会被转义,但若其他地方误用(如转发到其他系统),可能引发风险。
正确做法

  1. 输入时过滤危险字符:
// 前端过滤
const cleanNickname = nickname.replace(/[<>"'&]/g, '');// 或调用微信内容安全接口(推荐)
wx.msgSecCheck({content: nickname,success: () => { /* 内容安全 */ },fail: () => { /* 拦截危险内容 */ }
})

总结:XSS 防护口诀

  1. 数据绑定用双花{{ }} 默认转义,别用 innerHTML
  2. 富文本要过滤rich-text 或安全解析库。
  3. 用户输入必校验:前后端双重过滤。
  4. 动态代码要禁用:别用 evalnew Function
  5. 外部内容严管控web-view 域名白名单。

附:XSS 测试工具

  • 安全测试输入:尝试输入以下内容,检查是否被转义:
    <img src=x onerror=alert(1)>   <!-- 测试HTML属性 -->
    <script>alert(1)</script>      <!-- 测试脚本标签 -->
    javascript:alert(1)            <!-- 测试URL协议 -->
    

相关文章:

  • 上海车展,世界模型 + VLA,城区智驾进入下半场
  • 同时启动俩个tomcat压缩版
  • spring--事务详解
  • react-10样式模块化(./index.module.css, <div className={welcome.title}>Welcome</div>)
  • 神经网络用于地震数据时空均匀插值的方法与开源资料
  • 六、UI自动化测试06--PO设计模式
  • micro-app前端微服务原理解析
  • 论文笔记(八十二)Transformers without Normalization
  • linux系统加固
  • 逻辑回归之参数选择:从理论到实践
  • GNU gettext 快速上手
  • 两向量平行公式、向量与平面平行公式、两平面平行公式;两向量垂直公式、向量与平面垂直公式、两平面垂直公式
  • 基于 HT 构建 2D 智慧仓储可视化系统的技术解析
  • IP 地址和 MAC 地址是如何转换的
  • mac下载homebrew 安装和使用git
  • 3.2goweb框架GORM
  • 基于BM1684X+RK3588的智能工业视觉边缘计算盒子解决方案
  • c++线程的创建
  • 【Hive入门】Hive高级特性:事务表与ACID特性详解
  • 大数据平台与数据仓库的核心差异是什么?
  • 启程回家!神十九轨道舱与返回舱成功分离
  • 运动健康|不同能力跑者,跑步前后营养补给差别这么大?
  • 言短意长|政府食堂、停车场开放的示范效应
  • 西班牙遭遇史上最严重停电,已进入国家紧急状态
  • 国家发改委答澎湃:将指导限购城市针对长期摇号家庭和无车家庭等重点群体定向增发购车指标
  • 李强主持召开国务院常务会议