javascript iterator 本身不防篡改,仅按需返回数据;所谓“被篡改”实为遍历中底层数据动态变更导致业务逻辑错乱,常见于dom动态更新、proxy拦截next()、异步状态漂移三类安全风险场景。

JavaScript 中的 Iterator 本身不提供防篡改能力,它只是按需返回数据结构的成员;所谓“遍历器被篡改”并非 Iterator 对象自身被黑客修改,而是指遍历过程中底层数据被意外或恶意变更,导致业务逻辑错乱——这类问题在安全审计中常被忽略,却可能引发权限绕过、状态不一致、条件竞争等深层漏洞。
审计时重点关注三类“伪篡改”风险场景
DOM 集合动态更新未同步
比如用document.querySelectorAll('button')获取按钮列表后,再用for...of遍历并绑定事件,但页面后续通过innerHTML或框架响应式更新插入了新按钮。此时 Iterator 已完成遍历,新增按钮无事件监听,形成功能缺失或权限盲区。审计时要检查:是否假设 DOM 静态不变?是否遗漏对动态插入节点的二次处理?Proxy / Observable 对象拦截了 next() 行为
若目标代码使用了自定义迭代器(如Symbol.iterator返回一个 Proxy 包裹的生成器),攻击者可能通过污染原型或劫持next()方法,注入恶意逻辑(如跳过校验项、伪造返回值)。审计需识别非常规迭代器实现,检查return/throw是否被重写,以及done和value是否可控。异步遍历中状态漂移(Time-of-Check vs Time-of-Use)
典型如:先用Array.from(map.keys())获取键列表,再逐个调用map.get(key)处理——但若中间有其他代码map.set(key, newValue)或map.delete(key),就会读到过期或不存在的值。这不是 Iterator 报错,而是业务逻辑断链。审计应标记所有“先取集合快照、再逐个访问”的模式,并验证其原子性保障。
安全编码与审计建议
不依赖
for...of隐式迭代的安全性假设
明确写出const keys = Array.from(map.keys())或Array.from(set)获取不可变副本,避免直接for (const k of map.keys())——后者每次next()都实时查 map,状态不可控。禁止在迭代中触发副作用操作(尤其跨作用域)
如遍历用户权限列表时,同步调用fetch('/api/revoke', { body: JSON.stringify({id}) })。一旦网络延迟或失败,会导致部分权限撤销、部分未撤销,状态分裂。审计时标出所有遍历体内的异步 I/O 或全局状态修改。-
对关键业务集合启用防御性快照 + 校验
例如配置白名单数组:const safeList = Object.freeze([...config.allowedHosts]); for (const host of safeList) { if (!isValidDomain(host)) continue; // 每次仍做运行时校验 doSomething(host); }审计点:是否冻结原始集合?是否每轮都重校输入合法性?是否允许空字符串、通配符等模糊匹配?
deep-java-review下载Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
警惕
generator.next()的手动调用滥用
自定义生成器若暴露给不可信上下文(如插件系统、沙箱 eval),攻击者可反复调用next()跳过初始化逻辑或触发隐藏分支。审计需确认生成器是否封闭、yield是否含敏感状态、是否缺少调用次数限制。
JavaScript 的 Iterator 是中立机制,漏洞从来不出在 next() 函数本身,而出在开发者对“数据一致性”的错误假设里。审计真正要揪住的,是那些没写出来的前提条件。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










