Actionfunction执行的时候跳过表单验证。

参考文章 https://developer.salesforce.com/forums/ForumsMain?id=906F0000000977HIAQ

场景重现

我在“协会级别”picklist上添加了onchange事件,当onchange事件执行的时候,身份证号和协会任职上的验证便会起作用,导致onchange事件不能正常执行。

解决方法

在actionfunction中加入 immediate

<apex:actionFunction status="counterStatus" name="renderField" action="{!renderField}" immediate='true' rerender="editButtons">
  <apex:param name="fieldToShow" value=""/>
  </apex:actionFunction>


<think>我们正在讨论JavaScript原型链污染漏洞,特别是如何利用它来绕过身份验证机制。根据引用[2],存在一个场景:除了特定路由(如/static、/login、/register)外,其他路由都需要通过auth函数进行身份验证。攻击者通过原型链污染可以跳过auth的302跳转,然后通过表单提交用户名和密码,进而可能触发XSS攻击。 原型链污染漏洞的核心在于:JavaScript对象具有原型链继承的特性。如果攻击者能够修改一个对象的原型(例如Object.prototype),那么所有继承自该原型的对象都会受到影响。这可能导致应用程序的安全机制被破坏。 引用[2]提到,在robot.py中,机器人会打开本地页面的首页/,然后通过原型链污染绕过auth的302跳转。接下来,机器人会根据表单的name填写用户名和密码并提交。因此,我们需要构造一个原型链污染,使得在访问需要身份验证的路由时,auth函数被绕过。 ### 原型链污染漏洞的原理 在JavaScript中,每个对象都有一个原型(prototype)对象。当我们访问一个对象的属性时,如果该对象自身没有这个属性,就会沿着原型链向上查找,直到找到该属性或到达原型链的末端(null)。如果攻击者能够修改原型对象(例如Object.prototype)的属性,那么所有对象都会继承这个属性,除非它们自身已经拥有该属性。 例如: ```javascript let obj1 = {}; let obj2 = {}; // 正常情况下,obj1和obj2都没有toString属性,它们继承自Object.prototype console.log(obj1.toString); // [Function: toString] // 如果我们污染Object.prototype Object.prototype.foo = 'bar'; console.log(obj1.foo); // 'bar' console.log(obj2.foo); // 'bar' ``` ### 利用原型链污染绕过身份验证 假设在应用程序中,身份验证函数`auth`会检查请求对象(例如`req`)中是否包含某个认证属性(比如`req.authenticated`)。如果该属性为`true`,则允许访问;否则,重定向到登录页面(302跳转)。 正常情况下,未登录用户的`req`对象没有`authenticated`属性,因此会触发重定向。但如果攻击者能够污染`Object.prototype`,使其包含一个`authenticated`属性,并且该属性值为`true`,那么所有对象(包括`req`)都会继承这个属性,从而绕过身份验证。 攻击步骤可能如下: 1. 找到一个可以污染原型链的漏洞点。通常,这发生在应用程序使用不安全的递归合并、对象复制或属性赋值时,这些操作允许攻击者控制对象的属性名,并且属性名中包含`__proto__`或`constructor`等关键字。 2. 通过发送恶意请求,将`Object.prototype`的`authenticated`属性设置为`true`。 ```javascript // 恶意请求的载荷可能如下(例如通过JSON或表单提交) { "__proto__": { "authenticated": true } } ``` 或者在某些情况下,使用点符号的键名(如`"__proto__.authenticated": true`)也可能达到效果,具体取决于服务器如何解析请求。 3. 一旦污染成功,后续所有请求的`req`对象都会继承`authenticated: true`,从而绕过身份验证。 ### 实际利用示例 根据引用[2],攻击者首先需要触发原型链污染漏洞。假设应用程序存在一个接受JSON对象的接口,并且在处理该对象时进行了不安全的合并操作: ```javascript function merge(target, source) { for (let key in source) { if (typeof source[key] === 'object' && source[key] !== null) { if (!target[key]) { target[key] = {}; } merge(target[key], source[key]); } else { target[key] = source[key]; } } } // 假设从请求体获取的userInput是攻击者可控的 let obj = {}; merge(obj, userInput); ``` 如果攻击者提交的`userInput`为: ```json { "__proto__": { "authenticated": true } } ``` 那么,在合并过程中,`Object.prototype`会被添加一个属性`authenticated: true`。之后,每个对象(包括后续请求的`req`对象)都会具有这个属性,从而绕过身份验证。 ### 如何防范 1. 避免使用不安全的递归合并函数。在合并对象时,检查属性名是否为`__proto__`、`constructor`或`prototype`等敏感属性名,并跳过这些属性。 2. 使用`Object.create(null)`创建没有原型的对象,这样就不会继承`Object.prototype`的属性。 3. 冻结`Object.prototype`,使其不可扩展(但可能影响其他功能): ```javascript Object.freeze(Object.prototype); ``` 4. 在身份验证逻辑中,不要依赖对象上可能被继承的属性。应该使用`hasOwnProperty`来检查属性是否直接存在于对象上: ```javascript if (req.hasOwnProperty('authenticated') && req.authenticated) { // 通过认证 } else { // 重定向到登录 } ``` 注意:即使这样,如果攻击者能够直接给`req`对象添加`authenticated`属性(而不仅仅是原型链污染),那么仍然可能被绕过。因此,确保设置认证属性的过程是安全的。 ### 相关问题 1. 除了绕过身份验证,原型链污染还可能引发哪些安全问题? 2. 在实际应用中,如何检测和修复原型链污染漏洞? 3. 如何利用原型链污染漏洞来执行XSS攻击? 以上内容基于引用[2]提供的场景,并参考了原型链污染的一般原理。请在实际安全测试中遵循合法和道德准则。</think>### JavaScript 原型链污染漏洞利用与身份验证绕过 #### 漏洞原理 原型链污染(Prototype Pollution)是 JavaScript 特有的安全漏洞,源于 JavaScript 的原型继承机制。攻击者通过修改对象的原型(`__proto__` 或 `prototype` 属性),污染所有继承该原型的对象,从而影响整个应用的行为[^2]。 #### 利用步骤绕过身份验证 根据引用[2]的场景(需要绕过 `/login` 和 `/register` 之外的路由验证): 1. **污染原型链** 通过恶意载荷修改 `Object.prototype`,注入伪造的认证属性: ```javascript // 恶意请求示例(JSON 载荷) { "__proto__": { "authenticated": true, "isAdmin": true } } ``` 成功污染后,所有对象都会继承这些属性,包括服务器用于验证的 `req` 对象。 2. **绕过身份验证中间件** 假设身份验证逻辑如下: ```javascript // 原身份验证中间件 function auth(req, res, next) { if (req.session.authenticated) { // 检查是否认证 next(); // 通过验证 } else { res.redirect(302, "/login"); // 未认证则跳转 } } ``` 原型污染后,`req.session.authenticated` 会继承 `Object.prototype.authenticated=true`,直接绕过验证[^2]。 3. **配合 XSS 完成攻击** 如引用[2]所述,污染后可进一步利用表单提交触发 XSS: ```javascript // 自动提交恶意表单 document.write(` <form name="exploit" action="/admin" method="POST"> <input name="payload" value="<img src=x onerror=alert(document.cookie)>"> </form> <script>document.exploit.submit()</script> `); ``` #### 防御措施 1. **输入过滤** 禁止 `__proto__`、`constructor`、`prototype` 等关键属性: ```javascript function sanitize(obj) { Object.keys(obj).forEach(key => { if (key.includes("__proto__") || key === "constructor") delete obj[key]; }); } ``` 2. **使用无原型对象** 对敏感数据使用 `Object.create(null)` 创建无原型的对象: ```javascript const safeObj = Object.create(null); // 无原型链 safeObj.userInput = userData; // 不受原型污染影响 ``` 3. **冻结原型**(谨慎使用): ```javascript Object.freeze(Object.prototype); Object.freeze(Object); ``` 4. **身份验证增强** 使用 `hasOwnProperty` 严格检查属性归属: ```javascript function auth(req) { if (req.session.hasOwnProperty("authenticated")) { // 仅检查自有属性 // 安全逻辑 } } ``` ### 相关问题 1. 如何检测应用中的原型链污染漏洞? 2. 除了身份验证绕过,原型链污染还能导致哪些安全风险?[^1] 3. 如何结合 CSRF Token 和原型链污染防御实现双重安全保障?[^3] 4. 在 Node.js 后端开发中,哪些常用库容易引发原型链污染? [^1]: 原型链污染可导致点击劫持、权限提升等风险,需配合输入验证防御 [^2]: 通过污染 Object.prototype 注入 authenticated 属性可绕过 auth 中间件 [^3]: CSRF Token 可防御跨站请求,但需注意 XSS 漏洞会使其失效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值