尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

devalue安全指南:如何有效防范XSS攻击并保护应用安全

devalue安全指南:如何有效防范XSS攻击并保护应用安全 devalue安全指南如何有效防范XSS攻击并保护应用安全【免费下载链接】devalueGets the job done when JSON.stringify cant项目地址: https://gitcode.com/gh_mirrors/de/devaluedevalue 是一个 JavaScript 序列化库用来替代 JSON.stringify 处理循环引用、undefined、日期、Map/Set 等复杂值。它最被低估的价值是内置的 XSS 防护机制——在把数据内嵌进 HTML 页面时能直接阻断脚本注入攻击。这篇指南讲清楚它的三层防御原理和正确用法。为什么 JSON.stringify 会埋下 XSS 隐患做服务端渲染时最常见的手法是把数据序列化成 JavaScript 代码塞进页面的script标签里var preloaded ${JSON.stringify(state)};问题在于JSON 不会转义字符串里的和。只要某个字段来自用户输入比如const state { userinput: /scriptscript srchttps://evil.com/a.js };拼出来的 HTML 就会变成这样——脚本标签被提前闭合恶意代码被浏览器当成新脚本执行了script var preloaded {userinput: /script script srchttps://evil.com/a.js }; /script这就是典型的服务端渲染 XSS 注入攻击者不需要碰到你的前端代码只需要提交一条包含/script的评论或昵称。devalue 如何从源头阻断脚本注入devalue 的uneval和stringify在生成字符串时就做了双重防护核心实现在 src/uneval.js 和 src/utils.js第一重危险字符全部转义。序列化时、反斜杠、换行、U2028/U2029 等字符会统一替换成 Unicode 转义序列如→\u003C。转义表定义在 src/utils.js 的escaped对象中原始字符devalue 输出\u003C\\\换行 / 回车\n/\rU2028 / U2029\u2028/\u2029于是上面那段攻击载荷经uneval(state)处理后变成var preloaded { userinput: \u003C\u002Fscript\u003E\u003Cscript srchttps:\u002F\u002Fevil.com\u002Fmwahaha.js\u003E };/script变成了无害的\u003C\u002Fscript\u003E浏览器无法从中逃出脚本上下文。第二重拒绝序列化函数。uneval遇到函数或无法识别的非普通对象时会直接抛出 DevalueError。攻击者即使构造了精心设计的对象也无法借序列化过程携带可执行代码——这是序列化输出可安全 eval这一承诺成立的关键前提。三种安全用法按场景选对 APIdevalue 提供三种序列化方式安全性各有边界1. uneval服务端 → 客户端的安全通道uneval输出的就是可执行的 JavaScript 表达式体积最紧凑官方明确建议用它从服务端向客户端传数据import { uneval } from devalue; const html script var preloaded ${uneval(state)}; /script;客户端反序列化时用间接 eval切断对周围作用域的访问const data (0, eval)(( str ));⚠️ 注意两个细节必须写成(0, eval)(...)或(1, eval)(...)这种间接调用。直接eval(...)会让被执行的代码访问到外层变量等于给注入代码开了后门。new Function(code)与间接 eval 等效也可以放心使用。2. stringify parse完全不想 eval 时的选择如果你的运行环境禁止 eval如 CSP 严格模式就用与 JSON 同构的stringify/parse组合import { stringify, parse } from devalue; const stringified stringify(obj); // 可安全嵌入任意 JSON 位置 const revived parse(stringified); // 还原出循环引用、日期等stringify的输出是纯 JSON 数组parse负责还原 Map、Set、日期、循环引用等类型且输出同样经过 XSS 转义处理。3. unflatten嵌入大 JSON 中的片段还原当 devalue 数据只是整个 JSON 响应的一部分时const json { type: data, data: ${devalue.stringify(data)} }; const data devalue.unflatten(JSON.parse(json).data);重要边界绝不要用 uneval 接收客户端数据这是新手最容易踩的坑官方文档README.md 的 Other security considerations 一节特别强调uneval 只能用于服务端 → 客户端方向。因为uneval的输出最终要经过 eval 执行如果拿它来序列化用户提交给服务端的数据等于把 eval 执行权交给了攻击者——一旦有人构造出绕过序列化的 payload就能在你的服务器上执行任意代码。一句话记住✅ 服务端 → 客户端用uneval或stringify✅ 客户端 → 服务端只传纯 JSON服务端用JSON.parse接收出错了怎么定位DevalueError 自带路径追踪devalue 拒绝序列化非法值时抛出的不是普通错误。DevalueError在 src/utils.js 中实现附带一个path属性精确指向问题值在数据结构中的位置try { devalue.uneval({ object: { array: [new Map([[k, () {}]])] } }); } catch (e) { console.log(e.path); // .object.array[0].get(\k\) }排障时直接打印error.path一眼就能看到是哪个字段混进了函数。进阶用 operations 关闭序列化时的意外执行默认情况下序列化过程会读取属性、调用原型方法——如果对象上定义了 getter它会被触发。对于需要确定性、沙箱化的场景如处理不可信对象可以通过operations选项覆盖这些操作例如只通过属性描述符读值、遇到 getter 直接抛错从而保证序列化全程无副作用。接口定义见 src/operations.js。安全实践清单 内嵌数据到script标签→ 用devalue.uneval()不要手动拼JSON.stringify的结果禁用 eval 的环境→ 改用devalue.stringify()devalue.parse()反序列化 uneval 输出→ 一律使用间接调用(0, eval)(...)或new Function接收客户端数据→ 只接受 JSON绝不经过 uneval处理用户输入含 HTML 标签时→ 确认转义生效输出中应看到\u003C而非序列化报错→ 打印error.path快速定位污染源掌握这几点devalue 就能在你应用的数据通道上稳稳挡住这一类最常见的 XSS 攻击。【免费下载链接】devalueGets the job done when JSON.stringify cant项目地址: https://gitcode.com/gh_mirrors/de/devalue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表