Execute and transfer highly secure data between known and unknown hosts - security

The problem is: I have a script (written in PHP) that is able to get commands, gather and send private data (this is just backup script). Main server will ask scripts to get data.
Now I have 3 security problems I want to solve:
I want to disallow any other server to ask for the private data (no server, except the allowed, can execute any command)
I want to encrypt request - I will send private data in it (for example file names to transfer, which are considered private)
I want to encrypt the response - script will output private data (file contents).
Does anyone has any idea how to achieve these points or has any interesting cases of thoughts in this matter?
My idea is to:
Generate some kind of secure password and encrypt script before I will deploy it to remote server. I store the password and pass it in a request - it will decrypt the script (this is easy in PHP). Remote script then may send request to main server asking was this command authorised. Also, I can check IP of the server.
I will also generate another secure password which is used to encode/decode all sensitive data in request.
The idea here is to use also encode/decode approach from 2, but also not to send a response directly. Script will send request to the server with an answer. (using HTTPS). This will not let data go outside of the connection and will also make sure we use HTTPS (I don't know the status of the remote server, but I'm sure main server has strong SSL).
Is it enough? Will you add anything? WHat are your thougts?
Regards,
Jakub Król.

You can use client certificate authentication. You will generate a certificate for each of your clients, and then your server (i.e. the script you were talking about) will check whether it knows about the given client. See, for example, here for info on using client certificates in PHP.
Since your client knows whom it is sending data to, you can use Asymmetric encryption. Client will use server's public key to encrypt request. Server will decrypt the request with it's private key. Search google/bing for assymetric encryption in php
Similar to point 2), your server may encrypt data for the given client using it's Public key.

Related

Is it possible to intercept the payload of a secure request in plain text?

Consider we run the following request:
url="https://secretsub.example.com/secretpath/post.php"
payload = {'secretmessage1' : 'foo','secretmessage2' : 'bar'}
r = requests.post(url,data=payload,verify=True)
The language (python) is just arbitrary but it can be a request on any other language (NodeJs, Java, Php...)
Notice that the url is using https, which means that the connection is secured over SSL. Assuming that I compile this program into binary (.exe), would it be possible for computer to read the payloads through a software in plain text?
I know that packet sniffing software (like WireShark), will only reveal the domain name (example.com) in plain text but not the secrepath nor the payload which will be encrypted.
If I run this code in a web browser however (assuming that it is written in Javascript), I will be able to access the payload and the secretpath in plain text inside the browser console. I assume that the browser only encrypts it only after the request is logged in its console. But if this code is run outside the browser, is there a way a for the computer host to intercept those data in plain text? (some sort of packet sniffing tools)
It is only possible to see the domain name, the payload and path are encrypted and can only be decrypted by the session key as negotiated between the client and webserver. But malware on your computer could be able to access it, for instance by having access to the memory used by the application or by using an insecure programming library with some kind of backdoor.
What the https is doing is initiating a certificate exchange so your client will recieve a certificate from the server that validates the server is who thay say they are and allows the client to encrypt the data through the channell (network).
The first bit - validating the server is who they claim to be - relies on something called a certificate chain. The certificate you recieve will have been signed with an issuers private key. Your client should check this certificate using the issuers public key that you should "already have".
Most operating systems have a list of trusted root certificates. In windows you can see them in the certificate manager.
Without knowing python - #Patrick Mevzek hints that you can ship a root CA (certificate authority) or use the OS one. if your using the OS one - you might need to check its going to be there.
I would expect all this to be automatic - its part of the protocol that you've specified i.e. https. However - you might want to confirm that with a python person.
Most people kind of ignore all this bit - but it is very important. If you do not validate the certificate then you are susceptabe to a "Man in the Middle" attack or DNS spoofing.
Basically I can issue a cert for secretsub.example.com using a couple of tools on my desktop. It will not be signed by a valid CA but if you don't check it then I can either place that cert in a proxy (Man in the Middle) - and when you make your requet my proxy will get the real cert from the real server, establish the HTTP connection but issue my cert to your application. You will then encrypt to my proxy with my cert so I can read your data and then forward it to the real server - and you'll never know! (Many corporate proxies do exactly this to their employees).
Alternatively if I can change your DNS to point the IP to my server I can do pretty much the same - act as a proxy.
Once that's done the data will then be encrypted accross the network.
So - yes HTTPS will encrypt accross the network - but check the cert is valid.
Obviously as someone points out - the data is in the clear on the client computer - just like it is in your browser now.
Stuart

How to make sure that only the authorized user can access a feature provided by the server?

We are building an android application and one of its features is to book a cab service provider's cab (say an Uber).
We have an application specific user ID. Let us call it AUID. To book the cab, the application would Post a request to server and send AUID along with other relevant information (like lat, long etc). How do I make sure at the server end that the request is indeed coming from the correct user and it is safe to book the cab? In the current form, if a third party gets to know the AUID of another person, the third party can book a cab on behalf of that person.
One of the solutions I thought of was using asymmetric encryption. The application would hold the public key and the server would contain the private key. Instead of sending the user ID to the server, we'll instead send an encrypted key where the key would be AUID + timestamp encrypted using the public key. We'll then decrypt the message using private key at server end to obtain the AUID. If the timestamp at server does not lie within a certain interval of the timstamp sent by the client, we reject the request.
Is this a safe enough approach? Is there any other practice widely followed for such scenarios?
What you propose is sensible: encrypt the AUID on the client app and verify on the server. As comments suggest, SSL is vital.
The problem is that if how to encrypt the AUID is in your app, it can be figured out by anyone dedicated enough.
You can drastically reduce the risks of fake requests by issuing a separate encryption key for each user. This means that if someone cracks your code, they can still only spoof from one account. However, once an attacker had decompiled your app, they could theoretically start new accounts, get a valid encryption key and spoof requests.
What you need for 100% reliability is some form of authentication which is not stored in the client app - like a password or TouchID on iOS or fingerprint api on Android M. So when a user orders a cab, they need to enter some piece of information which you also encode with the AUID and check on the server. That secret information is not stored in your app, so no-one can fake requests.
Requiring a password from a user is pretty inconvenient. Fingerprint scanning is much easier and probably acceptable. You could also use a trust system - if the user has ordered cabs before and everything was OK, they can order without special authentication. Using Trust together with individual encryption keys is pretty effective because anyone trying to spoof requests would need to do a successful order before being able to spoof - which is probably too much hassle for them.

RSA signature on web applications, general directions needed

im 100% new to digital signature, as far as i understand, a document is signed by an user private key, and that signature is checked using the public key. my problem is that i have a web application, and a file server... Files are created on an earlier stage. then an user that is using the application checks the files and signs them using his key.
those files are stored on a file server and they need to be strip from some of the content in order to do the signature (according to the implementation manual of the file, an HL7 CDA file). so, i need some direction to understand how to do this, should i retrieve the file, then alter it and sign it from the browser, or should i send the private key to the server and make all things there?
or any other option, mks.
There are three options possible:
Transfer the file to the client. Have some client-side module that performs signing. The difficulty is that the files can be huge.
Transfer the key to the server. Sign the data on the server. This can be a problem if the private key is non-exportable (stored in hardware or just flagged as non-exportable in Windows CryptoAPI).
Use the distributeed solution which will calculate the hash on the server, transfer it to the client, calculate the signature on the client and send it back to the server. The example of such solution can be found in this SO answer.

Decrypt stored secret using HTTPS transport

I am considering developing a software for safely storing files on a server.
Let's say I have a secret document initially stored on my client computer that I want to upload to the server. The requirements here is that the file on the server should be encrypted at all times and since the private key is on the client, it is unreadable for anyone accessing the server directly. Maybe I can do it with javascript or maybe I need to develop a full fledged app to handle the upload. Either way is OK but I need to be able to download and decrypt the file using web browser only.
This got me thinking. Can I configure HTTPS (SSL) in a way that I can precalculate the encrypted response from server to client. In that case I can do that while uploading and when the document is requested I can just return the pre-encrypted data which will be decrypted by the SSL stack on the client.
I know that the there will be a random number exchange that prevents this. But is there a way to configure SSL so that the response from server to client will be the same always. In this case replay attacks from server to client is acceptable and not an issue.
In an SSL handshake, the client generates the pre-master secret that will be used to derive the session key. Since you appear to have control only over the server, you cannot prevent the client from steering the conversation in a particular (cryptographic) direction.

Sanity Check: SSL+ POST vs. un-encrypted GET

A classic dumb thing to do is pass something security related info via a GET on the query string ala:
http://foo?SecretFilterUsedForSecurity=username
...any yahoo can just use Fiddler or somesuch to see what's going on....
How safe is it to pass this info to an app server(running SSL) via a POST, however? This link from the Fiddler website seems to indicate one can decrypt HTTPS traffic:
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/DecryptHTTPS
So is this equally dumb if the goal is to make sure the client can't capture / read information you'd prefer them not to? It seems like it is.
Thanks.
Yes, it's "equally dumb". SSL only protects data from being read by a third party; it does not prevent the client (or the server) from reading it. If you do not trust the client to read some data, they should not be given access to that data, even just to make a POST.
Yes, any user can easily examine the data in a POST request, even over HTTPS/SSL, using software like Burp Suite, Webscarab, or Paros Proxy. These proxies will complete the SSL transaction with the server, and then pass on the data to the client. All data passing through the proxy is stored and is visible to the client.
Perhaps you are trying to store sensitive/secret data on the client-side to lighten the load on your server? the way to do this so that the user cannot look at it (or change it) even with a proxy, is to encrypt it with a strong symmetrical secret key known only to the server. If you want to be sure that the encrypted data is not tampered with, throw on an HMAC. Make sure you use a sufficiently random key and a strong encryption algorithm and key length such as AES 256.
If you do this you can offload the storage of this data to the client but still have assurance that it has not changed since the server last saw it, and the client was not able to look at it.
This depends on who you're trying to protect your data from, and how much control you have over the client software. Fundamentally, in any client-server application the client must know what it is sending to the server.
If implemented properly, SSL will prevent any intermediary sniffing or altering the traffic without modifying the client. However, this relies on the connection being encrypted with a valid certificate for the server domain, and on the client refusing to act if this is not the case. Given that condition, the connection can only be decrypted by someone holding the private key for that SSL certificate.
If your "client" is just a web browser, this means that third parties (e.g. at a public wi-fi location) can't intercept the data without alerting the person using the site that something is suspicious. However, it doesn't stop a user deliberately by-passing that prompt in their browser in order to sniff the traffic themselves.
If your client is a custom, binary, application, things are a little safer against "nosy" users: in order to inspect the traffic, they would have to modify the client to by-pass your certificate checks (e.g. by changing the target URL, or tricking the app to trust a forged certificate).
In short, nothing can completely stop a determined user sniffing their own traffic (although you can make it harder) but properly implemented SSL will stop third-parties intercepting traffic.
The other, more important reason not to add confidential information into URL with GET requests is that the web server and any proxies on the way will log it. POST parameters don't get logged by default.
You don't want your passwords to show up in server logs - logs are usually protected much, much less than, for example, the password database itself.

Resources