How to set App Transport Security in Appcelerator - titanium

I am trying to configure App Transport security, but I am always getting a response from Security Scan that it is not properly configured. I am using Appcelerator SDK 7.0.1 for iOS.
Scan result:
App Transport Security
App Transport Security (ATS), which is a networking security feature that ensures network connections employ the most secure protocols and ciphers, was found to be misconfigured.
NSAllowsArbitraryLoads set YES
This is a part of my tiapp.xml
<property name="ios.whitelist.appcelerator.com" type="bool">false</property>
<ios>
<enable-launch-screen-storyboard>true</enable-launch-screen-storyboard>
<use-app-thinning>true</use-app-thinning>
<plist>
<dict>
<key>UISupportedInterfaceOrientations~iphone</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIRequiresPersistentWiFi</key>
<false/>
<key>UIPrerenderedIcon</key>
<false/>
<key>UIStatusBarHidden</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
</ios>
It is done as specified in documentation:
http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network
What am I doing wrong? Thanks in advance for help.

Setting NSAllowsArbitraryLoads to true disables ATS, meaning that all URL's will be allowed and no restriction is configured. This is how it is configured by default in Titanium, to ensure backwards compatibility for apps upgrading to newer SDK versions. It can be overridden to either specify allowed domains (whitelisting) or by disabling NSAllowsArbitraryLoads.
The docs are still incorrect as Nirman pointed, so I just updated them (as I couldn't find the pull request mentioned earlier).

We need to set NSAllowsArbitraryLoads key to NO to enable ATS and get rid of the security warning.
I think the documentation is wrong. I have submitted a CR on github to update the doc page.

Related

react-native0.44, i am use fetch request "http", but network request failed?

i'm from official find fetch only support https, but now, i use Mock data, the url is http, official said if support http must change info.plist, add NSAppTransportSecurity and NSAllowsArbitraryLoads, below the image:
i add App Transport Security Settings and children row Allow Arbitrary Loads,
the request http not support! please ask how to resolve support Mock http request in react-native ? Thanks!
i use Mock is Alibaba "Rap" Mock address, it's only support Mock http request!
Info.plist will take effect after recompiling your app.
Probably you need to recompile your app by rerun react-native run-ios or rerun from Xcode.
You should not use NSAllowsArbitraryLoads must be set to false.
Instead you should add an exception to your domain.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Right now you are exposing your device to vunerabilities.
Checkout this post

Can't fetch or make XHR request to http URL in React Native (but https and http://localhost work fine)

I tried to make a request to the remote server in React Native, but always get TypeError: Network request failed; I tried different URL, and found that if I make a request to some http URL like http://rap2api.taobao.org/app/mock/3008/GET/api/creations, it always failed;
if I make a request to some https URL like https://facebook.github.io/react-native/movies.json, it works;
if I make a request to a http localhost URL like http://localhost:3002/list, it also works.
componentDidMount() {
console.log("_fetchData");
this._fetchData()
}
_fetchData = () => {
fetch('http://rap2api.taobao.org/app/mock/3008/GET/api/creations')
.then((response) => response.json())
.then((responseJson) => {
console.log('responseJson',responseJson)
})
.catch((error) => {
console.error(error);
});
}
I checked many references online and guess it's something about the setting in Info.plist doc. I tried to do some modification like:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>rap2api.taobao.org</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
or
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
However, neither of them works, I still get the same error when making requesting to http URL. I am sure the API is fine since I tried it on a web application and get the response successfully. What's the problem?
From https://facebook.github.io/react-native/docs/network.html:
By default, iOS will block any request that's not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with http) you will first need to add an App Transport Security exception. If you know ahead of time what domains you will need access to, it is more secure to add exceptions just for those domains; if the domains are not known until runtime you can disable ATS completely. Note however that from January 2017, Apple's App Store review will require reasonable justification for disabling ATS. See Apple's documentation for more information.
and from https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33
Starting in iOS 10.0 and later and in macOS 10.12 and later, the following subkeys are supported:
NSAllowsArbitraryLoadsForMedia
NSAllowsArbitraryLoadsInWebContent
NSRequiresCertificateTransparency
NSAllowsLocalNetworking
Note: There are two “allows arbitrary loads” keys and they employ different naming patterns. Take care to use …ForMedia and …InWebContent correctly.
You might try explicitly setting NSAllowsArbitraryLoadsForMedia and NSAllowsArbitraryLoadsInWebContent.
Also be sure to clean and rebuild your project in Xcode so that your updated plist settings are included in your package.

No solution for Transport Security?

I have tried all the methods of here for solving the problem of: "Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file."
But if I try for example adding this in my plist file:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>www.myserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
I get an error:"Unsupported URL", where in this case my link, looks like this:
let url:NSURL = NSURL(string: "www.myserver.com/jsonsignup.php")
But if I would use:
let url:NSURL = NSURL(string: "http://www.myserver.com/jsonsignup.php")
I would get the same error of Transport Security as mentioned above.
Any help?
I had the same issue. I tried adding it to info.plist but it did not work for me either. So I tried this and it worked.
Click on your project name in the "Project Navigator" then click on info. And add it there. See highlighted.
Before I tried selecting the plist from my project navigator under supporting files and for some reason it did not work. The above should work for you.
Note: This will allow all connections.
Are you using http://request ? then add following code in your .plist file.
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
I hope it's work for you.

How to use self signed (unpinned) certificate (SSL) with AFNetworking 2.6 and Swift 2.0 [duplicate]

I installed Xcode 7 and tried running my app under iOS 9.
I'm getting the infamous error: Connection failed! Error - -1200 An SSL error has occurred and a secure connection to the server cannot be made.
The thing is my server DOES support TLSv1.2 and I'm using NSURLSession.
What could be the problem then?
Apple has released the full requirements list for the App Transport Security.
Turned out that we were working with TLS v1.2 but were missing some of the other requirements.
Here's the full check list:
TLS requires at least version 1.2.
Connection ciphers are limited to those that provide forward secrecy (see below for the list of ciphers.)
The service requires a certificate using at least a SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256bit or greater Elliptic-Curve (ECC) key.
Invalid certificates result in a hard failure and no connection.
The accepted ciphers are:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
In iOS9, Apple added new feature called App Transport Security(ATS).
ATS enforces best practices during network calls, including the use of HTTPS.
Apple Pre-release documentation:
ATS prevents accidental disclosure, provides secure default behavior,
and is easy to adopt. You should adopt ATS as soon as possible,
regardless of whether you’re creating a new app or updating an
existing one.
If you’re developing a new app, you should use HTTPS exclusively. If
you have an existing app, you should use HTTPS as much as you can
right now, and create a plan for migrating the rest of your app as
soon as possible.
Add Below key in your info.plist & then see.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Even you can add specific exception,
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>testdomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<false/>
<key>NSExceptionAllowInsecureHTTPSLoads</key>
<false/>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSThirdPartyExceptionAllowInsecureHTTPSLoads</key>
<false/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSRequiresCertificateTransparency</key>
<false/>
</dict>
...
</dict>
</dict>
Check out this doc that apple provided.
I had a similar issue at runtime on iOS 9 and what I did to fix it was added the NSAppTransportSecurity Dictionary to my info.plist file with the NSAllowsArbitraryLoads Bool set to true and after cleaning and rebuilding it worked.
I hope this helps!
For me proxy was blocking try to use internet from different source will resolve issue.
Wifi, Lan, etc.
With iOS9, I had a same issue:
while SSLlab result showed no issues with protocols / ciphers on my server, a connection to one specific URL failed on an iPad running iOS/9.3.5 with an SSL-Error:
Connection cannot be established.
My stupid mistake was, that I had a redirect, i.e. in NGINX (and similar in Apache):
rewrite /calendar $scheme://www.example.org/resources/calendar;
If the user accessed /calender by setting:
https://example.org/calendar
the server redirected to another domain breaking the establishment of the SSL-connection.
Setting the redirect as follows fixed it:
rewrite /calendar $scheme://$server_name/resources/calendar;

iOS 9 app download from Amazon S3 SSL error: TLS 1.2 support

I get
An SSL error has occurred and a secure connection to the server cannot
be made.
on iOS 9 if I try to download a file from amazon s3:
https://s3.amazonaws.com/xyz/qer/IMG_0001.JPG
From what I understand Amazon s3 supports TLS 1.2
see: https://forums.aws.amazon.com/thread.jspa?threadID=192512
S3 and Kinesis support TLS 1.2 at this time.
"S3 and Kinesis support TLS 1.2 at this time." Aug 23, 2015 9:19 PM
Not sure then why do I get this SSL error. The account should be configured to take advantage of TLS 1.2?
I would've guessed that this should be 'on' by default.
I don't want to put this domain on the info plist.
EDIT:
I ended up using
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>s3.amazonaws.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Edit 2016-01-03: The renewed certificate for s3.amazonaws.com uses the SHA256 algorithm and complies with ATS requirements.
Original answer: s3.amazonaws.com uses a SHA1 cerificate that does not meet ATS requirements, resulting in a hard failure. Per the App Transport Security Technote, ATS in iOS9 has the following requirements:
The server must support at least Transport Layer Security (TLS) protocol version 1.2.
Connection ciphers are limited to those that provide forward secrecy, namely,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Certificates must be signed using a SHA256 or better signature hash algorithm, with either a 2048 bit or greater RSA key or a 256 bit or greater Elliptic-Curve (ECC) key.
Invalid certificates result in a hard failure and no connection.
SSL Labs' SSL server test (https://www.ssllabs.com/ssltest/analyze.html?d=s3.amazonaws.com) includes a handshake simulation for ATS in iOS 9 that indicates a failure for s3.amazonaws.com.
You need two things to have iOS 9 app successfully reaching SSL endpoint (S3 is just an example):
Forward Secrecy (https://www.wikiwand.com/en/Forward_secrecy) enabled on the server.
This feature is currently not supported by AWS S3. The workaround for that is that you can configure AWS CloudFront service (which supports FS) in front of your S3 bucket.
Set up is fairly easy. If you're using CORS, please keep in mind that proper headers need to be passed through the CloudFront proxy.
SHA-256 protected SSL certificate on the server.
Once you'll have your files available via Cloudfront, when hitting URL (https://somethinghashed1234wasdfawer421.cloudfront.net) you'll notice that the SSL certificate over there uses SHA-1. How bad...
The solution for that is to protect this with your private, SHA-256 SSL cert. To do that you need to specify CNAME for Cloudfront endpoint in your domain. This will allow you to secure the bucket with your own SSL certificate. Simply configure your DNS to have entry pointing cloudfront-bucket.mydomain.com to that ugly somethinghashed1234wasdfawer421.cloudfront.net. Upload your SSL cert to amazon and set SSL protection in Cloudfront distribution settings. Voila!
All things mentioned are easily clickable from AWS console (apart from uploading SSL cert, which needs to be done via AWS CLI).
Since S3 is not currently fully compliant, according to this post on the AWS blog, their official recommendation is to exclude S3 from App Transport Security by adding this set of keys to your Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>amazonaws.com.cn</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
UPDATE 10/27/15: As Pol points out in the comments, even though this is an official answer from AWS, an Apple Engineer in the support forums says this is actually a bug:
It turns out that the fact that NSExceptionRequiresForwardSecrecy relaxes the SHA-2/256 requirement is a bug; the intended behaviour of NSExceptionRequiresForwardSecrecy is the behaviour documented in the App Transport Security Technote, namely that it should just enable specific cypher suites.
Our plan is to fix this bug at some point in the future. We expect to fix this in some compatible fashion, so folks who’ve mistakenly used NSExceptionRequiresForwardSecrecy to disable the SHA-2/256 requirement won’t break. However, predicting the future is always a challenge.
Which brings us to what you should do right now. [A previous version of this post gave less concrete advice. The following is an update that tightens things up.] After discussing this with ATS Engineering our recommendations are:
If you're using a specific hosting service, you should consult your hosting service to get the latest advice.
In situations like this, where the server is fully compatible with ATS except for the SHA-2/256 certificate signing requirement, we recommend that you accurately document that state of affairs by using NSExceptionAllowsInsecureHTTPLoads.
You should attempt to make your server fully compatible with ATS as soon as possible.
When that happens, you should update your app with the more secure ATS settings.
I should stress that NSExceptionAllowsInsecureHTTPLoads isn't actually insecure. It's just as secure as your app currently is when it's running on iOS 8. Rather, it means that your app doesn't benefit from the extra security provided by ATS.
Share and Enjoy
Emphasis mine. Note that the current plan is to fix the bug in a way that will not break the behavior for people who have used NSExceptionRequiresForwardSecrecy to solve this issue, so the above is still a viable answer.
Just posting to point out that the issue with amazon's certificates are they use SHA-1 and the app transport security requires SHA-2/256.
The fact that NSExceptionRequiresForwardSecrecy works is a bug documented here at apple dev forums. According to the documentation and an Apple engineer in the linked thread a "better" solution would be
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>s3.amazonaws.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
I use the term "better" very loosely and only mean a solution that does not exercise a bug that Apple will eventually fix. Now this is a fix for the certificate issue only :)
Until Amazon gets their head out of their *ss on this one, as #Zsolt suggested insert the following keys and value in your plist file.
BUT be sure to set the NSExceptionDomain to amazonaws.com instead of s3.amazonaws.com, depending on how your assets are served and from which region amazon may serve them such as this s3-us-west-1.amazonaws.com, so not explicitly setting the subdomain will allow assets to be properly served from any AWS region identifier.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>