Is it safe to proxy a request from https to http? - ssl

I have 2 servers, Web and Api. Web serves up webpages, and Api serves up json.
I want to be able to make ajax calls from Web to Api, but I want to avoid CORS pre-flight requests. So instead, I thought to proxy all requests for https://web.com/api/path to https://api.com/path.
The only way I've been able to get this to work is to drop the https when making the request to the api server. In other words, it goes https://web.com/some/page -> https://web.com/api/path -> http://api.com/path.
Am I leaving myself vulnerable to an attack by dropping the https in my proxy request?

(I would make a comment but I don't have enough rep)
I think this would depend largely on what you mean by proxying.
If you actually use a proxy (that is, your first server relays the request to the second, and it comes back through the first), then you're only as vulnerable as the connection between those two servers. If they're in physical proximity, over a private network, I wouldn't worry about it too much, as an attacker would have to compromise your physical network. If they're communicating over open internet, you might have other attacks happen (DNS spoofing comes to mind if you don't supply an actual IP address), and I would not recommend this.
If by 'proxy' you mean the webpage makes an Ajax call to your API server, this would open things up to the same attacks that proxying across the internet could.
Of course, this all depends on what you're serving up in JSON. If any of it involves authentication or session-related information, I wouldn't leave it unencrypted. If it's just basic info that's the same for all users, you might not care. However, a skilled attacker could potentially manipulate the data with a man-in-the-middle attack, so I would still encrypt it.

Related

Is it safe to redirect non ssl requests to ssl version of site?

There is an API. Earlier all request were made not via ssl connection (encription was used) - http://api.com/dosomething. Logic has changed now. Now it is a bit problem to change URL for all clients who are using this API. There is https version of the api site. Is it safe to redirect all requests http://api.com/dosomething to https://api.com/dosomething on server side (apache or nginx)? How it works?
Your API consumer transmits everything in the clear: All its data, authentication, etc. And on your new server you're redirecting to the "same" URL, just using https? The https connection now will be secure, but all of your data and authentication has long leaked.
As we don't know anything about your API consumer, technically it could be a web browser that honors "secure" cookies, e.g. it might not transmit the authentication in the clear. But still, all of the data will be out already. As you say that you can't update the clients, I'm assuming that you're not in this situation.
So: The answer is no, it's not secure. Retire the old API, keep track of anyone accessing it. Once they're few enough, notify them of discontinuing the http service so that they upgrade. Or stay unsafe - choose your poison.

Should I set https on every page?

I am bulding a marketplace which store users session ect.... I just added a SSL encryption for login and for the payment (I am using stripe as a payment gateway). I have seen sites like facebook forcing HTTPS on every page so that got me wondering, should I force HTTPS on every page or just on login and payment?
side note, apparently SSL encrypted pages load faster
Yes. But not just because it loads faster, or even ranks better on Google than non-HTTPS sites, but mainly because of security. Having HTTPS makes it harder to do a man-in-the-middle attack, whereby an attack intercepts the connection between your website and the user to either steal or modify data. The trouble with HTTP is that it is possible for someone to do exactly that, and then modify the links to point to a fake login page to steal data (this souunds paranoid but it happens).
While many pages use a script to check if the user is attempting to access HTTP and then redirect them to a HTTPS version, this might still be an issue for websites as attackers can still 'strip' out any HTTPS links (known as the SSLStrip attack) to use only HTTP and then view the data, take a look at enabling HSTS (HTTP Strict Transport Security) for enhanced security to avoid that. This is done by forcing browsers to only interact with the website on HTTPS connections and avoid any sort of downgrade attack.

Why does Twitter serve every page over HTTPS (SSL)?

Is there a reason why a website such as Twitter serves all pages over HTTPS? I was under the impression that the only pages that need to be served over an encrypted channel are pages where sensitive information is being submitted or received.
I do that when developing web apps. It makes securing user data much simpler, because I don't have to think about whether or not confidential information could be passed through a particular request. If there is a performance penalty, it's hasn't been bad enough to make it worth my while to start profiling. My projects have been fairly small, in terms of usage, so far.
Every page on Twitter either:
Is accessed when you are logged in and sending credentials in the request (and potentially receiving data that is private) or
Contains a login form (that shouldn't be interfered with via a man-in-the-middle attack).
Consequently every page on the site has the potential to be a page where sensitive information is being submitted or received.
Switching between HTTP and HTTPS can be tricky to do correctly.
If any resource that is served over HTTP requires authentication, some form of authentication token (typically a session cookie) will be leaked from HTTPS to HTTP (assuming the user authentication itself is done over HTTPS).
Getting the flow of pages right so that, once that token has been used over plain HTTP, it can no longer be relied upon for anything more sensitive (which would require HTTPS) can require a lot of planning in the design of the application. (There are certainly a number of websites that don't do it properly.)
Since Twitter is a website where you're always logged on (or always have the opportunity to log on securely in the corner), it seems to make sense to use HTTPS for everything.
The main overhead in HTTPS is the SSL/TLS handshake: checking the certificates, asymmetric cryptography, ... Once the connection is established, it's all symmetric cryptography, with a much lower overhead.
You'll see a number of questions here (and other places) where people insist to have redirection rules to force plain HTTP for resources that don't need to be used securely, while forcing HTTPS for other pages. This seems misguided to me: by the time the redirection from HTTPS to HTTP happens, the handshake has already taken place. A good browser will keep the connection alive (and will be able to reuse sessions) to get multiple resources and pages, thereby keeping the overhead to a minimum, almost negligible at that point.

Is SSL enough for protecting a request and its headers?

I ask this because I work on an application where the X-AUTH-TOKEN can be copied from one request to another and impersonate another person. This makes me nervous, but I'm told since we're going to use HTTPS we don't have to worry about anything.
So, my question is: Is it good enough trust SSL to protect against stealing headers used for auth/sessions?
Thanks,
Using HTTPS encryption will indeed prevent someone from stealing your authentication token if they can intercept the traffic. It won't necessarily prevent a man-in-the-middle attack though unless the client enables peer certificate checking.
This question from the security stackexchange describes how to implement MITM attacks against SSL. If I can convince a client running HTTPS to connect to my server, and they accept my certificate then I can steal your authentication token and re-use it. Peer certificate validation is sometimes a bit of a pain to setup but it can give you a higher chance of whomever you are connecting to are who they say that are.
"Good enough" is a relative definition and depends on your level of paranoia. Personally I would be happy that my connection is secure enough with HTTPS and peer certificate validation turned on.
Presumably also your authentication token times out so the attack window would be time limited. For example the OpenStack authentication token is by default valid for 24 hours before it expires and then you are required to obtain a new one.
The HTTPS standard implements HTTP entirely on top of SSL/TLS. Because of this, practically everything except for the DNS query is encrypted. Since headers are part of the request and response, and only sent after the secure-channel has been created, they are precisely as secure as the implementation of HTTPS on the given server.
HTTPS is an end-to-end encryption of the entire HTTP session, including the headers, so on the face of it, you should be safe from eavesdropping.
However, that is only part of the story: depending on how the clients are actually connecting (is this a website or an API service?), it may still be possible to trick them into sending the data to the wrong place, for instance:
Presenting a "man in the middle" site with an invalid SSL certificate (since it won't be from a trusted authority, or won't be for the right domain) but convincing users to by-pass this check. Modern browsers make a big fuss about this kind of thing, but libraries for connecting to APIs might not.
Presenting a different site / service end-point at a slightly different URL, with a valid SSL certificate, harvesting authentication tokens, and using them to connect to the real service.
Harvesting the token inside the client application, before it is sent over HTTPS.
No one approach to security is ever sufficient to prevent all attacks. The main consideration should be the trade-off between how complex additional measures would be to implement vs the damage that could be done if an attacker exploited you not doing them.

Is a HTTPS query string secure?

I am creating a secure web based API that uses HTTPS; however, if I allow the users to configure it (include sending password) using a query string will this also be secure or should I force it to be done via a POST?
Yes, it is. But using GET for sensitive data is a bad idea for several reasons:
Mostly HTTP referrer leakage (an external image in the target page might leak the password[1])
Password will be stored in server logs (which is obviously bad)
History caches in browsers
Therefore, even though Querystring is secured it's not recommended to transfer sensitive data over querystring.
[1] Although I need to note that RFC states that browser should not send referrers from HTTPS to HTTP. But that doesn't mean a bad 3rd party browser toolbar or an external image/flash from an HTTPS site won't leak it.
From a "sniff the network packet" point of view a GET request is safe, as the browser will first establish the secure connection and then send the request containing the GET parameters. But GET url's will be stored in the users browser history / autocomplete, which is not a good place to store e.g. password data in. Of course this only applies if you take the broader "Webservice" definition that might access the service from a browser, if you access it only from your custom application this should not be a problem.
So using post at least for password dialogs should be preferred. Also as pointed out in the link littlegeek posted a GET URL is more likely to be written to your server logs.
Yes, your query strings will be encrypted.
The reason behind is that query strings are part of the HTTP protocol which is an application layer protocol, while the security (SSL/TLS) part comes from the transport layer. The SSL connection is established first and then the query parameters (which belong to the HTTP protocol) are sent to the server.
When establishing an SSL connection, your client will perform the following steps in order. Suppose you're trying to log in to a site named example.com and want to send your credentials using query parameters. Your complete URL may look like the following:
https://example.com/login?username=alice&password=12345)
Your client (e.g., browser/mobile app) will first resolve your domain name example.com to an IP address (124.21.12.31) using a DNS request. When querying that information, only domain specific information is used, i.e., only example.com will be used.
Now, your client will try to connect to the server with the IP address 124.21.12.31 and will attempt to connect to port 443 (SSL service port not the default HTTP port 80).
Now, the server at example.com will send its certificates to your client.
Your client will verify the certificates and start exchanging a shared secret key for your session.
After successfully establishing a secure connection, only then will your query parameters be sent via the secure connection.
Therefore, you won't expose sensitive data. However, sending your credentials over an HTTPS session using this method is not the best way. You should go for a different approach.
Yes. The entire text of an HTTPS session is secured by SSL. That includes the query and the headers. In that respect, a POST and a GET would be exactly the same.
As to the security of your method, there's no real way to say without proper inspection.
SSL first connects to the host, so the host name and port number are transferred as clear text. When the host responds and the challenge succeeds, the client will encrypt the HTTP request with the actual URL (i.e. anything after the third slash) and and send it to the server.
There are several ways to break this security.
It is possible to configure a proxy to act as a "man in the middle". Basically, the browser sends the request to connect to the real server to the proxy. If the proxy is configured this way, it will connect via SSL to the real server but the browser will still talk to the proxy. So if an attacker can gain access of the proxy, he can see all the data that flows through it in clear text.
Your requests will also be visible in the browser history. Users might be tempted to bookmark the site. Some users have bookmark sync tools installed, so the password could end up on deli.ci.us or some other place.
Lastly, someone might have hacked your computer and installed a keyboard logger or a screen scraper (and a lot of Trojan Horse type viruses do). Since the password is visible directly on the screen (as opposed to "*" in a password dialog), this is another security hole.
Conclusion: When it comes to security, always rely on the beaten path. There is just too much that you don't know, won't think of and which will break your neck.
Yes, as long as no one is looking over your shoulder at the monitor.
I don't agree with the statement about [...] HTTP referrer leakage (an external image in the target page might leak the password) in Slough's response.
The HTTP 1.1 RFC explicitly states:
Clients SHOULD NOT include a Referer
header field in a (non-secure) HTTP
request if the referring page was
transferred with a secure protocol.
Anyway, server logs and browser history are more than sufficient reasons not to put sensitive data in the query string.
Yes, from the moment on you establish a HTTPS connection everyting is secure. The query string (GET) as the POST is sent over SSL.
You can send password as MD5 hash param with some salt added. Compare it on the server side for auth.