点击劫持和DOM代码注入类漏洞攻击方式与防御措施|软件安全测试技术系列

本系列文章分享JavaScript语言常见的安全漏洞,漏洞的原理,可能导致的安全问题,以及如何防御与避免。本文分享的是点击劫持和Client_DOM_Code_Injection这两类。

一、点击劫持(ClickJacking)

漏洞描述

点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。

点击劫持防御方式

1.X-Frame-Options HTTP响应头是用来给浏览器指示允许一个页面能否在`<frame>、<iframe>、<object>`中展现的标记,有三个可选的值

DENY:浏览器会拒绝当前页面加载任何frame页面(即使是相同域名的页面也不允许)

SAMEORIGIN:允许加载frame页面,但是frame页面的地址只能为同源域名下的页面

ALLOW-FROM:可以加载指定来源的frame页面(可以定义frame页面的地址)

2.禁止iframe的嵌套

if(window.top.location !== window.loaction){window.top.location === window.self.location}

二、Client_DOM_Code_Injection

风险

攻击者可以在应用程序服务器主机上运行任意代码。根据应用程序的操作系统权限,这可能包括:

o 访问数据库,例如读取或修改敏感数据;

o 文件操作(读/创建/修改/删除);

o 更改网站;

o 打开到攻击者服务器的网络连接;

o 使用应用程序的加密密钥解密秘密数据;

o 启动和停止系统服务;

o 完全控制服务器。

攻击者可使用社交工程技术(错误格式的链接或其他方式)说服受害者使用攻击者的代码。这将使攻击者能够控制用户使用 Web 应用程序的体验、劫持浏览器以更改显示的网页、加载网络钓鱼攻击以及执行任意脚本。

起因

许多现代编程语言都允许动态解析源代码指令。这使得程序员可以执行基于用户输入的动态指令。当程序员错误地认为由用户直接提供的指令仅会执行一些无害的操作时(如对当前的用户对象进行简单的计算或修改用户的状态),就会出现 code injection 漏洞。然而,若不经过适当的验证,用户指定的操作可能并不是程序员最初所期望的。

在这种情况下,浏览器会读取不受信任的代码,并在客户端执行。

通用建议

如何避免

· 应用程序不应编译、执行或评估任何外部源的任何不受信任的代码,包括用户输入、上传的文件或数据库。

· 如果确实需要在动态执行中包括外部 数据,则应将数据作为参数传递给代码,但不要直接执行用户数据。

· 如果需要将不受信任的数据传递给动态执行,请使用非常严格的数据验证。例如,仅接受某些值之间的整数。

· 验证所有来源的所有输入。验证应使用白名单:仅接受适合指定结构的数据,而不是拒绝不对的模式。参数应限制为允许的字符集,并且应丢弃未验证的输入。除字符外,检查:

数据类型

大小

范围

格式

预期值

· 尽量将已知的和可信任的输入列入白名单,而不是与黑名单进行比较。

· 将应用程序配置为使用没有不必要权限的受限用户帐户运行。

· 如果可能,应根据最小权限原则,隔离出所有动态执行,以使用单独的专用用户帐户,且该帐户只有动态执行使用的特定操作和文件的权限。

· 在客户端,不要使用任何形式的动态代码评估不受信任的数据。只有硬编码命令可以使用动态评估。

示例(不规范用法):

在这个经典的 code injection 实例中,应用程序可以实施一个基本的计算器,该计算器允许用户指定执行命令。
..

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();

ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps);

如果 operation 参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,result 变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,JavaScript 允许调用 Java 对象;如果攻击者计划将 "java.lang.Runtime.getRuntime().exec("shutdown -h now")" 指定为 operation 的值,则主机系统就会执行关机命令。

修复方案:

在任何时候,都应尽可能地避免解析动态代码。如果程序必须动态地解释代码,您可以通过以下方式将这种攻击获得成功的可能性降到最低:尽可能限制程序中动态执行的代码数量,将代码限制到基本编程语言的程序特定的和上下文特定的子集。程序绝对不能直接解析和执行未经验证的用户输入。而应采用间接方法:创建一份合法操作和数据对象列表,用户可以指定其中的内容,并且只能从中进行选择。利用这种方法,就绝不会直接执行由用户提供的输入。

示例(规范用法):

对js引擎方法执行的源代码指令添加白名单过滤

JavaScript

Dynamic evaluation of untrusted input

eval(location.hash);


Dynamically Invoking a Safe Function

window.setTimeout(hardcodedFunction(), 1000);

后续会继续为大家介绍JavaScript语言中,其他类型的安全漏洞,期待你的关注。

(谢绝转载,更多内容可查看我的专栏)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值