I was thinking about a way to ensure that the authenticated client (by username, password, OAuth) is using the official client, and not a third side one which sends requests to the server, assuming that the official client can be decompiled and the code is revealed.
What's the best solution for this security problem?
I have been reading about digital signature and SSL certificates but I cannot find how it solves this problem.
Hope to find a good answer, thanks!
Related
Narrowing down from a broad topic, i have a specific question (maybe a little bit 'tin-foil hat').
This question is regarding the best practices of securing data transmitted in a post request between the client and server. The background is a web app I'm developing to learn more about node and express js.
Although the example i'm using is for login credentials it really could be about any information being transmitted in a post request from a form submit to an express server.
example:
client submits form data through a button click event on the client. I'm using vue for the front end, but this is a generic question. On the client page i'm also using (inside an async function):
const resp = await axios.post("http://someurl.com/login", {client:email, pw:pw});
in chrome developer tools on the network tab i can see the request payload. In the example it looks like:
{client:"some email address", pw:"some password"}
Would it be better to transmit the payload already encrypted / encoded? Then have it decrypted / de-encoded on the server?
For transmitting sensitive information, is it better to use a signed cookie?
The plan, should i ever get through all of this is to use let'sEncrypt for HTTPS.
Is it reasonable to only rely on HTTPS for protecting this type of payload?
For reference, on the express server, password gets hashed and compared with a hashed version from a database. I've read about Helmet, and csurf and intend to use them in the final product as well. There's a lot of great information in this answer. Which is incredibly awesome and talks about the importance of HTTPS over HTTP.
Any additional references / thoughts / practical considerations are appreciated.
Using HTTPS will encrypt your payload between your client and the server.
Any javascript handling on the front end can be circumvented by users with enough knowledge so all frontend is mainly there for is to facilitate a better user experience. Password confirmation checking, correct fields filled out etc.
Your main source of security will be your eventual LetsEncrypt HTTPS certificate and your hashing and salting applied at the server end. As you correctly surmised HTTP send passwords in clear text which is bad. As a warning though even HTTPS can be defeated if somebody wants it bad enough with a number of techniques to high jack Certificate Authorities (I believe Root CAs should be offline anyway) or modify trusted certificates on a users PC.
Although it does depend on the amount of effort required by the hacker vs potential return hence the more you are trying to protect the greater the security required before it becomes not worth the effort for any potential hacker to attempt to circumvent the security of a particular site. (Reputation hacks aside of course)
Hope this helps.
I'm writing an API that will be hosted without SSL support and I need a way to authenticate the requests. Each client would have a different ID, but if requests were authorised with that, anyone with a packet sniffer could forge requests. Is it possible to make a secure system WITHOUT relying on SSL?
(Some thoughts I had included OAuth, could that be implemented?)
Many thanks
Have each client cryptographically sign its requests with a client-specific key. Verify the signature on the server.
Using cryptography pretty simple. The main challenge is setting up the clients' keys. It'll be hard to do that securely without using SSL. There's no information in the question about how you set up client IDs, so I don't know if it's secure enough to set up keys at that point as well.
It's also going to be a problem if you serve the client code without SSL.
But hey, it's just an API you're building. Maybe the code that interacts with it is served over HTTPS. Or maybe the code is stored locally on the client.
I feel like a lot of people are going to complain about this answer though.
I know there are similar questions but I couldn't find something that answered my question.
When a new user registers (client - server) is there a common way of protecting these details when they are sent?
At the moment I am just concatenating the username-password-timestamp then sending as Base64 to the server over https.
The common and best way is https. Https already establishes a secure channel between the client and the server. You don't need anything more.
Please excuse me for the short answer. However if you really want the long answer then take a look at:
How to send password securely via HTTP using Javascript in absence of HTTPS?
I am thinking about writing a secure connection between a specific client and a specific server over HTTP. Of course SSL is the best and most obvious choice. But I keep thinking I could do the do the cryptography myself.
Note that this isn't about connecting any client to a specific server, but a specific client (e.g. a Java client app on my PC) to a specific server (my website hosted somewhere else). SO third-party certification doesnt seem necessary, since the server knows exactly which client to look out for and the cleint knows exactly which server to find.
If I want to upload a file from client to server. I could encrypt it manually (AES or other) and have the key hardcoded into the client app and also put in a file on the server, out of public view.
Please tell me if I'm crazy, stupid or pushing at windmills. Is my idea possible?
The short answer is, "No you can't." You can write some code that you think implements a secure connection, but actually it will be insecure. Designing and implementing a secure connection is a very skilled job; just see what a security consultant would charge you for doing that.
Since you are asking the question here, it is reasonable to assume that you are not such a person. Since you do not have the required skills and experience, anything you produce would be insecure.
Use existing standards where all the obvious errors, and a lot of the not so obvious ones, have been avoided for you.
Your idea possible, and really, if you just need to send file to specific URL, it would be easier to make a POST request with encrypted data (if URL/headers don't need to be secure for you).
Trying to roll your own replacement for SSL is a bad idea. Don't roll your own crypto. Instead, you should use SSL. It does what you need.
Given that you need to authenticate both the client and the server, you should use SSL with client certificates (as well as server certificates, which are standard).
Let's say I have 2 servers (server and authenticator), and I have a client. My end goal here is to be able to identify the client on server. My solution was to come up with a token/secret system like OAuth: client has a token and secret. It passes it to server. Server passes it to authenticator. If valid, server allows the request.
Obviously, this is nonoptimal just for the number of requests being made. The reason authenticator and server are separated is because this is for a decentralised service-- any number of servers may be used, and it's impractical to ask client libraries to register on each server.
So, the question remains, what's the best/correct way to do this? The goal is to create a system that is decentralised, but can still have clients identify themselves in a relatively secure fashion to the server.
Disclaimer: I'm not a security expert so I could be off-base here and in actual implementation there seems to be a number of security issues that would need to be ironed out.
In the broadest sense, could you have the client supply credentials to the authenticator and then upon verification the authenticator supplies the client and the server both with matching security tokens and then the client and server can communicate directly?
Just curious about there a reason you don't want to implement OAuth and run your own OAuth server.
Additional reference: http://groups.google.com/group/37signals-api/msg/aeb0c8bf67a224cc
Turns out the solution was to define my problem a bit better. As I'm only trying to create a way to block applications, I only need to store their name and key when they request the server. Then, as long as they're not blocked and the key matches the one in the datastore, they'll be identified. So I'm not trying to authenticate so much as identify. Thanks for the input!