IOS中UIWebView的UXSS漏洞及修复方法

做IOS开发的同学经常用到UIWebView,大多时候是加载外部地址,但是有一些时候也会用来加载本地的html文件。

UIWebView加载外部地址的时候遵循了“同源”策略,而加载本地网页的时候却绕够了“同源”策略,导致可以访问系统任意路径。

这就是UIWebView中存在的UXSS漏洞。已知尚未修复该漏洞的App有:微盘、文件全能王、QQ阅读。

漏洞复现方式大体相似,现在微盘为例:

在PC上编辑一个网页,命名为test.html. 内容如下:

<script>
alert(document.location);
var aim='file:///private/etc/passwd';
var d=document;
function doAttack()
{
    var xhr1= new XMLHttpRequest();
    xhr1.overrideMimeType('text/plain; charset=iso-8859-1');
    xhr1.open('GET',aim);
    xhr1.onreadystatechange = function()
    {
       if(xhr1.readyState ==4)
       {
       	  var txt=xhr1.responseText;
       	  alert(txt);
       }
    };
    xhr1.send();
}
doAttack();
</script>

通过文件发送到微信手机端,在微信手机端点击刚才发过来的文件,选择用其他应用打开,在弹出来的应用列表里选择“微盘”,这个时候会进入微盘界面,点击上传按钮,上传完毕后,在我的微盘文件列表中点击刚才上传的文件,这个时候会弹出一个alert框显示当前文件所在路径,点击“好”,接着就会显示系统账户和密码信息(也就是passwd文件的内容)。

效果图如下:

修复方案

<1>禁用从外部打开HTML文件;(切断攻击入口)

<2>针对本地HTML文件中脚本做一些权限限制;(初步防范措施)

<3>新增一个NSURLProtocol, 专门用来处理本地网页的加载,根据同源策略来安全地加载本地文件。(彻底的解决方案)

前面两种方案相对简单一些,这里不赘述。

这里主要讲讲第三种方案,

我们知道IOS中对于各种协议(http,https, ftp, file)的处理都是通过NSURLProtocol来实现的,

每一种对应了一个NSURLProtocol,有以下几个重要的方法:

+ (BOOL)registerClass:(Class)protocolClass

注册NSURLProtocol,

+ (void)unregisterClass:(Class)protocolClass

反注册NSURLProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

表示是否走该NSURLProtocol的处理逻辑,返回YES,表示走,NO 表示不走,

- (void)startLoading

表示开始加载请求,由系统调用该方法,我们只需在该方法内部做网络数据请求就可以

- (void)stopLoading

表示停止加载请求,由系统调用该方法,我们只需在该方法内部做一些取消请求操作

我们新建一个类派生自NSURLProtocol, 暂且命名为SeMobSandBoxFileProtocol

在AppDelegate的application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions回调中调用

[NSURLProtocol registerClass:[SeMobSandBoxFileProtocol class]];  //注册我们的协议

SeMobSandBoxFileProtocol.h、SeMobSandBoxFileProtocol.m内容分别如下:

#import <Foundation/Foundation.h>

@interface SeMobSandBoxFileProtocol : NSURLProtocol

@end
#import "SeMobSandBoxFileProtocol.h"

@implementation SeMobSandBoxFileProtocol

+ (NSArray *)supportedScheme
{
    return [NSArray arrayWithObjects:@"file", nil];
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    NSURL* url=[request URL];
    NSUInteger index = [[self supportedScheme] indexOfObject:[url scheme]];
    if (index!=NSNotFound)
    {
        NSURL* baseURL=[[request mainDocumentURL] URLByDeletingLastPathComponent];
        NSString* baseString=[[baseURL absoluteString] lowercaseString];           //得到主资源的路径
        NSRange sharpRange=[baseString rangeOfString:@"#"];
        if (sharpRange.length) {
            baseString=[baseString substringToIndex:sharpRange.location];          //路径过滤处理,去掉#号以及#号后面的内容
        }
        if([baseURL isFileURL]) {
            BOOL ok=![[[url absoluteString] lowercaseString] hasPrefix:baseString];  //判断子资源路径是否包含主资源路径前缀
            return ok;
        }
        else
        {
            return baseString.length>0;
        }
    }
    return NO;
}

- (void)stopLoading
{

}

-(void)startLoading
{
    [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:@"CFNetwork" code:kCFURLErrorUnknown userInfo:@{@"NSErrorFailingURLKey":self.request.URL}]];
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}
@end

代码分析

总体思路是根据主资源与子资源的文件路径判断它们是不是父子目录关系,如果是的话,就允许访问子资源,否则就不允许,这样就阻止了子资源访问主资源对应目录以外的目录,因为判断是否为父子目录关系,是根据是否包含目录前缀来判断的,所以需要对路径进行过滤处理,把路径中#号后面的内容连同#一起过滤掉。

时间: 2024-10-03 10:37:43

IOS中UIWebView的UXSS漏洞及修复方法的相关文章

iOS中UIWebView的使用详解

iOS中UIWebView的使用详解 一.初始化与三种加载方式 UIWebView继承与UIView,因此,其初始化方法和一般的view一样,通过alloc和init进行初始化,其加载数据的方式有三种: 第一种: - (void)loadRequest:(NSURLRequest *)request; 这是加载网页最常用的一种方式,通过一个网页URL来进行加载,这个URL可以是远程的也可以是本地的,例如我加载百度的主页:     UIWebView * view = [[UIWebView al

iOS中UIWebView执行JS代码(UIWebView)

iOS中UIWebView执行JS代码(UIWebView) 有时候iOS开发过程中使用 UIWebView 经常需要加载网页,但是网页中有很多明显的标记让人一眼就能看出来是加载的网页,而我们又不想被人卡出来. 如网页中的这个导航 通常我们不需要WebView中的 导航栏,也不需要里面的返回上一级的交互.. 对WebView常用的另外一种功能就是对某个点击添加对用function实现JS调用OC的交互功能. 下面一一介绍: 1. UIWebView 调用JS代码 OC调用JS通常是,在webVi

IOS中UIWebView和JavaScript交互(转自http://blog.2jun.net/2012/11/02/webviewandjs/)

IOS中UIWebView和JavaScript交互 当程序中使用到UIWebView控件的时候,难免会遇到需要与页面进行交互的情况.这种情况在android平台下比较容易处理,android平台下WebView控件的addJavascriptInterface()方法可以很轻松的完成交互,而IOS上就稍复杂一些. 页面与客户端的交互是通过JS来完成的,通常情况下与JS的交互可以分为两种:客户端传递给JS一些数据和JS向客户端请求一些本地操作.下面分别对这两种情况进行处理. JS向客户端请求本地

Windows Server中的IIS漏洞以及修复方法

Windows Server中的IIS漏洞以及修复方法 我可以有把握地说,对于Windows服务器管理员来说普遍的目标是拥有适当弹性的系统.世界上有很多网络安全威胁,你最不希望发生的是在世界的另一头,或者在你的组织内部有人利用了IIS或者Windows的漏洞,而这一切都是本来可以避免的. 你可能无法触及应用层面的漏洞,但是在服务器层面你有很多事情可以做到使基于IIS的系统更加安全.通过回顾我多年的网站安全评估项目,可以指出以下最影响Windows服务器的IIS漏洞. 未处理异常(HTTP 500

验证码的三个常见漏洞和修复方法

把验证码存储在Cookie中 一般来说,我们会把验证码的值用Session存储起来,通过对比用户提交的验证码和Session中的验证码,就可以知道输入是否正确.由于Session会占用服务器资源,我曾经想过是否可以把验证码的值加密后存储在Cookie中.不过事实证明,这只是异想天开罢了. 假设验证码的值是a,通过sha1加密后得到的值为b = sha1(a),并且把b存储在Cookie中.而用户提交的验证码值为c,通过判断sha1(c)是否与b相等,可以知道输入的验证码是否正确.然而,Cooki

iOS中常用的四种数据持久化方法简介

iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults standardUserDefaults]就够用了 @interface User : NSObject <NSCoding>@property (nonatomic, assign) NSInteger userID;@property (nonatomic,

让ios中MKMapView的定位点不居中的方法

让ios中MKMapView的定位点不居中的方法 by 伍雪颖 构造一个coordinate: CLLocationCoordinate2D centerCoordanate; centerCoordanate.latitude = [userLocation coordinate].latitude - 0.0037; centerCoordanate.longitude = [userLocation coordinate].longitude; MKCoordinateRegion reg

iOS中UIWebView使用JS交互

iOS中偶尔也会用到webview来显示一些内容,比如新闻,或者一段介绍.但是用的不多,现在来教大家怎么使用js跟webview进行交互. 这里就拿点击图片获取图片路径为例: 1.测试页面html <!doctype html> <html> <head> </head> <body> <div> <img src="test.png"/> </div> </body> <

iOS中UIWebView使用JS交互 - 机智的新手

iOS中偶尔也会用到webview来显示一些内容,比如新闻,或者一段介绍.但是用的不多,现在来教大家怎么使用js跟webview进行交互. 这里就拿点击图片获取图片路径为例: 1.测试页面html <!doctype html> <html> <head> </head> <body> <div> <img src="test.png"/> </div> </body> <