直接答案:25 个首页共 195 个外链脚本,0 个带 integrity、0 个带 crossorigin;同时有 154 段内联脚本(177.6 KB,23 站)、123 个内联事件属性(11 站)、79 个 javascript: 链接(15 站)、document.write 8 处(3 站)与 eval 3 处(1 站);2 站提供 noscript。上一期 CSP 的结论是 11/25 有策略、0 站真正限制脚本,本期的脚本写法正好解释了这一结果。运行时复核(390×844,观察 4 秒):8/25 站有错误——2 个未捕获 JS 异常(E03)、10 个资源 4xx/5xx(7 站)、1 个混合内容(E11);控制台 warning 30 条。
静态部分只统计 HTML 中的脚本标记与属性;另做一次 390×844 运行时观察(加载后 4 秒、不交互),见下文。
方法:只读 HTML 里的脚本标记
2026-11-09 05:40–05:41,对第 4 期 25 个缓存 200 首页实时请求 HTML,统计 <script src>、内联 <script> 块、onclick 等事件属性、href="javascript:"、document.write( 与 eval( 的出现次数,并检查外链脚本是否带 integrity 与 crossorigin。只读标记,不执行。
| 口径 | 判定 | 边界 |
|---|---|---|
| 外链脚本 | <script src> 且 src 非空 | 不判断是否成功加载 |
| integrity / crossorigin | 标签上出现对应属性 | 不校验证书或哈希是否有效 |
| 内联事件属性 | onclick、onload、onsubmit 等 25 类事件 | 不含 data-onclick 等自定义属性 |
| javascript: 链接 | <a href="javascript:"> | 不含按钮上的 JS 行为 |
| document.write / eval | 文本出现 document.write( / eval( | 字面匹配,可能含注释中的示例 |
结果:SRI 为 0,内联脚本遍及 23 站
| 指标 | 数量 | 站点数 |
|---|---|---|
| 外链脚本 | 195 | 25 |
| 带 integrity | 0 | 0 |
| 带 crossorigin | 0 | 0 |
| 内联脚本块 | 154 | 23 |
| 内联脚本体积 | 177.6 KB | — |
| 内联事件属性 | 123 | 11 |
| javascript: 链接 | 79 | 15 |
| document.write | 8 | 3 |
| eval | 3 | 1 |
| noscript | 2 | 2 |
问题集中在少数站:E17 一页 47 个内联事件属性、21 个 javascript: 链接;E13 有 22 个事件属性;E04 有 20 个事件属性、6 个 document.write 与 3 个 eval。内联脚本体积也有明显长尾:E24 38.3 KB、E02 17.5 KB、E18 14.7 KB,而中位每站约 3 KB。
与上一期 CSP 对照:CSP 页发现 11/25 有策略但 0 站真正限制脚本;本期的 154 段内联脚本与 123 个内联事件属性,正是“策略难以收紧”的写法基础。外链脚本 195 个全部没有 SRI,意味着第三方文件被替换时浏览器不会拒绝执行。
运行时复核:8/25 站有错误,E03 2 个未捕获异常
2026-11-09 23:40–23:44,用 headless Chrome 124 与 CDP 在 390×844 下重新打开同一批 25 个首页:等 readyState 为 complete 后再观察 4 秒,记录未捕获 JS 异常、控制台 error/warning、资源 4xx/5xx(排除 favicon)与混合内容。不滚动、不点击、不提交表单。
| 运行时指标 | 数量 | 站点 |
|---|---|---|
| 未捕获 JS 异常 | 2 | 1(E03) |
| 资源 4xx/5xx | 10 | 7 |
| 混合内容 | 1 | 1(E11) |
| 有任一错误 | 13 | 8 |
| 控制台 warning | 30 | 8(E20 20) |
8 个有错误的站是 E02、E03、E06、E11、E17、E23、E24、E29。E01 的 favicon 404 已按规则排除。错误不等同于用户可见故障:异常可能来自第三方或非关键脚本,图片 4xx 可能有备用图;但 E03 的 2 个未捕获异常、E11 的混合内容值得优先排查。
| 站点 | 错误 | 现场 |
|---|---|---|
| E03 | 2 | 2 个 Uncaught JS 异常(横幅/列表脚本) |
| E11 | 2 | 1 个混合内容脚本 + 1 个 404 样式表 |
| E17 | 2 | 2 个 403 媒体资源 |
| E29 | 2 | 2 个 404 图片 |
| E02 | 2 | 2 个 404 XHR |
| E06 | 1 | 1 个 403 XHR |
| E23 | 1 | 1 个 567 图片 |
| E24 | 1 | 1 个 404 图片 |
口径:只统计初始加载后 4 秒内的错误;favicon 404 排除;资源错误只算 Script/Stylesheet/XHR/Fetch/Document/Image/Font/Media;ERR_ABORTED 不计。控制台 warning 单列,不与错误相加。
对验收的启示
- 第三方脚本要带 SRI。 195 个外链脚本 0 个 integrity;至少对 CDN 上的库补上 integrity + crossorigin,并在升级时同步更新哈希。
- 把 javascript: 链接列为缺陷。 15 站 79 个;改成 button 或带 href 的链接,再绑定事件,键盘与新标签行为才正常。
- 用 addEventListener 取代内联事件。 11 站 123 个 onclick 等属性,既难审计也让 nonce/hash CSP 失效。
- 清理 document.write 与 eval。 8 处与 3 处,集中在少数站;替换为 DOM API 与显式解析。
- 内联脚本要有预算。 154 段、177.6 KB,无法跨页缓存;把可复用逻辑外链化,并给内联部分设体积上限。企业官网验收可参考网站建设服务。
局限
- 静态部分只读标记:运行后注入的脚本与事件不计;运行时观察另做一次 4 秒复核,但不滚动、不点击。
- 字面匹配:document.write 与 eval 可能命中的是注释或字符串中的示例。
- 不验证 SRI:只检查属性是否存在,不校验哈希是否与文件匹配。
- 单次抓取:页面可能因时间、AB 测试或登录态不同而变化。
- 运行时窗口:只观察加载后 4 秒;滚动、点击后的错误不计,favicon 404 已排除。
- 错误≠可见故障:第三方/非关键脚本异常或图片备用图可能不影响功能,需人工复核。
- 25 站 pilot:同一批装备企业样本,不外推行业。
数据与复算
运行时数据:equipment-homepage-runtime-errors-2026.csv(25 行 × 10 列:未捕获异常、资源错误、混合内容、warning 与时间)。仓库内为 docs/research/2026-11-homepage-runtime-errors.csv。
匿名数据:equipment-homepage-script-hygiene-2026.csv(25 行 × 13 列:外链/内联脚本、事件属性、javascript: 链接、SRI、document.write、eval 与时间)。仓库内为 docs/research/2026-11-homepage-script-hygiene.csv。
解析:scripts/script_hygiene_probe.py;单元测试 scripts/test_content_script_hygiene_probe.py(9 项,无网络)。运行:
python -m unittest scripts.test_content_script_hygiene_probe
配套:首页 CSP pilot(11/25 有策略、0 站限制脚本)、JS/CSS 资源注释审计、静态与渲染后语义对比。
数据来源与口径
- 样本:第 4 期 25 个缓存为 200 的首页。
- 抓取:2026-11-09 05:40–05:41 Asia/Shanghai,串行,站间 0.5 秒,超时 15 秒。
- 脚本:统计
<script src>、内联块与标签属性;不执行、不下载脚本文件。 - SRI:只检查 integrity / crossorigin 属性是否存在,不校验哈希。
常见问题
0 个 integrity 说明什么?
说明第三方脚本没有被 Subresource Integrity 锁定版本。CDN 或域名被篡改时,浏览器仍会执行被替换的脚本;本期 195 个外链脚本、0 个带 integrity,也没有一个带 crossorigin。
javascript: 链接不是还能用吗?
能用,但会阻断新标签打开、复制链接与部分键盘行为,也无法被 CSP 的脚本策略正常覆盖;本期 15 站共 79 个。
内联事件属性为什么单列?
onclick 等属性把行为写进 HTML,难以统一审计,也让基于 nonce/hash 的 CSP 更难落地;本期 11 站共 123 个。
document.write 与 eval 有多严重?
不是漏洞本身,但会拖慢解析、破坏流式渲染,并扩大注入的影响面。本期 document.write 8 处(3 站)、eval 3 处(1 站)。
内联脚本 177.6 KB 算多吗?
中位每站约 3 KB,但 E24 一页 38.3 KB、E02 17.5 KB、E18 14.7 KB;内联脚本无法被浏览器缓存复用,页面间会重复下载。
数据能复核吗?
可以。公开 CSV 25 行 × 13 列;scripts/script_hygiene_probe.py 有 9 项离线单测。
0 个 integrity 说明什么?
说明第三方脚本没有被 Subresource Integrity 锁定版本。CDN 或域名被篡改时,浏览器仍会执行被替换的脚本;本期 195 个外链脚本、0 个带 integrity,也没有一个带 crossorigin。
javascript: 链接不是还能用吗?
能用,但会阻断新标签打开、复制链接与部分键盘行为,也无法被 CSP 的脚本策略正常覆盖;本期 15 站共 79 个。
内联事件属性为什么单列?
onclick 等属性把行为写进 HTML,难以统一审计,也让基于 nonce/hash 的 CSP 更难落地;本期 11 站共 123 个。
document.write 与 eval 有多严重?
不是漏洞本身,但会拖慢解析、破坏流式渲染,并扩大注入的影响面。本期 document.write 8 处(3 站)、eval 3 处(1 站)。
内联脚本 177.6 KB 算多吗?
中位每站约 3 KB,但 E24 一页 38.3 KB、E02 17.5 KB、E18 14.7 KB;内联脚本无法被浏览器缓存复用,页面间会重复下载。
数据能复核吗?
可以。公开 CSV 25 行 × 13 列;scripts/script_hygiene_probe.py 有 9 项离线单测。
运行时错误一定影响用户吗?
不一定。未捕获异常可能来自第三方或非关键脚本,图片 4xx 也可能有备用图;但 E03 的 2 个未捕获异常、E11 的混合内容值得优先排查。观察窗口只有 4 秒且不交互,滚动、点击后才出现的错误不在本次范围内。