Good day,
I am very new to database/application/connection security and would like some help on a project.
Let me explain my environment :
I have a username A and password A being saved in a database (A) on a local machine.
Password A is being stored using a type of hashing algorithm with salt A.
I am sending the credentails (Username A and Password A) via a HTTPS SOAP Call to a webservice sitting remotely.
Apon receiving Username A and Password A the webservice validates those credentials to a table sitting in database (B) local to the webservice location.
My Problem : If someone gets access to database A and extracts the hashed passwords they can use a SOAP request to connect to the webservice. This means that my security is null and VOID.
I have to possible solutions :
SOLUTION 1 : Before sending password A to the webservice, I decrypt it and send it over plaintext via the Secured HTTPS connection. The webservice will then encrypt it again when validating agains the hash stored in database B.
SOLUTION 2 : Before sending password A to the webservice, I do a second encryption to that existing hash. When arriving at the webservice, it is decrypted to expose the hash which is .then validated against database B.
My Question : Is any of the 2 solutions above, best practice. If not, what would be a best practive solution for this scenario.
Kind Regards
Just a few notes
there is difference between hash (one way, non-reversible) and encryption (reversible). You cannot decrypt hashed value.
I will assume you are working with service credentials, not user's identity credentials
Here I will assume you are talking bout
SOLUTION 2 : Before sending password A to the webservice, I do a second encryption to that existing hash. When arriving at the webservice, it is decrypted to expose the hash which is .then validated against database B.
The hash effectively becomes a password, it doesn't add any security to the solution
SOLUTION 1 : Before sending password A to the webservice, I decrypt it and send it over plaintext via the Secured HTTPS connection.
There are several standards to authenticate the SOAP WS client, using simple credentials it's WS-UsernameToken. Effectively the client sends its username and password plain, relying HTTPS to handle the channel security.
My Problem : If someone gets access to database A and extracts the hashed passwords they can use a SOAP request to connect to the webservice
One the password is hashed, you won't be able to decrypt it, but as well you cannot use the hashed value as a password. Otherwise you will get the "solution 2" and you are using the hash as a password.
Indeed, this is generally a problem. You may search other questions, how to store service credentials locally. The whole problem is - you need to store the credentials. In my experience the best you can do at least make retrieval somewhat harder, e.g. encrypt the service passwords so they are not stored plain in the database or config files. At the end the client application needs the encryption key somewhere to decrypt the credentials. The key needs to be protected as well.
If you are dealing with user credentials (user identities), do not store the user passwords at all at the client side, there are other ways how to authorize user actions (access token, jwt token, ..)
If you are using xml based SOAP you can use WS-Security to encrypt the password and sign your request data so that the integrity and security of your password is ensured, and the send the data over https.
For storing passwords you should use irreversible crypto hash like sha2, at server you will decrypt the password, create sha2 hash and match it against the one from database
Related
I'm using AWS Amplify (if that makes any difference, I assume the backend APIs control this regardless) and would like to understand if when a user logs in their password is sent in plaintext (albeit within a TLS connection) or if it's hashed - and if so what the hashing algorithm is.
Does anyone know? Thanks.
In my experience (I don't have anything written from AWS to back this up) Amplify sends a USER_AUTH followed by a password challenge similar to SSH. That means the password is not send over the wire, not plaintext and not hashed. The method would be similar to what is explained here: the client proves that it has the password by answering a challenge. A hashing mechanism is used, but the hash used is not a hash of just the password.
I have setup an web-based API to allow a remote app to GET/POST data. Every API call is authenticated with a User ID and Password that is encrypted with a secret key known only to the remote app and the website. This authentication not only ensures that the user can access the API, but also allows me to implement security features based on the user's profile (i.e. User A can see items A & B, but not item C).
I would like my server-side website pages to be able to call the same API methods remotely via AJAX calls, but, something just doesn't seem right about storing encrypted passwords in the code, and, my website implements a "Login As" feature, which will not allow me to set the encrypted password, since the passwords are not stored in plain text.
What is a good way to implement API security for both remote and "local" calls that doesn't require encrypting the user's password?
You should not be storing usernames and passwords in server side code. Sooner or later someone will lay eyes on your code and your data will be vulnerable.
But you should also not be storing secrets (key) in client side code. You should not assume your client can be trusted to keep that secret.
Giving user A access to item A and B, but not C is called authorization and depends on you knowing who calls your API (authentication).
You should probably look into a authentication protocol like OpenID Connect and an authorization protocol like OAuth 2.0.
Also see my answer to this question.
I am now developing web service, but i want person who are authenticated have the right to use the web service. Now I have two methods, one is use username and password in every service, the other is first use username and password to login and get token, then visit other services just by token. Now I want to know which is better? Suppose I use https, it is secure to pass username and password. But my mentor told usually we use token. So can any compare these two methods detaily from security,performance or any other aspects?Thanks very much!
If you are using SOAP, you can implement soap header authentication.
Or Basic in http header
Implement the system in the following way.
The User should send an Encrypted Format password and UserID in the first request.
The Password authentication logic can be unique to you but make sure that the password is not exposed in the SOAP message as plain text.
Next at your service side, implement a service handler which maintains a list of authenticated IP addresses.
Whenever a new IP address tries to contact your service, you validate its credentials and then if authenticated, you add the IP to your safe IP List.
In case the Authentication fails you reject the request.
In case of Multiple services, implement a common Service Handler for the same. and keep the IP list as a static variable.
Other than this You can look into Web Service Security:
Oracle Doc
Wiki Page
and so on...
I think it would be very comfortable to use the user's password hash as the secret for generating a hmac. Why is OAuth and others using tokens and nonces?
I think of something like this:
Client enters a password in the ui.
The application registers with the webservice using the hash of that password, which is stored on the server.
Form now on that hash hasn't to be transmitted again.
The client can always regenerate the secret by asking the user to enter the password and hashing it. Every message is signed with this hash, the server can look it up by username or guid and check if the sent mac is valid.
A intruder on the server can get that hash, but doesn't know the users real password, anyway he could send valid request with that hash. But this is not likely to happen, the saved hashes could also be hashed again using a nonce. Anyway because the pwd-file will be on a client's server it should be obfuscated using e.g. base64 to avoid the file looking like {"password":"a4bd146hashhashhash"}.
Most of all the real password of the user won't ever be transmitted. The request's will be secured with a timestamp/token against replay (I recognize the purpose of the token here).
Sending a hash would be perfectly applicable for me because the client will never be a simple website with a tag e.g.. The webservice will be used in a ajax-based application and a java desktop application, both of them capable of hashing strings...
What's wrong with that? It's so simple, more RESTFul than anything related to authentication, and i think yet effective. What am I missing?
Greets, kruemel
I'm writing a web app in Django that is interfacing with the Read it Later List API (http://readitlaterlist.com/api/docs/). However, all of the API calls require sending the username and password with each request. In order to do this, it seems that I need to store the user's password in plain text in my database. Am I missing something or is that the only approach possible in this case? Is there some way to store an encrypted password in my database, but yet be able to send a decrypted version of it when making the API call? If not, then are there any best practices that I should be following to safe-guard the user's password?
I'm pretty sure that this can't be the only service requiring sending password in plain-text. I'm interested in knowing how developers deal with these sort of services in general. I'm new to web development, so any help or pointers is appreciated.
do your users have to log into your website to use it? if you also are making use of a password authentication scheme, you could piggy back on top of that. Use the login password for your site as a cipherkey in a symmetric key cipher to encrypt the api password. then you need only store a hash of the users password (to your own site) and an encrypted password for the remote api.
Never save password in plain text. You can encrypt and decrypt the password but the problem is that the key you use to do the encryption and decryption will generally be accessible to anyone who has gained access to your server so it's not secure.
An alternative is to ask them to enter their password and save it in an encrypted cookie, or session variable or something else that will expire when they have logged out of your app. This has the drawback of them having to enter their password every time they user your app.