WebView security on iOS (PL)
-
Upload
lpilorz -
Category
Technology
-
view
152 -
download
0
description
Transcript of WebView security on iOS (PL)
Bezpieczeństwo WebView w systemie iOS
Łukasz Pilorz"!
Spotkanie OWASP Kraków, 29 stycznia 2014
Teoria
[webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString:@“http://example.com“] ] ];
!
- loadRequest: !
- loadHTMLString:baseURL: !
- loadData:MIMEType:textEncodingName:baseURL: !
- stringByEvaluatingJavaScriptFromString: !
- goBack !
- goForward !
- stopLoading !
- reload
!id<UIWebViewDelegate> delegate"!NSURLRequest request"!UIDataDetectorTypes dataDetectorTypes"!enum { UIDataDetectorTypePhoneNumber = 1 << 0, UIDataDetectorTypeLink = 1 << 1, UIDataDetectorTypeAddress = 1 << 2, UIDataDetectorTypeCalendarEvent = 1 << 3, UIDataDetectorTypeNone = 0, UIDataDetectorTypeAll = NSUIntegerMax } !… !https://developer.apple.com/library/ios/documentation/uikit/reference/UIWebView_Class/Reference/Reference.html
UIWebViewDelegate
– webView:shouldStartLoadWithRequest:navigationType:
– webViewDidStartLoad:
– webViewDidFinishLoad:
– webView:didFailLoadWithError:
Pytania:Jak odróżnić nawigację w głównym dokumencie od nawigacji w ramce?Jak zablokować wyświetlanie obrazków lub uruchomienie JavaScript?Czy po webViewDidStartLoad może nie nastąpić webViewDidFinishLoad?Czy przed webViewDidFinishLoad może nie nastąpić webViewDidStartLoad?
Ograniczenia• Brak Nitro
• Brak obsługi HTTP 401
• Brak opcji wyłączenia JavaScript
• [Dotyczy też Safari]Content-Disposition: attachment; filename=“download.html”Content-Type: text/plain- zgadnijcie, jak zachowa się UIWebView? (więcej informacji w CVE-2011-3426)
• Blokuje JavaScript podczas przewijania
• Ograniczona obsługa atrybutu target i window.open() ~ document.location.assign()
• Brak obsługi RSS
Praktyka
Zalety• Aktualizacja treści bez aktualizacji w App Store
• HTML5 + JavaScript + CSS
• Możliwość wykorzystania tego samego kodu na wielu platformach (+ Apache Cordova / PhoneGap)
• .html / .key / .numbers / .pages / .xls / .pdf / .ppt / .doc / .rftd.zip / .rtf
• Automatyczna weryfikacja certyfikatów SSL
• Automatyczne narzucenie zasad Same Origin Policy… w nietypowej wersji
Typowe zalecenia bezpieczników• “Ensure that all UIWebView calls do not execute without proper input validation. Apply filters
for dangerous JavaScript characters if possible, using a whitelist over blacklist character policy before rendering. If possible call mobile Safari instead of rending inside of UIWebView which has access to your application.” (OWASP Mobile Top 10)
• “[…] maintain control of all UIWebView content and pages, and prevent the user from accessing arbitrary, untrusted web content.” (OWASP iOS Developer Cheat Sheet)
• “Inspect remote content via the use of the NSData class method dataWithContentsOfURL in an attempt to prohibit the loading of malicious script into a UIWebview. Do not load content remotely and then process the data returned before passing to a UIWebview (if at all avoidable) otherwise you grant local file system access to any malicious script that smuggles itself past your content inspectors.” (MWR Labs blog)
• Hmmm… Brzmi groźnie :-)
UIWebView w aplikacjach iOS• Chrome
• Coast
• SkyDrive
• Skype
• WinZip
• i setki innych
Bezpieczny UIWebView - jak się do tego zabrać?
Wymagania:
• bez redukowania planowanej funkcjonalności
• bez poświęcania tygodni na budowanie filtrów treści (i kolejnych na utrzymanie i poprawki)
• tak, by zabezpieczenia wymagały małej ilości kodu
• skutecznie
Krok 1
Prawdopodobnie NIE, jeśli to mobilna bankowość: http://blog.ioactive.com/2014/01/personal-banking-apps-leak-info-
through.html (20 z 40 testowanych aplikacji bankowości elektronicznej dla iOS jest podatnych na XSS w UIWebView)
Czy w Twojej aplikacji potrzebny jest UIWebView?
TAK !
NIE
“Nie tych robotów szukamy.Możesz wracać do swoich zajęć.”
Krok 2Czy dokumenty, które zamierzasz wyświetlać,
muszą być wyświetlane w Twojej aplikacji?
TAK !
!
!
NIE !
Wykorzystaj Safari, Chrome (x-callback-url?)
lub inną przeglądarkę
Krok 3Czy dane prezentowane w UIWebView
są ładowane bezpośrednio przez HTTP?
TAK - loadRequest(…)
!
Wykorzystaj https:// !
Nie wyłączaj walidacjicertyfikatów SSL
NIE - dane przekazywane lub
modyfikowane lokalnie !
!
Pamiętaj, aby ustawić baseURL"
!
- loadRequest: !
- loadHTMLString:baseURL: !
- loadData:MIMEType:textEncodingName:baseURL: !
- stringByEvaluatingJavaScriptFromString: !
- goBack !
- goForward !
- stopLoading !
- reload
baseURL vs Same Origin Policy• file:/// ma uprawnienia do odczytu lokalnych plików i dowolnych
adresów URL (np. https://accounts.google.com) - niebezpieczne!
• nil/NULL == applewebdata:, uprawnienia jak file: - niebezpieczne!
• domyślnie UIWebView przyjmuje file:// (czyli @“test” == @“file://test”)
• dla http(s):// obowiązują standardowe zasady Same Origin Policy
• dla about: i data: również, bez kontekstu domeny
<script>a = document.location.href.split('/');if(a[0]==='file:') { path = ‘file:///'+a[3]+'/'+a[4]+'/'+a[5]+'/'+a[6]+'/'+a[7] +'/Library/Cookies/Cookies.binarycookies'; x = new XMLHttpRequest(); x.open('GET', path, false); x.send(); alert(x.responseText); }</script>
[webView loadHTMLString: [NSString stringWithContentsOfFile:@“/sciezka/do/pliku.html” encoding:NSUTF8StringEncoding error:&error] baseURL:[NSURL URLWithString:@“about:blank”]];
!
Potencjalny problem: obrazki, CSS itd. nie zostaną wczytane z file:///
Przykład: Chrome dla iOS
<!-- CVE-2012-2899 --> !
<script> function test() { pop = window.open('about:blank', '_blank'); pop.document.write( '<script>document.write(document.location)</scr' +'ipt><br><iframe src=“http://example.com/“' +'onload="alert(this.contentDocument.body.innerHTML)"></iframe>' ); } </script> <input type="button" onclick="test()" value=“Click">
Przykład: Coast by Opera
Krok 4Czy UIWebView będzie prezentował dokumenty,
nad których treścią masz kontrolę?
TAK - mam kontrolę nad treścią
!
Upewnij się, że wyświetlane dokumenty nie są podatne na XSS
(DOM-based!)
NIE - nie mam kontroli nad treścią
!
Upewnij się, że użytkownik może rozpoznać źródło pochodzenia
!
Zastosuj CSP lub HTML Sandbox
Interfejs użytkownika• wyraźne rozdzielenie zaufanej i niezaufanej treści
• pasek adresu z aktualnym URLwebView.request.mainDocumentURL.absoluteStringvs[webView stringByEvaluatingJavaScriptFromString:@"window.location.href"]
• wskaźnik SSL
• ostrzeżenie przed pierwszym wyświetleniem niezaufanego pliku
• inne pomysły?
Cross-Site Scripting
• Stored (po stronie serwera lub iOS)
• Reflected (uwaga na URL scheme handlers)
• DOM-based (!)
• [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerText='%@'", input]];
Cross-Site Scripting/JavaScript Injectioninput: ';alert(0)//🌙ꆁ
!
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerText='%@'", input]];
!
document.body.innerText='';alert(0)//🌙ꆁ'
- (NSString*) escapeForJavaScript:(NSString*)fromString { NSString *toString = @""; for(int i=0;i<fromString.length;i++) { toString = [NSString stringWithFormat:@“%@\\u%04X", toString, [fromString characterAtIndex:i] ]; } return toString; }
escapeForJavaScriptinput: ‘;alert(0)//🌙ꆁ !
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerText='%@'", [self escapeForJavaScript:input] ]];
document.body.innerText='\u0027\u003B\u0061\u006C\u0065\u0072\u0074\u0028\u0030\u0029\u002F\u002F\uD83C\uDF19\uA181'
innerHTML
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerHTML='%@'", [self escapeForJavaScript:input] ]]; !
Pytanie: dlaczego powyższy kod nie jest bezpieczny?
innerHTMLinput: <img src=x onerror=alert(0)> !
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.body.innerHTML='%@'", [self escapeForJavaScript:input] ]];
document.body.innerHTML='\u003C\u0069\u006D\u0067\u0020\u0073\u0072\u0063\u003D\u0078\u0020\u006F\u006E\u0065\u0072\u0072\u006F\u0072\u003D\u0061\u006C\u0065\u0072\u0074\u0028\u0030\u0029\u003E'
Krok 5Dodatkowe zabezpieczenia
Filtrowanie dopuszczonych URL !
http https data
about
Wyłączanie JavaScript!
Content-Security-Policy HTML5 Sandbox
!
Co może pójść nie tak?
[webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString:@“https://unknown.tld/untrusted.php“] ]];
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { NSMutableDictionary *mHeaders = [NSMutableDictionary dictionary]; NSString *CSP = @"default-src 'none'; img-src *;style-src 'unsafe-inline' *;child-src *;frame-src *;sandbox allow-forms allow-top-navigation"; for(id h in response.allHeaderFields) { if(![[h lowercaseString] isEqualToString:@"content-security-policy"] && ![[h lowercaseString] isEqualToString:@"x-webkit-csp"]) { [mHeaders setObject:response.allHeaderFields[h] forKey:h]; } } [mHeaders setObject:CSP forKey:@"Content-Security-Policy"]; [mHeaders setObject:CSP forKey:@"X-Webkit-CSP"]; NSHTTPURLResponse *mResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL statusCode:response.statusCode HTTPVersion:@"HTTP/1.1" headerFields:mHeaders ]; [self.client URLProtocol:self didReceiveResponse:mResponse cacheStoragePolicy:NSURLCacheStorageNotAllowed ]; }
?
//<UIWebViewDelegate>- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if([request.URL.scheme isEqualToString:@"http" || [request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme isEqualToString:@"about"] || [request.URL.scheme isEqualToString:@“data”]) { return YES; } return NO;}
Pytanie: Czy powyższy kod zablokuje odnośniki javascript:?
Krok 6O czym zapomnieliśmy?
Pentest
Cordova/PhoneGap !
i inne “mostki” Javascript/Objective-C
…
Linki(OWASP)
• https://www.owasp.org/index.php/IOS_Application_Security_Testing_Cheat_Sheet
• https://www.owasp.org/index.php/IOS_Developer_Cheat_Sheet
!
(iOS)
• http://www.apple.com/business/accelerator/develop/security.html & https://developer.apple.com/videos/wwdc/2010/
• http://stackoverflow.com/questions/3496505/differences-between-uiwebview-and-mobile-safari
!
(CSP)
• https://www.owasp.org/images/2/2b/Oxdef_csp_poland.pdf & http://niebezpiecznik.pl/OWASP2013-Krakow-CSP.pdf
• http://lists.w3.org/Archives/Public/public-webappsec/2012Mar/0043.html
http://browser-shredders.blogspot.com
Teaser: Breaking iOS browsers (before it will be cool ;-)