I have developed an iOS app using Xamarin and I am unsure about how encryption would work when calling a service that uses HTTPS.
On my end I do nothing particularly special: I utilize a RestClient and add the credentials to the body of a json serialized request. I then post it to the HTTPS service.
Is this safe or should I be doing more? I am not sure if iOS handles the rest for me in terms of encryption.
Answer
Yes, by using HTTPS, you are most-likely safe. However, there are a couple things to verify to ensure that there are no security leaks.
More Info on TLS
Communication with secure HTTPS enpoints encrypt the header and body of the message by default using TLS.
HTTPS consists of communication over Hypertext Transfer Protocol (HTTP) within a connection encrypted by Transport Layer Security. Source
Things To Verify
Do Not Use Sensitve Data in the URL
The Url of the HTTPS endpoint is not encrypted. It is important to never put any sensitive data into the Url of the HTTPS enpoint. To ensure sensitive data is encrpyted, put the data in the message body.
For example, if you are validating a user's login (username: user1234, password: password1234), do not send the username/password as a url parameter. Instead, serialize the username and password data, and set it as the HttpContent of the HttpClient.
Bad: https://myApiEndpoint.com/getIsUserValid/user123/password1234
iOS HttpClient Implementation
Ensure that you are using NSUrlSession for the iOS HttpClient Implementation.
NSUrlSession will use TLS by default when communicating with secure HTTPS endpoints. As of iOS 10, NSAppTransportSecurity will not allow communication to non-secure HTTP endpoints by default; communication with non-secure HTTP enpoints can be enabled by updating NSAppTransportSecurity in Info.plist, Apple Documentation.
You can verify NSUrlSession is being used in the iOS Build Settings (screenshot below).
When using HTTPS everything except the server address is encrypted during transit. The encryption is totally transparent to the client and server.
Example: for the URL https://myApiEndpoint.com/getIsUserValid/user123/password1234 only myApiEndpoint.com is not encrypted, the rest of the URL is encrypted.
In order to protect against MITM attacks pin the server certificate, that is verify that the certificate received on the request belongs to the correct server.
If you control the server use TLS 1.2 and Perfect Forward Secrecy.
Related
I know that certificates that are sent by the server cant be faked (still there is MD5 collisions but costy) but what about faking the client ..
in man in the middle attack:
cant we tell the server that we are the legitimate client and take data from that server manipulate it then encrypt it again with legitimate client public key ? how does the client be sure that the data came really from the server ?
in theory .. can we inject any data into the response sent by the server to the client ?..
How are you authenticating the client? SSL client certificates? Or some application level system (cookies etc)?
Here's what SSL does in a nutshell:
Negotiates a Diffie-Hellman shared session key between the two parties
Has the server sign the session key and send the result to the client. Once the client verifies this, the client knows there is no MITM, and the server is who they say they are.
If client certificates are enabled, has the client sign the session key and send the signature to the server. The server now knows there is no MITM and the client is who they say they are.
Encrypts all data in both directions using the shared session key
Typically when you use SSL you won't use client certificates. Strictly speaking, the server does not know if the connection is MITM'd. However, most clients will disconnect if the server certificate is bad. The server assumes that if the client pushes forward with the connection, there is no MITM. Even if Mallory, doing the MITM, chooses not to propagate the disconnect from the client, he has no new information now; all he's done is connected to the server himself. Without intercepting the client's session cookie or other authentication information (which is only sent by the client after verifying the connection is secure) the MITM is useless.
So in short, as long as one end or the other verifies the certificate of the other end before initiating any high-level communication of sensitive information, SSL is secure in both directions.
You're right -- without secure certificate authentication on the client and server there is an opening for a man in the middle attack.
SSL can be "secure both ways" if you use mutual authentication also called two-way SSL.
I am working on some app which as API call. while i add proxy in mobile and see response in web debugging tools. I can see my api call parameters and response too.
while in others app I cant see this things and it is secured.
how can i acheive this?
Pictures said your API is using non-secure HTTP protocol while others app using HTTPS. The Web API should be performed via HTTPS protocol. HTTPS using SSL/TLS as secure transport layer, it means all data are encrypted before they're online. So, we don't care about any kinds of proxy
I am a developing an Rest API in spring boot and it has to be consumed by an IOS Application.I have implemented JWT token with Oaut 2.0 as security and my web server is having SSL.So the call will be made by
https://server:port//dataurl
with the header as the token. My question is since My web Server is having SSL so the connection channel will be secured (because the token should be passed in a secure channel ) or do the client side (IOS App) should also have to implement SSL Certificate. I am a having a little confusion about how the SSL channel communication. Any help is appreciated.
This link has a nice graph about how SSL works.
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm
You can have a look of AFNetworking, no matter you want to use it or not.
In particular, have a look of AFSecurityPolicy.h and how it is used in AFURLSessionManager.m. That could be a good start point.
I need to protect my API for CSRF on post and put requests.
To do that, I think the mobile device (example iOS) need to send to the API server (node.js) a token. This token must be encrypted and contain a JSON data that will be decrypted server side.
To decrypt the data, the mobile device use the same secret key that the sever know.
For example : {_csrf: 123456789} will be decrypted from the token sent via the mobile device and checked by the API if it match.
Is it the right way ? If not what is the right way ?
How I can encrypt a Jon data on iOS and decrypt it on node.js ? (JWT Token does not have library for iOS)
Can you provide me a example code to encrypt data on iOS et decrypt on node.js ?
Just use https, it encrypts everything, even any query string.
The content is encrypted with a random symmetric key and that key is encrypted with a asymmetric key from the certificate. Additionally the symmetric key has a short lifetime. Additionally you do not have to implements and encryption routines.
Also note that iOS9 will by default require https to be used for all connections, any http connections will need to be white-listed in the plist.
If you do your own encryption you immediately have a problem sharing the encryption key between the device and the server. This is not an easy problem to solve.
When accessing the API from a browser page, to protect against CSRF, you can send a token in HTTP headers, for example, X-CSRF-Token, or, use a cookie.
For example, have your server send the CSRF token in an HTTP response using the X-CSRF-Token header. You can have your page send it back in the JSON on the POST or PUT. Or have your page read it from the cookie and put it into the JSON.
(HTTPS from the browser will not protect against CSRF, since any script on any other site running in the same browser can POST to your HTTPS server freely. Your page needs to have a token that no other page in the same browser has access to.)
I have a Rails WebServer based on REST API
I have a AngularJS app, which connects to this WebServer
What is the best way to encrypt login and password on client side and decrypt these credentials on server side?
If you are using RSA you have to have keys in the browser. The keys can't get to the browser unless they go over the unsecured HTTP connection. If an attacker has the keys by sniffing the HTTP connection, and the algorithm from your javascript code, you aren't protecting anything since decrypting your traffic becomes trivial.
I suggest putting an nginx proxy in front of your web server. You can configure nginx to do the TLS handshake, and you can get a Comodo SSL certificate for less than $15 a year. I've done this myself in front of a Python server and truly, that's all it cost.
I've just decided to use http://travistidwell.com/jsencrypt/index.html in way when I store public server key on client side and private server key on server side.
JS client encrypts all messages that are send to server.
The best way, as mentioned by Geoff Genz, is to secure your web server with HTTPS and ensuring that your login action only accepts requests through HTTPS. Configure your angular app to make requests to the HTTPS URL of your login action and all encryption will be taken care of seamlessly. You won't have to worry about manually encrypting the data clientside and then decrypting serverside. All of this will be handled by the TLS protocol which make HTTPS work.