Reputation: 1822
Is it possible to safely include a password in a query string for a c# asp.net site.
Few assumptions and things I know -
I know the site may be susceptible to cross site scripting and replay attacks. How do I mitigate these?
Given the above scenario, how should I include a password in a query string?
Please don't ask me 'why', I know this is not a good idea, but it is what the client wants.
Upvotes: 2
Views: 9738
Reputation: 4282
It is generally not advisable to put secrets in a query string, which can then be book marked and copied, exposing the password at-rest in history files, cookies, etc.
To just safeguard the password in this use-case, an option would be to hash the password (one-way, not reversible). In this way, the actual password is not known in transit nor at-rest but... it implies that an attacker can still use the hashed value to login to the server that would presumably compare the hash value to its store for authentication.
Update: Switching to stateless (JWT) sessions
In the olden days when buggies were a thing (okay - they are still a thing with some fringe groups but) - we used "sessions". A "session-ID" (see JSESSION_ID) for example in Java/J2EE/Servlet based systems was stored as a cookie. That value, being a random number, was hard to guess - but it had problems from hijacking to memory and lookup overhead on the server.
In 2020 times (as of this writing) ... JSON Web Tokens (JWT) can be used to securely encapsulate the user-session information and be pushed back down in an immutable cookie without ever exposing the password and with very little server overhead.
In this model, after login, the server issues a token (using OAUTH2 or related), which has an expiration time-stamp.
This data and possibly other session information can then be encrypted, hashed, signed and wrapped up in a JWT (token) - as a cookie back to the web-browser.
At this point, the client cannot do anything to compromise (or even view) the cookie because any sensitive data should have been encrypted (using AES256 et al or better) and the contents hashed and the hash signed. What this means is that when the server gets the token back, it looks at the timestamp and may throw it out - forcing re-authentication and then...
Can otherwise verify it signed the content, hash the contents and verify the hash and decrypt data if needed (which would not include the password but rather just the ID of the user - which is verified and not necessarily a secret per se).
This can include already-looked-up scopes (authorization) for what the user can do etc - avoiding round trips to the authentication server until the token times out.
Thus the above (using JWTs, hashing, signing, encrypting - into a cookie) is the recommended way to both go stateless and avoid passing around a secret between the client and server.
Ref: https://auth0.com/blog/stateless-auth-for-stateful-minds/
Additionally, consider that multi-factor authentication schemes (see Google authenticator) and related systems are a much stronger security posture (stealing password is not enough and the keys auto-rotate on external systems) but do require semi-frequent access to the rotating key system, which inhibits a smooth user experience to some extent.
Update: Multi-Factor auth by Google and others has gotten much better.
Older companies still use SMS one-time-passwords (OTP) ... which can be compromised by going to a wireless company store and claiming SIM card loss (given a known phone-number). Google and other more advanced companies comparatively use rotating tokens that can be embedded in a smartphone app that then are used for many services. Google even has push-notification where user just confirms by button press: "Yes - it is me".
Upvotes: 2
Reputation: 54771
You can safely send the password to a web server using a SSL connection. This encrypts all the communication between the client/server.
Basic authentication protocols place the user/password information in the HTTP request header. C# and many other web server languages can access this information, and use it to authenticate the request. When mixed with SSL this is very safe.
If none of the above is possible, then it's recommended that you create a unique key for each user. Rather then send their password this key is used. The advantage is that the key is stored in the database and can be removed. The user's password remains unchanged, but they must register again to get a new key. This is good if there is a chance someone could abuse their key.
Hand shaking is where the client makes a request to the server, and the server sends back a randomly generated key. The client then generates a hash from that key using a secret, and sends it back to the server. The server can then check if the client knew the correct secret. The same thing can be done where the password is the secret instead and the client includes username details in the request. This can authenticate without ever sending the password.
If none of the above are possible options, then you could attempt to use JavaScript to encrypt the password before it's sent via an open URL. I found an open source version the AES block cipher. The project is called JSAES and supports 128 to 256 bit encryption. There might be other JS libraries that do the same thing.
Upvotes: 7