WKWebView not loads http image in iOS 10 and above - ios

I am loading a https URL in WKWebView and inside that few images are coming from HTTP URL which is loading perfectly fine on enabling NSAllowsArbitraryLoads in info.plist file in iOS 9. But on iOS 10 and above it is not loading the HTTP images. I read Apple and followed all possible way but no luck.

Add the below line in info.plist,
NSAllowsArbitraryLoadsInWebContent
and set its value as YES

Allowing Insecure Connection to a Single Server
fetching media from an insecure server use below
NSAppTransportSecurity
NSExceptionDomains
"media-server.example.com"
NSExceptionAllowsInsecureHTTPLoads = YES
Apple warnings
Important: Before implementing this exception, consider that a
seemingly-benign network request can cause security problems of the
sort that ATS is intended to mitigate. For example, fetching media
from an insecure server entails the following risks, among others: An
attacker can see the media file a user is accessing Your app’s attack
surface expands, for example, by allowing a bad actor to feed your app
a malicious file intended to trigger a buffer overrun Avoid this
connection type if possible.
The App Transport Security (ATS) keys are:
NSAllowsArbitraryLoads
NSAllowsArbitraryLoadsForMedia
NSAllowsArbitraryLoadsInWebContent
NSExceptionAllowsInsecureHTTPLoads
NSExceptionMinimumTLSVersion
You can get more info from NSAppTransportSecurity

Related

WKWebView XMLHttpRequest fails with custom url scheme

I'm building a mobile app using WKWebView. I register custom url schemes image:// and thumb:// to serve assets from the native part to the web part of the app.
webViewConfiguration.setURLSchemeHandler(handler, forURLScheme: "image")
webViewConfiguration.setURLSchemeHandler(handler, forURLScheme: "thumb")
This approach works well if urls with a custom scheme are used in HTML. For example, <img src="thumb://watermarkly.com/1.jpg" /> works properly - WKWebView invokes my handler and displays the result. However, WKWebView blocks requests if I try to fetch these urls using XMLHttpRequest:
[Warning] The page at https://watermarkly.com/app/watermark/ was allowed to display insecure content from thumb://watermarkly.com/1.jpg.
[Warning] [blocked] The page at https://watermarkly.com/app/watermark/ was not allowed to display insecure content from image://watermarkly.com/1.jpg.
[Error] Not allowed to request resource
[Error] XMLHttpRequest cannot load image://watermarkly.com/1.jpg due to access control checks.
The only difference here is that "thumb:" url was assigned to an img tag, while "image:" url were fetched via XMLHttpRequest. Unfortunately, no other info provided in Safari Developer Tools.
The problem appears on a real devices only - everything works properly in iOS Simulator.
Is there something I need to configure to make it work for XMLHttpRequests as well?
Update
We switched from HTTPS to HTTP to make XHR to solve the problem.
Unfortunately, custom url schemes seems not to work on some iPhones. We have 5 customers with iPhones where nor switching to HTTP, nor sending Access-Control-Allow-Origin header help. We weren't able to identify which setting causes the issue - the problem cannot be reproduced on any of devices we have. Apple reviewer didn't have any complaints as well. Nor XHR, not getting images through urls work on these phones. One of the customers has two phones. Custom url schemes work on one of them and they don't work on the second one at all. He says they are identical and there is no Safari extensions installed. Unfortunately, we weren't able to identify what causes the problem. Beware custom url schemes may not work on some phones.

iOS: SSL error - page not loading in WKWebView but loads in Safari

In the app I'm working on, I need to handle 3-D Secure redirects from our payment service provider. These redirects point to a web page of the card issuer that is shown in a WKWebView to the user in the app.
This works all the time except one case where the WKWebView doesn't load for https://3dsecure.csas.cz/ and fails with the following error:
Error Domain=NSURLErrorDomain
Code=-1200
"An SSL error has occurred and a secure connection to the server cannot be made."
What's interesting is that the same URL loads with no problems in Safari or in SFSafariViewController. Even the server's certificate is okay:
I've tried to play around with NSAppTransportSecurity settings in app's Info.plist file, specifically enable NSAllowsArbitraryLoadsInWebContent and NSAllowsArbitraryLoads but it does have no effect.
Forward Secrecy
It turns out that the server for 3dsecure.csas.cz does not support Forward Secrecy: https://www.ssllabs.com/ssltest/analyze.html?d=3dsecure.csas.cz&s=194.50.240.77
Perfect forward secrecy is required by App Transport Security in iOS9 and above for all app connections, including webviews (not including Safari, however)
ATS Debugging
Running the following command in Terminal runs ATS diagnostics and tells more about the problem and how to solve it:
/usr/bin/nscurl --ats-diagnostics --verbose https://3dsecure.csas.cz
ATS Exception in the app
Allowing the webview in the app to connect to a specific server that does not support forward secrecy could be done by adding the following in the Info.plist file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>3dsecure.csas.cz</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Not future-proof
This exception needs to be added for every single domain that does not support forward secrecy. Unfortunately, It's impossible to know all the 3-d secure servers in advance as they come as redirects from the payment provider.
What I don't know is if not requiring forward secrecy could be set for any domain, globally, and just within a specific webview, without affecting the whole app.

App Transport Security blocking with "Allow Arbitrary Loads = YES"

I'm trying to access my Python CGI script running on an instance in Amazon EC2 though a POST request but even though I have changed my Info.plist file to allow arbitrary loads it shows:
Here's where I make the POST request:
let manager = AFHTTPRequestOperationManager()
let URL = "http://ec2-XX-XX.compute-1.amazonaws.com/cgi-bin/hellopy2.py"
let params = ["userToken": "XXXXXXXXXXX"]
manager.POST(URL, parameters: params, success: { (operation, responseObject) -> Void in
Here is my info.plist file:
Make sure you have the right Info.plist file
First, make sure that the Info.plist that you put those settings in is the one your project is using. You can verify this by going into your project settings and searching for Info.plist. Make sure that the Info.plist file where you set those values is the one for the build target you are building.
You can also verify after the fact if you build your project to an IPA. Unzip the IPA, and in the folder that is unzipped, you should see an Info.plist file. Verify that your ATS settings are in that file to make sure the running app should use those exceptions.
Get the settings correct / consistent
Once you've verified this, you should clean up your settings. You use the global flag for allowing any insecure traffic. That will work for now, but after the end of 2016, you won't be able to submit to the store without providing Apple a justification and facing possible rejection. I would recommend not using it at this point, unless this is an app that won't be distributed through the app store (e.g. an enterprise app). If you do choose to use this flag, remove the exception domains, as they are unneeded (you are basically saying all domains are exceptions and allow http).
If you want to do it correctly, by only allowing insecure connections to amazonaws, your settings should simply look like this:
If you have those settings, and your Info.plist configuration is correct, you should be able to access any amazonaws.com subdomains without https.
"http://" is not part of the domain name.
Remove the "http://" from the domain name in your Info.plist file.
*You don't need to set the global "Allow Arbitrary Loads" key to "Yes" for this to work.

CFNetwork SSLHandshake failed (-9806) only on 3G/4G (Not on Wifi)

I understand this question has been asked in a similar vein a couple of times, but this error is only occurring on a 3G/4G connection, and not on a wifi connection.
I've also added the appropriate NSExceptionDomains and keys to my info.plist file, as many other answers on here have suggested, and this error does not seem to go away.
I have:
NSTemporaryExceptionAllowsInsecureHTTPLoads = YES
NSThirdPartyExceptionRequiresForwardSecrecy = NO
NSTemporaryExceptionMinimumTLSVersion = 1.0
NSIncludesSubdomains = YES
I am trying to make HTTPS requests to an Amazon EC2 instance (Linux).
Finally fixed the problem. Turns out I was missing a "www" in front of the URL I was trying to access. The SSL certificate was registered with the "www" in the domain name, and this inconsistency was throwing an error.
This might also explain why the error only occurs on mobile data, but I'm not too clear on the specifics so maybe someone else can explain that.

NSData cannot retrive image from internet anymore [duplicate]

This question already has answers here:
How do I load an HTTP URL with App Transport Security enabled in iOS 9? [duplicate]
(8 answers)
Closed 7 years ago.
The following code works fine before iOS8.4.1 (includ 8.4.1). While it ruturns nil in iOS9.0.1. Is it a bug or there is a public annoucement for this change? I tested with two iPads.
let url = NSURL(string: "http://www.mapshots.com/wp-content/uploads/2014/05/mapshots-ag-studio-agricultural-mapping-software-logo.png")
let data = NSData(contentsOfURL: url!)
NSLog("Data length #%", (data?.length)!)
This is an issue related to ATS(App Transport Security Protocol) changes made by Apple in iOS 9. By default iOS9 disregard communication with http protocol. Your URL should be https. However you can include exception for specific domains in your app or you can allow all http communication to be allowed from within your app.
Check the Documentation for full details.
To Allow all http domains from your application, you should add
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But as Apple has recommended these new settings, you should chose to add exception for this specific domain in your app rather than allowing all http domains. Check this thread to achieve this.
With iOS 9 you can't call an HTTP anymore because the ATS (App Transport Security) calls should be HTTPS. To work with HTTP links, you should insert the following key in the info.plist file to disable the ATS:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
create a new voice in the info.plist file "NSAppTransportSecurity" like dict.
insert in it the key "NSAllowsArbitraryLoads" like boolean and set to YES
;-)

Resources