I'm looking for a server-side implementation to disable a browser from saving invalid login credentials.
For example, user "foo" logs in with password "bar". Browser asks foo if he wants to save the password. However, foo's password is actually "baz" and therefor would be saving the incorrect password.
I've tried manipulating the HTTP codes, such as sending HTTP/1.1 401, but without success.
This is NOT solved by adding "autocomplete" to the form, as this prevents any saving (even valid).
Server backend is PHP.
I don't think you can - that's a browser behaviour.
Closest you could come, is write a Firefox plugin that maybe could intercept the request. But I'm not even sure about that, and it only applies to Firefox. You'd need to look at Chrome, IE, Safari and any other browser you're interested in.
It seems that you are attempting to fix something that is not your job and which you have no control over. As Joel Mueller has stated, Firefox addressed this issue by changing their modal save password dialog to a status bar which allows you to confirm that the password was correct before you save it. If you are experiencing this issue in other browsers then you should submit it as a feature request to the developers of that browser so that the issue can be fixed at their end, which is the only place it needs to be addressed.
You can't have it dismiss that box if the authentication fails. However, you could have it prevent subsequent fillings of that field on the "Password Failed" page after the initial attempt. Once the page has loaded, manipulate the DOM to remove the text value from the password field if the last login attempt was invalid. It would still display the password on subsequent "fresh" visits to the site, but hopefully the correct password will have been saved by then.
Related
Please note the code snippet is just there as an example, there is nothing wrong with the way it works - my question is relating to Chrome's default behaviour of prompting the user to remember their sign-in details, which I want to happen when the password is correct, but not to happen when the password is wrong.
I have been looking around, and come across other articles, but they aren't specifically for my issue and cannot be related to it.
The backend code handling a form submission essentially goes like this (cut down because the code is not actually the problem here)
if(password_verify($password,$dbpassword)){
//Task: Please DO prompt me here chrome, this is correct
header('Location: /account');
exit();
}
setcookie('error','Your password is incorrect',time()+5,'/','',true);
//Task: Please DON'T prompt me here chrome, this is the wrong password!
header('Location: /log-in');
exit();
The log in page then reads the set cookie and displays the error, prompting the user to make another attempt.
The problem is not related to my code. The code is fine.
Chrome takes the header('Location:') to mean that login was successful, thus prompting the user to save these details (annoying). I was wondering if anyone knows how to basically tell the browser it was a failed attempt?
Untested, but I imagine the same prompt would occur on other browsers that offer the same user/password storage... So an all-browser solution would be amazing if anyone has... I'm sure it is a simple one liner to fix this, but I've been researching for over an hour with no success
My code so far performs fine like this:
Cookie set with error message ✓
Header redirect back to login page ✓
Cookie read & error message displayed ✓
Cookie removed ✓
Google shouldn't ask to remember because it was wrong ❌
You could try telling the browser that the user is not authenticated yet, by setting the status code 401 (Unauthorized):
http_response_code(401)
However, you should be aware that the Location header should only be used with redirect status codes (3xx). Therefore, to prevent unexpected behavior consider either directly rendering the login page, or use a different method of redirection. See also this answer.
What I think of is detecting authentication attempt and logging user in using PHP and standart HTTP credentials without bugging him with popup, when he does not try to login. That may sound easy, but we must keep in mind, that browsers check whether site is requesting authentication, and when it does not, they are bugging user with warning and they also send no data.
Is there any bypass? Any trick?
QUESTION SUMMARY:
I want url http://example.com/site to work wihout any promts and popups. User will see the site as anonymous.
I want url http://user:password#example.com/site to work without any popups too. User will see the site as user
To answer your question: no there is no way around it. The browser will not send the authentication information if it has not been requested by the website, and as you have discovered, it will also show an annoying security warning to the user. You should bite the bullet and use a GET param.
In PHP, when making a login page, if your page is HTTPS, is it common for the username/password to appear in the request post information?
Shouldn't the password be encrypted? What am I missing?
Here is an example of what I'm talking about: this website is called souq.com where you can see in Firebug monitoring it's showing the username and password.
It is encrypted when sent over the internet. What you see here is what your browser sent to the server before it became encrypted.
Therefor what you see in Firebug has nothing to do with how it looks like when being sent through the web.
Firebug sees the data before and after encryption so yes, you will be able to see it. But it's only visible within the application , so don't worry, this data you are seeing is all in the DOM :)
If you have more concerns about this, install something like Wireshark and you'll see that the data being transferred is indeed encrypted.
use some network sniffer (e.g. wireshark). then you will really see what goes over the wire. firebug shows you values before they really leave your browser so it's not good to check any security issues.
I know that this feature is to enhance user experience (by not retyping their details every time) and users can tweak their browser settings, but is it possible to send some "headers" etc (or any method, I mean server side controlling) so that when users try to log into my site they dont get this "Do you want IE/Firefox to remember your password?" prompt?
I am not very sure if it is possible? what would you say? Any ideas will help.
Thanks.
Put 'autocomplete="off"' in the input tag of the field. This works in IE and Firefox, but it's not part of the HTML standard, so you'll end up with invalid mark-up.
Add autocomplete="off" to the <form>
Mozilla docs on autocomplete
Besides using the autocomplete attribute you could add a random number to the url that receives the posted form.Each time the form is presented to the user it will be different so the browser's attempt to recall will fail.
I was looking at the livehttpheaders plugin for Firefox and decided to test my login page. I noticed that the parameters shown inside of it contain my login and password. For example:
username=sarmenhb&password=thepassword&submit=Login
in plain English.
I don not see this on other sites.
What can I be doing wrong? I see this as a security flaw. The login page, all it does is validate and log in the user. All fields are ran through mysql_real_escape_string (in case that is relevant).
The information has to get to the server from the client some how. Use SSL if you are worried about security.
Even if you do an MD5 hash in Javascript, this does not help because it is trivial to submit the hash to the login page, and the hash effectively becomes the password. All things are plain text until they, or the transport, is encrypted. POST the variables, use SSL.
To add from my comment below. You may not see the headers for other-sites because they may use AJAX, POST method or another client-side mechanism to authenticate.
This reminds me of a certain building in a large city (I am sure there are others in other places) where they have a web based interface to the building concierge. Residents can log on to a web site (over http) and specify (among other things) who is allowed to enter their apartment for repairs etc in their absence. I am sure the whole thing was programmed by someone's nephew who is a 'guru'.
I am sure it is, shall we say, good enough.
You're seeing it for your site and not for others because livehttpheaders shows the URL for GET requests, but doesn't show the content for POST requests.
Sending login information through GET requests is a minor extra security hole over sending them POST, in that the URLs for GET requests are often logged in various places, whereas almost no one logs POST content. Does everyone with permission to look at the webserver logs have permission to know the CEO's password?
However, as others have pointed out, unless you're using https: for login, data is going across the network in plain text whether you use GET or POST. This is almost always bad.
Still, as an intermediate measure I would change your app to send username and password stuff as a POST, not a GET, so that you don't end up storing usernames and passwords in your webserver logs - it's no use using https over the wire if you're doing something that then writes the username and password to an insufficiently protected logfile on the server.
When you are using http and submit a form, the form contents are sent across the wire "in the clear", as you're seeing. When that form submission includes credentials, then yes, you have a security issue.
Among your alternatives are:
Use https, so that over-the-wire communication is encrypted
Use OpenID for login, which pushes management of https credentials off onto the user's OpenID provider
Use Javascript on the client side to encrypt the credentials before posting the form
The latter approach tends to get people into trouble if they're not very careful, because the mechanism for encrypting the credentials is fully visible to anyone who cares to inspect the javascript.
HTTP live header shows POST requests as well. Post sends the data the same way as GET does but the only difference being that the variables are passed in the url itself in GET but in POST they are appended to the HTTP header.
To get better security use encrypting in JS (only password or token+password). But that still can be hacked using rainbow tables for say MD5 or any other hashing technique.
SSL is the only way to achieve high security.