
SSR状态序列化暗藏哪些安全隐患react-ssr中serialize-javascript防XSS实战【免费下载链接】react-ssrA baseline for server side rendering for your React application项目地址: https://gitcode.com/gh_mirrors/re/react-ssr做React SSR服务端渲染时有一个几乎人人都要处理的细节把服务端拿到的Redux 状态序列化后注入 HTML供浏览器水合hydrate使用。开源项目react-ssr一个 React 服务端渲染基线示例给出了业界标准答案——用serialize-javascript替代裸JSON.stringify从源头堵住SSR 状态序列化 XSS漏洞。本文带你逐行看懂这条服务器取数 → 序列化 → 客户端水合链路以及其中暗藏的安全陷阱。先看懂链路状态是怎么从服务端搬到浏览器的 react-ssr 的数据流转非常简洁整条链路由四个文件串起来服务器取数src/api.js请求外部接口F1 赛程数据src/store.js中的fetchCircuits把结果存入 Redux 的data字段服务端渲染src/server.js在 Express 中创建 store、执行serverFetch取数用renderToString把组件渲染成 HTML 字符串状态序列化渲染完成后把store.getState()的整个状态对象序列化塞进页面内联script的window.REDUX_DATA变量客户端水合src/client.js用createStore(window.REDUX_DATA)直接复用这份状态配合ReactDOM.hydrate完成接管。// src/server.js简化 const reduxState store.getState(); res.end(htmlTemplate(reactDom, reduxState, helmetData)); // htmlTemplate 中注入状态 // script // window.REDUX_DATA ${ serialize( reduxState, { isJSON: true } ) } // /script 为什么要注入状态否则客户端加载后还要重新请求一遍接口白白浪费服务端已经取到的数据首屏也慢一截。暗藏隐患JSON.stringify 序列化为什么会翻车⚠️很多教程会直接写JSON.stringify(state)注入 HTML。这在两个场景下会出安全事故/script逃逸状态里只要有/script这个字符串比如用户提交过的内容、评论、昵称序列化结果就会提前关闭script 标签攻击者可趁机插入自己的script执行任意代码——经典 XSS!--注释逃逸在 HTML 中!--会开启注释把后续 JS 全部注释掉或改变解析边界同样可能被利用。react-ssr 的状态来自接口数据见src/api.js而真实业务里 state 往往混着用户可控内容表单、评论、富文本。一旦这些数据原样进入 HTML风险就是实打实的。标准答案serialize-javascript 如何防 XSS️react-ssr 在src/server.js第 5 行引入了serialize-javascriptpackage.json中锁定为^2.1.1序列化那一行只比JSON.stringify多了几个字import serialize from serialize-javascript; // ... window.REDUX_DATA ${ serialize( reduxState, { isJSON: true } ) }它做了几件关键的事机制作用转义/script为\/script从根上阻断标签逃逸浏览器 JS 引擎仍正确解析处理!--等特殊序列避免 HTML 注释边界被破坏isJSON: true选项保证输出是合法 JSON客户端可直接JSON.parse或字面量解析与JSON.stringify兼容性一致简单说它输出的字符串既是合法 JS、又是合法 JSON、还绝不会破坏宿主script标签三者兼得这是裸JSON.stringify做不到的。水合端客户端如何安全地接住这份状态src/client.js中只有一行核心逻辑const store createStore( window.REDUX_DATA );由于服务端已保证window.REDUX_DATA是一段安全的 JS 字面量浏览器在解析 HTML 时就会把状态对象构造好客户端无需二次解析、也不存在HTML 解析器先于 JS 引擎执行的注入窗口。整个入口链也可参考根目录index.js用 babel-register 引导再require(./src/server)启动src/server.js中的 Express 服务监听 2048 端口。序列化库之外两个更隐蔽的坑 光靠serialize-javascript还不够成熟项目还应注意别把敏感数据放进 storesrc/store.js的loggedIn只是布尔值很安全。但如果你把 JWT、session token、API key 也写进 state它们会随window.REDUX_DATA完整暴露在每个用户的页面源码里任何人都能查看源代码拿走。原则store 只放渲染页面所必需的数据数据源头不可信src/api.js拉取的接口数据最终都进了 state。若接口内容可被第三方影响比如 UGC序列化层转义是最后一道防线——不要依赖我们的数据很干净。实用清单SSR 状态序列化安全自查 ✅用serialize-javascript或等效安全方案替代JSON.stringify注入 HTML开启isJSON: true保证客户端可直接解析注入前检查 state 中无 token、密钥等敏感字段客户端通过window.*变量直接读取不做二次eval/JSON.parse用户数据在src/server.js的htmlTemplate函数中集中管理注入逻辑避免多处散落的模板字符串。写在最后react-ssr 虽是一个刻意保持极简的教学基线README 中明确提醒不要在生产里复制这些简化但它在状态序列化这一环的做法——serialize-javascriptisJSON 全局变量水合——至今仍是 React SSR 的安全实践标杆。理解这条链路后无论是自研 SSR 还是使用 Next.js、Remix 等框架你都能敏锐地回答那个终极问题我注入到 HTML 里的每个字节都可控吗【免费下载链接】react-ssrA baseline for server side rendering for your React application项目地址: https://gitcode.com/gh_mirrors/re/react-ssr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考