UXSS vulnerability in UIWebView in IOS and its repair methods
IOS developers often use UIWebView. Most of the time, they load external addresses, but sometimes they are used to load local html files.
UIWebView follows the "same source" policy when loading external addresses, while the "same source" policy is enough when loading local webpages, resulting in access to any path of the system.
This is the UXSS vulnerability in UIWebView. Apps that have not fixed this vulnerability are known to include: Micro disks, file almighty Wang, and QQ reading.
The vulnerability recurrence method is similar. The current microdisk is used as an example:
Edit a webpage on PC and name it test.html. The content is as follows:
<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>
Send the file to the mobile phone end, click the file you just sent on the mobile phone end, select another application to open it, and select "micro disk" in the pop-up Application List ", at this time, you will go to the micro-disk interface and click the upload button. After the upload is complete, click the file you just uploaded in my micro-disk file list, in this case, an alert box is displayed, showing the path of the current file. Click "OK", and the system account and password information (that is, the passwd file content) will be displayed ).
As follows:
Solution
<1> disable opening HTML files from the outside (cut off the attack entry)
<2> restrict the permissions of scripts in the local HTML file. (Preliminary Prevention Measures)
<3> A new NSURLProtocol is added to process the loading of local webpages and securely load local files based on same-origin policies. (Complete solution)
The preceding two solutions are relatively simple and will not be described here.
Here we will talk about the third solution,
We know that in IOS, the processing of various protocols (http, https, ftp, and file) is implemented through NSURLProtocol,
Each method corresponds to an NSURLProtocol. There are several important methods:
+ (BOOL) registerClass :( Class) protocolClass
Register NSURLProtocol,
+ (Void) unregisterClass :( Class) protocolClass
Anti-register NSURLProtocol
+ (BOOL) canInitWithRequest :( NSURLRequest *) request
Indicates whether the NSURLProtocol processing logic is used. If YES is returned, the NSURLProtocol is used. If NO, the NSURLProtocol does not run,
-(Void) startLoading
This method is called by the system to start loading requests. We only need to make network data requests within this method.
-(Void) stopLoading
This method is called by the system to stop loading requests. You only need to cancel the request within this method.
We create a new class derived from NSURLProtocol and name it SeMobSandBoxFileProtocol.
In AppDelegateApplication :( UIApplication *) application didfinishlaunchingwitexceptions :( NSDictionary *) launchOptionsCalling in callback
[NSURLProtocol registerClass: [SeMobSandBoxFileProtocol class]; // register our protocol
SeMobSandBoxFileProtocol. h and SeMobSandBoxFileProtocol. m are as follows:
#import
@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]; // obtain the path of the primary resource: nsange sharpRange = [baseString rangeOfString: @ "#"]; if (sharpRange. length) {baseString = [baseString substringToIndex: sharpRange. location]; // path filtering and removal of # And # Content} if ([baseURL isFileURL]) {BOOL OK =! [[Url absoluteString] lowercaseString] hasPrefix: baseString]; // determines whether the Sub-resource path contains the primary resource path prefix 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
Code Analysis
The general idea is to determine whether the parent-child directory relationship is based on the file paths of the primary and sub-resources. If so, access to sub-resources is allowed; otherwise, access to sub-resources is not allowed, in this way, the sub-resource is blocked from accessing directories other than the corresponding directories of the primary resource. To determine whether the Sub-resource is a parent sub-directory relationship, it is determined based on whether the directory prefix is included. Therefore, the path needs to be filtered, filter the content after # In the path together.