I am getting to the point in my Google App Engine development where I am signing users up. I collect the signup info, do some initial validation to make sure that things are the correct length/format, then send that info to the App Engine for server side validation and ultimately signup and login. I understand that I can think of the App Engine as extremely secure (it's Google anyway) and my client side is a Cordova application, which is also secure because it is wrapped in an app package. The only insecure part of the interaction is the HTTP POST request that I send containing the password. I see really only one option for making this more secure. I may be right, I may be wrong. I honestly have no idea.
I'm thinking that I could encrypt the password locally and decrypt it once it hits the app engine. The problem with this is that anyone monitoring my requests can read this decrypted value and they don't even need to decrypt it. They can just send it encrypted as it is. I can adjust this by making the encryption dependent on other variables that only the app engine knows about, but I'm not sure if that is a good way either.
I know next to nothing about web security, and very little about encryption techniques. What is the best way to send and store passwords with Google App Engine?
Don't reinvent the wheel and (as already mentioned in the comment) just use SSL.
It works out of the box for *.appspot.com domains (example) but if you want to enable it for your custom domain you will have to go through documentation.
Send over HTTPS - App Engine provides SSL for free - USE IT! Then at the server encrypt for storage. Never save passwords in plain text. If your using Python, check out the webapp auth api, which takes care of everything for you -> https://webapp-improved.appspot.com/api/webapp2_extras/auth.html
Related
How would I go about deploying a web app intended for only a single user (myself)? I feel like making a login that only accepts 1 user is the wrong method and also easy to hack? Would it be a good idea to make it only accessible from a certain IP? Please advise! Thank you. Backend will be using nodejs.
If I were you, I would program the back-end the proper way. This involves generalizing the entire implementation so that any hypothetical user with the correct password could use your login system. You could still authorize and authenticate the application so that when anybody else tries to log in, you automatically decline their request. If you are concerned about security, ensure that you are using SSL, basic encryption, hash passwords and, most importantly, do not use your own authorization library. It is far more secure if you use OAuth instead of using an IP, for example. Last, but definitely not least, make it as hard as you can for hackers to steal your data in the client side. This way, you also learn a lot of things that might come in handy in the near future.
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 am new to NodeJS and have made a web application login feature using passport.
I know when someone registers an account, the app needs to hash their password and save the hash to the database. But when I use console.log(), the object still contains the user's password in plain text. I have a feeling it's not safe but I'm not sure how to approach this. Can anyone explain what I am doing wrong here?
Irrespective of whether it is node.js or any other framework used for backend development, it is a good practice to pass the sensitive data such as passwords in encrypted format.
Typically we prefer using Json Web Tokens(JWT) - https://jwt.io/
You can use https://www.npmjs.com/package/jsonwebtoken to encrypt and decrypt it.
Don't bother too much with it.
If a malicious agent has access to the runtime environment of your server he will be able to do, possibly, everything. Even if you are using jwt he will be able to get the secret and decode it easily.
Focus on:
leaving the password encrypted in the database (as you did very well)
using SSL between you and the entry point on your servers network
making sure that you only expose the necessary, having a firewall/barrier in the exterior of your server is a very good pratice
sanitize and validate your server inputs to avoid injections and exploits
I just want to say only on don't use third party API or packages for it
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.
Let's say, there is a website for an online diary. Users upload their secrets to the web server and stored in the database. Normally, a user without the password can't see the diary items. However the web admin or DB admin could still can connect to the DB and see everything.
Is there a solution to prevent this? I mean a solution for the whole web application, not only for a single user.
Client-side javascript can encrypt the content, using a key known only to the client and never sent to the server, prior to saving.
However, the server can at any time start serving up malicious JS that would send the keys back down to the server. The only way to make this impossible is to make your application an installable client-side app (via an extension or whatever - but nothing that auto-updates). Additionally, all of this paranoia is pointless unless the user can verify what the app is doing, so it would need to be open-source.
At this point you're basically writing GnuPG, so you might as well just use that.