iOS developers often use UIWebView, most of the time to load external addresses, but sometimes they can also be used to load local HTML files.
UIWebView load the external address when the "same-origin" policy followed, while loading the local Web page is enough to bypass the "same-origin" policy, resulting in access to any path of the system.
This is the UXSS vulnerability that exists in UIWebView. The app that is known to have not fixed the vulnerability is: micro-disk, file almighty King, QQ reading.
The vulnerability is reproduced in roughly the same way, now the micro disk as an example:
Edit a webpage on your PC and name it test.html. The contents are 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>
Through the file sent to the mobile phone side, click on the mobile phone just sent over the file, choose to open with other applications, in the app list to select the "micro-disk", this time will go into the micro-disk interface, click the Upload button, upload finished, in my micro-disk file list Click the file you just uploaded, This time the alert box will pop up showing the path of the current file, click "OK", then the system account and password information (i.e. the contents of the passwd file) will be displayed.
As follows:
Remediation Scenarios
<1> disable opening of HTML files from outside; (Cut off attack entry)
<2> some permission restrictions for scripts in local HTML files (preliminary precautions)
<3> added a nsurlprotocol to handle the loading of local Web pages and securely load local files according to the same Origin policy. (A thorough solution)
The previous two options are relatively simple and are not mentioned here.
Here we talk about the third kind of program,
We know that the processing of various protocols (HTTP,HTTPS, FTP, file) in iOS is done through Nsurlprotocol,
Each of these corresponds to a nsurlprotocol, and there are several important methods:
+ (BOOL) RegisterClass: (Class) Protocolclass
Register Nsurlprotocol,
+ (void) Unregisterclass: (Class) Protocolclass
Anti-registration Nsurlprotocol
+ (BOOL) Caninitwithrequest: (Nsurlrequest *) request
Indicates whether to go the processing logic of the Nsurlprotocol, return yes, mean go, no means not to go,
-(void) startloading
Represents the start of a load request, which is called by the system, and we only need to do a network data request inside the method to
-(void) stoploading
Represents a stop load request, which is called by the system, and we only need to do some cancellation requests inside the method
We create a new class derived from Nsurlprotocol, which is named Semobsandboxfileprotocol
Application in Appdelegate : (uiapplication *) application didfinishlaunchingwithoptions: (NSDictionary *) called in the launchoptions callback
[Nsurlprotocol Registerclass:[semobsandboxfileprotocol class]]; Sign up for our agreement
The contents of SeMobSandBoxFileProtocol.h and SEMOBSANDBOXFILEPROTOCOL.M are as follows:
#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]; Get the path of the main resource nsrange sharprange=[basestring rangeofstring:@ "#"]; if (sharprange.length) {basestring=[basestring substringToIndex:sharpRange.location]; Path filtering processing, minus the # and the contents after the # # if ([BaseURL Isfileurl]) {BOOL ok=![ [[url absolutestring] lowercasestring] hasprefix:basestring]; Determines whether the child 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" Co De:kcfurlerrorunknown userinfo:@{@ "Nserrorfailingurlkey": Self.request.URL}];} + (Nsurlrequest *) Canonicalrequestforrequest: (Nsurlrequest *) request {return request;} @end
Code Analysis
The general idea is to determine whether they are parent-child directory relationships based on the file path of the master and sub-resources, and if so, to allow access to the child resources, otherwise it is not allowed, which prevents the child resources from accessing directories other than the directory of the primary resource, since it is judged by whether or not the directory prefix is included. So we need to filter the path and filter out the contents of the # after the # number in the path along with #.
UIWebView UXSS Vulnerability in iOS and how to fix it