I'm building an iOS app for a company whose website currently makes use of an embedded webpage for login/account creation. This embedded webpage handles some cryptographic logic that is complex to replicate. On the web, they restrict what external webpages can load the embedded webpage by checking the origin, so that only whitelisted domains can load it (e.g. third party company's webpages).
Ultimately they want to make a native version of this login for mobile, but for v1 are considering just embedding the webpage to avoid rushing the API/client side encryption. But they would need the same ability to restrict where it can be embedded.
Is it possible to get the bundle id/app id of the mobile app requesting the page, in a way that can't be modified programmatically e.g. I can't just add a header, because any app could just add the same header. I'm also looking to avoid hardcoding any credentials in the source code.
Youtube has a similar functionality to what i'm looking for, giving the option to restrict video embedding by bundle id. But says its currently not available to iOS apps: https://support.google.com/youtube/answer/6301625?hl=en
However tools like google's OAuth dashboard, require inputting the iOS apps bundle id when setting up an app. Which makes me think it is possible. But experimenting with Charles proxy and WKWebView or SFSafariViewController didn't result in it being sent up by the system. Is there anyway for a website, either through initial load or redirects etc, to get the bundle-id in a safe way?
Related
I'm not sure there is a "proper" way, but before I just bodge together my own incompatible implementation, perhaps there's something in all the standards that can fit my need?
Here's the situation: Apple has declared that apps on their phones MUST include all standard functionality inside themselves. No more iframes with web content! If you need to show stuff from web, open the system browser (Safari)! Unfortunately we need to display stuff from web, so here we go...
Now, the app requires authentication which the user has done previously. We store whatever tokens we need. When the time comes to open the browser, we don't want to force the user to re-authenticate. We need to somehow pass the access credentials to the browser, and preferably do this securely. Furthermore, the webpage in the browser will need a token obtained from our OpenID Connect server.
Unfortunately, the only point of communication between the app and the browser is the URL, so everything that we give will be there, in plain sight. I know that OAuth was pretty worried about this, so much so that they made it impossible to intercept authentication with just the stuff visible on the screen and instead using things like single-use intermediary codes, backchannels and PKCE.
Unfortunately I cannot see any way to use the default flows "out of the box" to achieve what I need. I can think of modifications to those flows that would do it, but I'm not a security expert so I'd rather go with something standard which is vetted by experts.
SCENARIO
It's a good question since many companies want to show existing web content in a secured manner within a mobile app, and to avoid an extra login.
WEB + MOBILE INTEGRATED SOLUTION VIA DISCONNECTED BROWSER?
Ideally what you want to do is pass the mobile app's JWT to the external web content in an HTTP header. iOS APIs such as openURL may not support this however.
You may have to pass a JWT in a query string, in which case I would try to follow a signed request model, though it is not trivial. I have used SalesForce signed requests though not implemented a full solution myself.
Mobile app calls an API method at POST /api/encrypt-token
API returns an encrypted payload that includes the JWT
Mobile app opens a web page at https://mywebapp?token=0a78904cwdu
Web UI calls POST /api/decrypt-token to get the JWT
Web UI stores the token in memory and uses it to call the API
You will want to prevent raw tokens being written to web server logs.
I believe the recommendation for this type pf solution is to use a one time key, as described in the above link. And of course the web session will have some limitations such as silent token renewal not working.
WEB + MOBILE INTEGRATED SOLUTION VIA WKWEBVIEW
In the past I've managed secured web content in a mobile app by making the Web UI get access tokens from the mobile app. This enables an integrated UX and you can use a 'standard as possible' OAuth solution.
When the Web UI runs within a mobile app's web views it no longer does its own OAuth handling and instead calls the mobile app to get tokens and trigger logins
This means there is a single login across web and mobile views, and the Web View gets all the benefits of mobile user experience, such as secure storage of tokens
The Web UI is no longer impacted by things like the web view aggressively dropping cookies
VALID USE OF WEB VIEWS?
Web views are probably not a good long term solution in most cases. I know that Apple are likely to reject apps in 2020 if they use any of these behaviours:
Use of UIWebView - the Cordova default - you need to update to WKWebView
Delivering an app that is solely a repackaged web site with no mobile views
Displaying web content of a dubious nature (ads etc)
I suspect that use of WKWebView used responsibly and justifiably would be accepted. I could be wrong though, so please don't take my word for it.
ONLINE SAMPLES
I will be documenting some stuff about mobile / web integration on my OAuth blog, including code samples.
We can send a link to someone formatted as okta:// and it will launch the Okta mobile app, but I would like to know if there is a way to deep link to a specific app in Okta mobile?
Something like okta://appname
or better yet would be okta://appname/specificpageinapp
I have tried all sorts of options, but none seem to work.
The Okta Mobile app doesn't support deep linking as you described.
You may be able to deep-link directly into native iOS applications using a similar URL Scheme (exampleapp://page/example). If the native iOS app is integrated with Okta, this might work as you expect.
However, it sounds like what you might actually want to do is link directly into the embedded web view of a web application in Okta. If that is the case, I suggest reaching out to Okta support with a feature request and the use case that you're trying to solve, so that it can get the attention of the product manager for the Okta Mobile app.
So, now twitter from 25 sep supports universal linking, it means that when UIWebView hits https://twitter.com/oauth/authorize?oauth_token link, it tries to open a twitter app, and if it is there, then it redirects me to auth page with auth error, so I wonder, how can I disable it from code, without uninstalling twitter app, or how I can enable universal linking auth in my xamarin ios app? Is it possible at all?
(similar question but for native: Disable Twitter Universal Deep Links)
Unless Twitter removes/updates the apps section of "https://www.twitter.com/apple-app-site-association" to allow a bypass or a secondary oauth that is not in the apple-app-site-association file I do not see how you would do it. These files are signed and iOS handles them at an OS level.
I have not played around very much with the continueUserActivity delegate and the NSUserActivity object that is passed to apps launched from UNI links, but I do not see a way for the launched app (i.e. Twitter) to return control to the original app, and at that point the oauth call-chain would be broken anyway....
Unique. Unlike custom URL schemes, universal links can’t be claimed by other apps, because they use standard HTTP or HTTPS links to your website.
Secure. When users install your app, iOS checks a file that you’ve uploaded to your web server to make sure that your website allows your app to open URLs on its behalf. Only you can create and upload this file, so the association of your website with your app is secure.
Via: https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html
I would like to play videos inside an IOS web view with Cordova.
Videos must be available only inside this app.
I don't have any domain to restrict access, because it's a web view inside a native app.
Is there a way to use HTTPS with Javascript to authenticate with an API token, then play each video with this token?
Can anyone provide a specific script example to do the job?
It is not possible to do this in such a way that someone could not break it because an attacker could install a man-in-the-middle server with a certificate created using their own certificate authority and then sniff the data and use it outside the application.
However you could make it more difficult, by creating "single use" keys that you send to the device using the notification service every time a key is used, you invalidate it and create a new key for the next use. This would mean that someone trying to get around the system would find it very difficult to have more than one client using the content at any given time.
Given that that is the best you can do, why not simply have users authenticate themselves and not allow multiple sessions to be active for the same user?
The documentation at https://developers.google.com/console/help/new/#generatingdevkeys states that:
Create and use an iOS key if your application runs on iOS devices. Google verifies that each request originates from an iOS application that matches one of the bundle identifiers you specify. An app's .plist file contains its bundle identifier. Example: com.example.MyApp
Does this mean that the google APIs (server-side) somehow verify/ensure that only my app can use this key? Or, does it just mean that the iOS libraries that google provides will do a sanity check before accepting the api-key? Is there anything to prevent a malicious user from decompiling my iOS app and re-using this api-key within his own app (making direct HTTP calls without using google iOS libraries)?
Extending this to the api-key used in browsers - the only protection seems to be the Referer check against a whitelist of domains. Is there anything stopping a malicious app developer from taking my api-key from the browser and using it within his native app (which sets a fraudulent Referer header)?
So basicly you are correct the api key is mendetory because only you/your app should have access. But the fact is that everyone with your api key is can have access. And the play store has a big issue with not hidden api keys
http://www.cnet.com/news/thousands-of-secret-keys-found-in-android-apps/
for the second question I have no Idea sorry