I'm PHP developer and I know very little when it comes to https/ssl, but I would like to offer my client safest possible way of uploading file to webpage (i.e. webftp as part of client service on page).
Which way should I look?
Thank you in advance, I will clarify my question if needed.
I'll probably disappoint you, but without HTTPS or some other form of encryption, all the data passing over the wire is plaintext - this also holds for FTP. (In other words, it's practically impossible to verify that the data which the server has received actually came from the client, and hasn't been modified.)
Valid (and widely accepted) HTTPS certificates are cheap and relatively simple to use, plus it's probably the optimal solution currently available in terms of safety*simplicity (switch URLs from HTTP to HTTPS, no other configuration required from end user). With a valid SSL certificate, the client could be reasonably sure that they're communicating with your site and that the data is encrypted while in transit.
In other words, there are safer (but more complicated) alternatives (such as encrypted VPN), and there are simpler (but less safe) alternatives (such as plain HTTP). HTTPS done right is about the right combination of safety and simplicity for a general-purpose website. (OTOH, if you're trying to protect top-secret NSA files, HTTPS is definitely not enough)
I'm sorry, the browsers themselves offer no alternative to either sending the file in plain text or sending it encrypted through HTTPS.
The only alternative would be to use some sort of client side plugin (e.g. a Java Applet) that would encrypt the file prior to sending it (as a bonus, you could compress the file before it was encrypted and sent). However, this solution hinders compatibility by requiring a plugin to be installed, is much more complex and ultimately rendered unnecessary by the existence of HTTP over SSL/TLS (HTTPS).
Related
I am creating a simple PHP application which uses JQuery and AJAX to call (GET method) a PHP script with some parameters; username and password. The application uses SSL.
When tracing the request in Google Chrome Developer tools, I see the following request URL:
https://application.com/php/login.php?username=John&password=Simple1234
I used WireShark to make sure the parameters are encrypted when sending the request, and I don't see any obvious request-headers.
Just to be a 100% sure. Does SSL also encrypt parameters which are included in the header and am I doing this the right way? I found some duplicate questions about this topic, but none of them had a specific example.
Yes but it is a bad idea to use $_GET for such sensitiv data.
This data would be saved in the server logs
This data would be saved in the browser cache
Even Screenshots taken while the login process could contain this data
Also even if the data is encrypted it is still "availble" and could be decrypted.
Use $_POST instead.
This article will show the risks:
https://blog.httpwatch.com/2009/02/20/how-secure-are-query-strings-over-https/
The fact that it is PHP or AJAX does not matter here.
The only thing that matters is the URL: is it https:// or http://?
If it is https:// since it means it is HTTPS(!) which means in summary HTTP inside TLS (SSL is dead since 20 years, its successor is TLS).
TLS encrypts everything (it does other things too but here we discuss only confidentiality needs), if implemented and configured correctly (I want to emphasize that because it is not a silver bullet, putting a sticker "TLS" is not enough, for example there is the whole issue of certificates verification, as authentication may be deemed more important that confidentiality in fact, because what do you gain if you encrypt everything towards an endpoint you are not 100% sure it is the valid one?)
What you see in the URL is part of the HTTP protocol. The URL will be inside the HTTP stream as GET /php/login.php?..., just before other headers. Same if using other HTTP methods. Since it is inside HTTP, it is inside TLS, hence encrypted.
The only thing visible by a passive monitor will be the domain name (both for DNS queries before the HTTPS connection - DNS over HTTPS/TLS solves that - and because of the SNI extension at the beginning of the TLS handshake - and encrypted SNI, still being designed, will solve that).
How safe is it to pass passwords / username in POST or GET requests to an external server?
I will use PHP / CURL and I have second toughts about security.
Alternatives will be considered aswell!
If you use HTTP without SSL encryption, everything is transmitted in the clear, which includes the full URL, the HTTP request/response headers, and the body of the POST request and response.
If you place a password in the GET parameters, it will additionally be displayed in the address bar and quite likely saved in browser history, proxy server logs, and sent to other websites in the referrer header. Sending the password in the POST body or in the standard Authorization header avoids this obvious problem, but it is still visible to an observer who can sniff or proxy your traffic.
Digest Authentication avoids transmitting the password in the clear, and only a non-reusable signature is exposed to the outside observer. It is still vulnerable to man-in-the-middle attacks; see HTTP Digest Authentication versus SSL.
The correct solution is to use an SSL certificate and exclusively use HTTPS. When you do so, the URL string, HTTP headers, and POST body are all encrypted, and the browser verifies that no third party is operating a server in the middle. HTTP Basic Authentication is permissible in this case.
By themselves, not necessarily. You shouldn't use GET for things aside from queries, in general because they can get stored on the user's browser. POST is relatively easy to encrypt using libraries, as you shouldn't implement your own encryption.
Also, if you get an SSL, that would help. If you use HTTPS (rather than HTTP), then it will be even more secure.
You didn't give many details as to what the page was (read: the language) so I can't really recommend a good encryption library, but just Google it and I'm sure you'll find something.
I have created web service for android in PHP that uses GET method. Now I want to convert it to POST, to make it more secure. How to convert the application from GET to POST? Is there any other way to make it more secure?
The answer depends on who you want to secure it from. Assuming that you want to protect from network sniffers, SSL is your best option.
POST is the weakest form of "security" you could suggest. All it does it prevent the parameters being visible in a browser's cache history (which doesn't affect you at all in this case) and make it a fraction harder to sniff the parameters over the network (which does affect you). So there's minor benefit (yes, it's worth it), but it's not secure at all.
The simplest solution is to POST using SSL. In other words, as opposed to posting to "http://example.com" you should post to "https://example.com" with a valid certificate on the server. That will encrypt the traffic between device and server. Google for suggestions, or start Secure HTTP Post in Android
Failing that, you could encrypt the data yourself and then send the encrypted query openly as only your server can decrypt it. A little bit of Googling will give you code on how to encrypt in one and decrypt in the other securely - but as a small warning, getting it to work can be frustrating as it won't work until it suddenly does... there's not much debugging you can do when it doesn't work!
I building a service which be served via https.
I would like to know if password (or any specific key) transmitted in curl option CURLOPT_USERPWD are safe when data is "over the wire" ?
ALL data send via HTTPS is encrypted. This means that it is very difficult (but not impossible) for anyone between the server and the client to view the raw data of the request.
If you want to fully understand the potential ramifications of using HTTP basic auth, you should fully understand how it works.
Since HTTP is a plain text protocol, it is very insecure. HTTPS is simply HTTP using an encrypted socket - which means that the request/response format itself is completely unchanged. If you can view the plain-text version of the request, you can glean from it whatever information you like. But, using SSL/TLS makes it very difficult to view the plain-text version.
HTTP Basic auth is inherently vulnerable to man-in-the-middle attacks and should never be used over an unencrypted connection, but using HTTPS makes it fairly safe. The only consideration is that the server will be able to view the password in plain text - if you don't want this to happen, you should use Digest auth, HTTPS or otherwise.
Yes, the password won't be visible, because it is sent encrypted over the network, but most probably (not completely sure), the script that runs on the target website (the service in your case), will be able to see your password.
I want to secure the login page on my blog when my browser sends my password to the server (http) as I don't want anyone to steal it.
How would you do it?
As far as I am aware the only real way to do it from a production perspective would be to use javascript to encrypt the data sent in the form and then decrypt it at the other end.
There appear to be a couple of JS classes for this purpose, e.g. http://www.jcryption.org/
jCryption uses the public-key algorithm of RSA for the encryption.
Then a third party packet sniffer would have to know the decryption key to be able to do anything with the data.
I would recommend using SSL for all login's though! Personally I tunnel all my traffic over a VPN so I know it is slighty safer when in public places.
You could only allow the use of the login page over an SSH tunnel ;) However I think SSL is then much less burdensome.
The javascript suggestions I don't know what I should think about those. The key must be shared between client and server so this needs a secure key-exchange as well. That's not trivial at all and I suspect that only very few really good libraries for that are around. The basic suggestion to "encrypt" something with javascript will most certainly just fail.
Use JS to perform RSA. Encrypted it before posting it to the server. Then decrypt it when reach the server
If you ask me, I won't use non-SSL encrypted logins. As soon as sessions are involved I switch to SSL as session stealing without SSL is just too easy. Also SSL allows me to protect my pages with Basic-Auth, so I do not even need a session.
So perhaps best is to consider switching your Blog to SSL entirely. Note that for using SSL on your server you just need an SSL certificate. There is a company out there which offers a free ssl certificate for 0$ per year. Also note that Google and all major search engines can handle https pages without trouble.
I skip the 1000 lines of answer how to implement your own secure password scheme using JavaScript and AJAX over insecure lines, because this is difficult to implement.
Two options how to securely login without JavaScript and without SSL come into my mind:
There is a cheap one time password USB device out there. You just plug it into the USB port, press the button, it creates an OTP and here you go. As it is an OTP it only is valid a single time, so no replay and no problem when it is sniffed.
The other thing is OpenID which is used here on stackoverflow. OpenID does not need SSL between server and client. Note that this USB token above already is OpenID enabled as well.
Both ways offer trainloads of free libraries to implement it using PHP or other languages. It certainly is easier to implement than to create a properly designed and secure password scheme yourself over insecure lines.
One big caveat, however:
If you use sessions over insecure lines, and logins ususally use sessions, be sure to protect the session at least by the IP seen. This must be implemented on the server side. This way, if somebody steals the session Cookie the session cannot be (ab)used, provided that the thief does not share the same wLAN (or computer) as you.