This question already has an answer here:

I have a web application and I have implemented a check on the browser to ensure that a user sets only strong passwords. A company that we have called to check security vulnerabilities pointed out that this is not enough because using some hacking a user can ignore the check and set a weak password.

I do not understand how this can be a security vulnerability. Why would someone hack the security check just to set a weak password? Someone expert enough to hack the web application will understand the importance of using a strong password.

The only reason I can think is that someone, very very lazy, can decide to hack the check just to have an easier password to remember. I do not know how likely is this case.

I know that you cannot enforce a strong password on the client side and that if you are required to have a strong password in any circumstance, you have to do it on the server side.

My point is: given that, to have an acceptable user experience, we have to do the check on the client side, there has to be a good reason, a real use case that creates a possible vulnerability to justify a duplication of the check on the server side.

Reading the answers, so far, it seems that the only use case that can create a vulnerability is when the javascript does not work. This does not seem a problem for me because the submit button is disabled by default.

marked as duplicate by Xander, CaffeineAddiction, Steffen Ullrich, Anders, André Borie Apr 28 '17 at 12:48

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 11
    You can always ask these companies for clarification. Ask them for an attack scenario. I'm guessing it's a mistake from their side. – Silver Apr 27 '17 at 7:51
  • 10
    If you have the same requirements on both front and back end then there is no confusion to your users and no confusion to your system. – LukeXF Apr 27 '17 at 14:16
  • 2
    I think that it is not a duplicate of the other question because it is asking something more specific. I knew already the answers given in that question. I I knew that you cannot enforce a password strength on the client side, but I wanted to know in what circumstances this can be a security vulnerability. – Marco Altieri Apr 27 '17 at 17:23
  • 5
    "Why isn't a client-side password check considered secure?" -> "Why isn't a client-side password strength check considered secure?" – ErikE Apr 27 '17 at 20:59
  • 1
    Part of the answer depends on what you do with a weak password. Do you reject it? Do you warn the user and let them set it anyway? – jpmc26 Apr 28 '17 at 3:08
up vote 63 down vote accepted

You’re assuming that the check is bypassed on purpose. It could be the case that someone is using a browser which fails to handle the script properly or with scripts disabled, possibly even without knowing this.

You seem to have a reason for people to use strong passwords. If you do so, why accept that people can bypass it?

Client-side validation can be helpful from a usability perspective, but if you decide that a minimum password strength is required, you should enforce it by implementing it server-side.

  • 9
    Exactly. If it's used more as a guideline, but is not strictly needed, doing it on the client is fine. For my website I "require" users to have a password longer than 5 characters, which must not all be numbers (date of birth...). But if the check isn't executed for some reason, the server is perfectly fine accepting it. Unless you handle sensitive data, this should be just fine. – Stephan Bijzitter Apr 27 '17 at 11:14
  • 9
    @MarcoAltieri it is trivial to block your scripts but still use javascript to enable the submit button. Someone could also manually post to your form's target. – 0xFF Apr 27 '17 at 13:06
  • 5
    @MarcoAltieri, a rule of thumb I use is to assume that a sufficiently malicious/incompetent user is just not using a browser at all, and all they will ever do is send HTTP requests straight to my backend regardless of what I attempt to tell them to do. – ymbirtt Apr 27 '17 at 13:29
  • 2
    To indicate just how trivial @fhl's suggestion is -- I've done it, and I don't write js, or code for the web in any ther way. I've used selective commenting of js in a browser (a broken validation that would never pass) and I've written a python script to submit a form with no browser (for my convenience -- a tedious wifi portal screen). – Chris H Apr 27 '17 at 13:54
  • 4
    @fhl The question is: why would someone do it ? Just to set a weak password? It would be easier for this person to write a strong password and then write it down on a post-it, as someone as already pointed out. – Marco Altieri Apr 27 '17 at 18:14

The rule when writing a server application is simply never trust what comes from client. Checks done client side are great as they allow a nice user experience with nice popups and immediate display. But as anything can happen, from a disabled javascript browser to a user using a scripting language to simulate a browser, all checks must be done (again) server side.

If strong passwords are just recommended, do what you want, if they are a requirement, you must implement a check server side.

BTW: you as the dev can propose solutions, but the client does express requirements. If you do not agree with them you can ask for clarification and propose other ways, but in the end the client will decide.

If the user MUST set a strong password, checking the password strength only on the client side is a vulnerability.

Example

If you work in a big company and you have to change your password every 2 or 3 months a few people will start bypassing the client-side check of password strength to use shorter or better to memorize passwords. If these passwords are used to derive cryptographic keys, e.g. for multi-user encryption of files, it becomes horrible...

Solution

Always check the password strength at the server and optionally check the password strength at the client to decrease requests to the server.

Recommended library: ZXCVBN

  • Uses pattern matching and checks for most used passwords to estimate password strength.
  • Is available in multiple programing languages
  • Are you saying that there will be users who will really take the time to hack the check just to set a weak password ? It seems so unlikely to me. By the way, I like the library you linked! – Marco Altieri Apr 27 '17 at 8:25
  • I do not know how critical this vulnerability is for your application. But checking the password strength at the server is best practice and it shouldn't be too much work to implement. – nebulak Apr 27 '17 at 8:35
  • 7
    My two cents: checking the password strength on the client is a UX feature, not a security feature. Never trust the client, therefore the same check has to be done on the server regardless – Alex Apr 27 '17 at 8:47
  • 3
    Never validate anything on the client! Never! You can additionally check input on the client for increased usability, but you always have to validate it on the server. The client belongs to the user, so client only validation is equal to no validation but just telling the users they have to use a strong password. Wonder how well that would work? – Josef Apr 27 '17 at 8:47
  • @MarcoAltieri the whole "you must set a new pasword that you've got little chance of remembering" thing could be designed to make your users look for workarounds. Or post-its. Particularly if their perception is that it's uneccesary hassle. – Chris H Apr 27 '17 at 14:01

Building on Teun Vink's answer, there are a few real world scenarios where a user may accidentally bypass the security check.

Let's say a user downloads an adblocker like Adblock Plus or uBlock Origin. Then, due to the scripts being misconfigured, one of these adblockers accidentally blocks the script you were using to verify password security. Now the user can enter 1234 as a password without any server-side checks in place to prevent it.

Or alternatively, maybe local caching gave the user an older version of your script. Maybe they've saved your webpage as a static HTML file on their desktop. Maybe the user's PC has a virus that altered the content of your script. As the common saying goes...

Never trust the user.

Edit: See also "Cannot save profile when maps.googleapis.com is blocked" for a great example of why you should never trust the user.

  • If the javascript is blocked, the submit button won't be enabled because it is disabled by default. – Marco Altieri Apr 27 '17 at 17:30
  • 4
    @MarcoAltieri Adblock doesn't work by blocking JavaScript in its entirety. It works by blocking specific scripts as defined by the user. – Steven M. Vascellaro Apr 27 '17 at 17:36
  • It seems unlikely that the adblock will be able to selectively execute parts of my script ending up enabling the button even if the check has not been executed. It is all in the same script. – Marco Altieri Apr 27 '17 at 17:43
  • 3
    @MarcoAltieri I agree. The scenario I've described is very unlikely. In fact, unlikely is the key word here. When considering security, if there's a chance of something happening, even if it's extremely unlikely, you typically want to make sure your system is prepared if it happens. – Steven M. Vascellaro Apr 27 '17 at 17:47
  • 1
    @paj28 they are. Even SE is a pain to use in countries like china (referring to a past experience i had maybe SE fixed this already) – wannabeLearner Apr 28 '17 at 10:35

You mention that both the check & the enabling of the submit button are one script, so it's safe even if some scripts are loaded and others aren't. How sure are you that those two functions will always be in the same script?

I suppose what I'm saying is that it sounds like, as things stand right now, it would mean someone intentionally doing something they know is a bad idea in order for them to get a bad password, and you're ok with that; you're trying to prevent accidents, not intentional stupidity.

The thing that worries me is that if this script ever gets refactored & split up, or intentional stupidity becomes your problem, or some attacker writes a client side script ostensibly to help people,... then you're in trouble.

One possible problem is that it only takes one wise guy (that might be knowledgeable enough to use that technique to use a password that fails the checker and is nevertheless secure!) to find a way to hack it - and distribute the hack to a few other people (that s/he probably deems responsible enough) that will eventually give it to people against whose lack of security competence the solution was supposed to guard.

  • This seems a real case that can create a vulnerability. Thanks – Marco Altieri Apr 29 '17 at 7:40

Enforce rules on the server

Whatever rules you set up, they must be enforced at the server level in every case. This is true for password setting, and for mandatory fields in forms for example (e.g. if a phone number is required when signing up, it should be checked in the server).

Help your user on the client

Whatever rules you enforce on the server, you should help your user as much as possible by giving help on the client.

It can be just explanation, stars next to mandatory fields, showing errors before you submit forms, ...

But enforce rules on the server

But in any cases, you cannot rely on the client at all. Some people will block JS. Some people will block flash. At some point you may open your API to third parties, which may or may not enforce your rules for you.

I, for one, have at times re-activated JS-blocked buttons because I found that client-enforced rules were ridiculous (e.g. your password must be exactly 8 characters, including exactly 1 capital letter, 1 number, and 1 special character in (!@#$%&*?) only), hoping that the server was not enforcing those rules (which often it didn't).

If your specifications are to have a precise set of rules on your users' password, then having the validation client-side does not meet the specifications.

I expect the pen test firm are applying a general principle here "do all validation server-side" without considering the specific case in much detail.

In your scenario, where JavaScript cannot be disabled, I see no practical security risk. There may be a non-technical risk if you need complex passwords for a regulatory requirement (e.g. PCI-DSS).

Not the answer you're looking for? Browse other questions tagged or ask your own question.