iPhone UIWebView intercept HTTP calls to redirect through proxy - iphone

I'm trying to hook UIWebView so that when a user enters a url, they are re-directed through our proxy and prompted for authentication.
I'm essentially needing to take the request and add proxy information to the request and pass it over to a UIWebView.
The proxy has to be controlled by the iOS application and not by safari or read from system wide credentials.
I've tried using ASIHTTPRequest to create a request to route through a known proxy with NTLM authentication, that works fine however doesn't bring back css, javascript, images etc.
I then read about and used ASIWebPageRequest however that is currently a bit unstable, doesn't stream and waits for the whole HTML site to download before rendering it to the user.
Can anyone point me in the right direction?

Are you allowed to change the content of the pages so that they point directly to your proxy? That might work.
Personally I'm very curious if there is any other way to do this without rewriting URLs (basically w/ only client side changes). If you found a solution please let me know1

Related

ATS policy issue when using a redirect url in Swift

I am using this link for example to load the link. Although the link is a http link it will be redirected to a https link. It works in the browser.
However, as soon as I let my iOS Application load the resource it will say "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.".
I am using this library to load the picture. Is it not supported that Swift loads the https resource? I could think of that ATS blocks the connection to the server so the redirect can't even be received.
I would be very thankful for any thoughts on this.
Christian
While you certainly can disable the entirety of ATS using the solutions provided by Kishan and Johnson, if you know the domain of the http resource you are trying to load, you have better options. For details of why the disabling of ATS entirely is not the best idea, see this post.
Better options are:
If you know the http resource is always going to give you a redirect to the same https:// url, why not simply use the https:// url in your code. This won't work if the redirect is dynamic, but if your code is trying to load http://www.example.com/resource and that always redirects to https://www.example.com/resource, why not just change your code to go to the https version.
Only disable ATS for the domain in where you need to allow non https connections. This allows you to only allow http connections for domains you know don't support https, better protecting your application users.
Your ATS settings in your info.plist wqould look something like this:
If and only if your urls are driven by data that you don't control (i.e. the domains in those urls could be anything), you will need to disable all of ATS, and Apple may eventually want you to provide justification for disabling it. Originally they were going to have all ATS disabled apps go through an additional justification request processs, but they haven't mentioned that recently. This should be a last resort.
Honestly, looking at your example UR
Go to info.plist add a term called App Transport Security Settings.
And under that add Allow Arbitrary Loads

Secure communication between Web site and backend

I am currently implementing a Facebook Chat Extension which basically is just a web page displayed in a browser provided by the Facebook Messenger app. This web page communicates with a corporate backend over a REST API (implemented with Python/Flask). Communication is done via HTTPS.
My question: How to secure the communication the Web page and the backend in the sense that the backend cannot be accessed by any clients that we do not control?
I am new to the topic, and would like to avoid making beginners' mistakes or add too complicated protocols to our tech stack.
Short answer: You cant. Everything can be faked by i.e. curl and some scripting.
Slightly longer:
You can make it harder. Non browser clients have to implement everything you do to authenticate your app (like client side certificates and Signet requests) forcing them to reverse engineer every obfuscation you do.
The low hanging fruit is to use CORS and set the Access Allow Origin Header to your domain. Browsers will respect your setting and wont allow requests to your api (they do an options request to determine that.)
But then again a non official client could just use a proxy.
You can't be 100% sure that the given header data from the client is true. It's more about honesty and less about security. ("It's a feature - not a bug.")
Rather think about what could happen if someone uses your API in a malicious way (DDoS or data leak)? And how would he use it? There are probably patterns to recognize an attacker (like an unusual amount of requests).
After you analyzed this situation, you can find more information here about the right approach to secure your API: https://www.incapsula.com/blog/best-practices-for-securing-your-api.html

Use RequestBuilder without sending cookies

Assume I have a gwt app on a large website which sets a lot of cookies, and that I'm not in control of which cookies get set. Assume further that my gwt app makes a number of REST calls to a lightweight API within the same domain (as indeed one must do) using RequestBuilder.
RequestBuilder reasonably enough makes an HTTP request to the server, and sends all the cookies it has received. The problem with this is that the cookies themselves sometimes take over 90% of the request size.
Yes, it would be nice if the web site did not set so many cookies, but assume this is unfixable. No, deleting the cookies from the browser is not an option (it's fine if they are totally inaccessible to / hidden from the gwt application, for instance if I could somehow persuade the gwt app to use a separate empty cookie jar).
How do I persuade RequestBuilder not to send any cookies?
Note solving this for XmlHttpRequest and wrapping it up in GWT code would be fine.
Things I found that might be useful (in general for JS and not for GWT, but GWT ultimately uses XmlHttpRequest):
Cookie Monster: An observer that steals the cookies from XmlHttpRequest before the request is sent. I think this might be Firefox specific, and it seems a bit like hard work.
yourXMLHttpReq.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS;: this would be pretty much perfect, save it requires surgery to get it into GWT and I think its Firefox specific.
This question, which handles Chrome extensions, the answer to which is to either remove and readd all the cookies (does not work for a long-running app), or use an incognito window (I want this to only affect the REST API call).
RequestBuilder delegates to Javascript's XMLHttpRequest, which will always send cookies. You have two options.
Use a different subdomain for your REST endpoints that cookies haven't been set for
Temporarily remove all cookies during the request, and restore them afterwards

iPhone and UIWebView: Force HTTPS (rewrite URLs on the fly)

I have a web based application that uses Cocoa/CocoaTouch's UIWebView. I want (need?) to force all HTTP connections to HTTPS. Note that I am interested in forcing the initial, landing URL to HTTPS and all the intermediate fetches to HTTPS also. Motivation: New Tricks for Defeating SSL in Practice and sslstrip.
Is it possible to configure WebView to only use HTTPS? The UIWebView documentation does not even mention HTTPS. Considering Apple does not allow me to disable JavaScript in a UIWebView, I doubt I can make the configuration change on the view.
Or does the answer lie somewhere in NSURLRequest, NSURLConnection, and possibly delegate methods? I read URL Loading System Overview, and I don't see where I am able to change requests.
If you want to change the request you can proxy UIWebView so all requests are intercepted and then replace http with https, and make the request from the proxy. One way of doing this would be to subclass NSURLCache and override the method cachedResponseForRequest.

How can pass the user name / password to iOS external browser for authentication?

Greeting everyone, may I ask your help for following question?
I'm using following code to call external browser in my current iPhone apps:
[[UIApplication sharedApplication] openURL:urls];
urls = "http://myhost.net/home.aspx"
Assume user is already logged in to the apps,
I can to pass the user name password to "home.aspx" if security is not a concern...
e.g. urls = "http://myhost.net/home.aspx?username=xxx&password=123456"
Question 1: Can I pass some information to home.aspx by "post" instead of "get" method?
Question 2
If above solution is not possible, I would like to set basic authentication in IIS 7.
When the external browser called by apps, can users access to "home.aspx" without 2nd login? (e.g. use code to bypass it)
For Q2, here is my current situation for your reference:
1) I have video steaming service provided by Windows IIS, when user type the URL from browser, the login form will prompt. a. e.g. xxxx/video.htm b. The IIS is configured with SSL and basic authentication
2) After user login succeed, the video should be properly displayed in the HTML 5 page.
3) We have the iPad/iPhone apps will open the external browser (i.e. Safari) to see the video page, but I don't know how can by pass the authentication (i.e. user should not see login form) if user already logged in the app within 15 mins.
Many thanks for your attention.
Re: August
About question 2, "[[UIApplication sharedApplication] openURL:urls];"
In theory you can do it for non-video streaming hyperlinks, but there are no solution or workaround for video streaming in similar passthough scenario.
Please also see:
Stream MP4 Video From Seek Position in ASP.NET
Both handler or REST web service require header handling but that might be product limitation because no existing APIs work for it.
Hope this helps.
As far as your question is concern, you can only pass variables to a web url if and only if you a Web Service like REST or SOAP installed on your local or remote server. You can search for Web Service API's for ASP.net that suits your need. From there, you can authenticate any variables by setting the response in every request. You can start with this.
On the other end (in the iphone), you can't just use your code above to send request, this can be done using the native iOS url connection but I do recommend to use libraries like RESTKit or probably ASIHTTPRequest. Both handle requests like get, post, delete and update.