javascript:链接如何拖垮你的站点:Ammonia URL协议白名单与UrlRelative配置实战
javascript:链接如何拖垮你的站点Ammonia URL协议白名单与UrlRelative配置实战【免费下载链接】ammoniaRepair and secure untrusted HTML项目地址: https://gitcode.com/gh_mirrors/am/ammonia如果你的网站允许用户提交 HTML、评论或富文本一条javascript:链接可能就是拖垮整站的隐形炸弹。本文带你用 Rust 生态中流行的HTML 净化库 Ammonia基于白名单机制专为防止 XSS、布局破坏和点击劫持而设计通过URL 协议白名单url_schemes和UrlRelative 相对链接策略两项核心配置快速构建一条可靠的安全防线。️一条 javascript: 链接能做什么坏事想象评论区里这样的内容a hrefjavascript:fetch(/api/secret)点我看答案/a用户一点浏览器直接在你的域名下执行脚本——读取 Cookie、调用你的 API、发起伪造请求。更阴险的写法还有HREF属性值中混入换行和大小写绕过如javAscript:、java#115;cript:data:协议内嵌 HTML 页面实现点击劫持clickjacking相对链接//evil.com伪装成站内资源把用户流量导到恶意站点这些攻击的共同点不是攻击标签而是攻击链接里的 URL。所以 HTML 净化的关键一步就是管住href和src里能写什么。 Ammonia 使用 html5ever 按 HTML5 标准解析输入解析方式和浏览器一致因此对这类语法混淆非常免疫——攻击者骗过 naive 正则清洗器的写法在 Ammonia 眼里都是普通 HTML。第一道防线URL 协议白名单url_schemes在 src/lib.rs 中Ammonia 对每个href/src属性都会先解析 URL再检查协议是否出现在白名单里不在名单内的协议属性整个被删掉。默认白名单里有什么Ammonia 的默认协议白名单比较宽容包含 25 个协议见 src/lib.rs 中Builder::new()的默认值bitcoin, ftp, ftps, geo, http, https, im, irc, ircs, magnet, mailto, mms, mx, news, nntp, openpgp4fpr, sip, sms, smsto, ssh, tel, url, webcal, wtai, xmpp注意两点✅javascript、data、vbscript都不在默认名单中天然被拦截⚠️ftp、ssh、magnet、tel等默认都在——对普通内容站点来说偏宽了实战收紧到最小集合一般内容站建议只保留http、https、mailtouse ammonia::Builder; use maplit::hashset; let safe Builder::new() .url_schemes(hashset![http, https, mailto]) .clean(user_html) .to_string();配套还有两个细粒度方法方法作用使用建议url_schemes(set)整体替换白名单明确自己只需要哪些协议时add_url_schemes([...])在默认名单上追加业务需要自定义协议如my-scheme:时rm_url_schemes([...])从默认名单中移除只想去掉个别危险协议如ftp时对于javascript:链接的清洗效果是链接文字保留href被删除变成无害的普通文本既安全又不影响阅读。另外Ammonia 默认会给外链自动加上relnoopener noreferrerlink_rel配置防止反向标签劫持这一层防护通常是免费白送的。第二道防线UrlRelative 相对链接策略协议白名单只管带协议的绝对 URL。而相对链接如href/admin、href//evil.com/x、href../secret不含协议走的是另一套逻辑——url_relative()配置的UrlRelative策略。相对链接为什么危险//evil.com/page是协议相对链接浏览器会用当前页面的协议直接访问别人的域名常被用来钓鱼站点内容被嵌入 iframe 或转发到别处时站内相对路径会悄悄指向宿主域名下的敏感接口Ammonia 提供 5 种策略定义见 src/lib.rs 中的UrlRelative枚举策略对相对链接的处理适用场景Deny全部删除最严格适合完全不可信的 UGCPassThrough默认原样保留内容确定渲染在自己站内时RewriteWithBase(base_url)按基准 URL 改写成绝对链接归档、离线分发内容RewriteWithRoot { root, path }强制归入指定目录让内容更易移植Custom(闭包)返回Some(新值)改写None删除需要自定义规则的灵活业务⚠️最容易被忽略的一点默认策略是PassThrough也就是说什么都不配的话//evil.com这类协议相对链接会被原样放行。如果你的场景面向外部投稿建议显式收紧。三种典型配置组合 组合一评论区/论坛最严格Builder::new() .url_schemes(hashset![http, https]) .url_relative(UrlRelative::Deny) // 相对链接一律删除 组合二博客/文档站站内互链友好Builder::new() .url_schemes(hashset![http, https, mailto]) .url_relative(UrlRelative::RewriteWithBase( Url::parse(https://your-site.com/)? )) // 相对链接统一改写成你站点的绝对链接 组合三自定义规则例如只允许以 / 开头的站内路径用UrlRelative::Custom传入一个判断函数返回Some(改写结果)保留、返回None删除文档里的示例src/lib.rs 的UrlRelative注释演示了如何识别绝对路径并加上统一前缀思路完全可以照搬。上手只需三步引入依赖在Cargo.toml中声明ammonia 4.1项目最低要求 Rust 1.80见 Cargo.toml配置 Builder按上文组合设置url_schemes与url_relative先净化后渲染所有外部 HTML 一律走clean()再入页想动手试试仓库自带了一个命令行小工具 examples/ammonia-cat.rs把 HTML 从标准输入读入、净化后输出到标准输出方便你用真实脏数据观察清洗效果。也可以先阅读 README.md 了解定位并对照 CHANGELOG.md 关注安全修复记录——例如 4.1.3 就修复了一个由 MathML 命名空间切换引发的 mXSS 问题生产环境请务必使用最新版本。常见误区与避坑清单❌ 以为默认配置就安全——默认协议名单含ftp/ssh/tel等且相对链接默认放行请显式收紧❌ 只在入口做一次净化之后又拼接了用户原始 HTML——净化结果才是唯一可信输出❌ 用正则替代解析器做预过滤——浏览器解析出的坑嵌套标签、异常命名空间正则是扫不全的Ammonia 的 html5ever 解析就是为此而生✅ 补充意识javascript:之外还要靠url_schemes一并挡掉data:、vbscript:等非浏览器协议它们是点击劫持和离线攻击的常客✅ 性能无忧构建 DOM → 过滤节点 → 重新序列化官方基准测试显示其速度约为 Python bleach 的 15 倍数据见 README.md 与 benchmarks/写在最后防御javascript:这类链接攻击本质上就是回答两个问题允许哪些协议相对链接怎么办Ammonia 用url_schemes白名单和UrlRelative策略把这两个问题变成了两行配置再配合 HTML5 标准解析带来的混淆免疫能力让净化不可信 HTML这件事对新手也足够友好。把本文的两道防线放进你的内容管线恶意链接就再也拖不垮你的站点了。【免费下载链接】ammoniaRepair and secure untrusted HTML项目地址: https://gitcode.com/gh_mirrors/am/ammonia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻