0

We have a site where we're using zxcvbn by Dropbox to inform users of their password strength, however, we've been getting occasional reports that it doesn't work.

Turns out that these users (reasonably rare) are accessing our website from their workplace which has a strict corporate firewall policy, because the js file contains swearwords and NSFW words (to mark the password as insecure if it contains these commonly used words), the whole JS file is being blocked from loading.

The rest of our site loads fine, including other JS files.

How could we encrypt or minify this js file to a point where it didn't get blocked for having "bad" words in the request, but be successfully decrypted at the client side to actually do it's job and detect unsafe passwords?

This JS Fiddle will (sort of) demonstrate the problem: https://jsfiddle.net/0cgap96m/3/

<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js" integrity="sha512-TZlMGFY9xKj38t/5m2FzJ+RM/aD5alMHDe26p0mYUMoCF5G7ibfHUQILq0qQPV3wlsnCwL+TPRNK4vIWGLOkUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="test">

</div>
window.onload = function(){
    var name = prompt("Put in a fake password to test?");
        var passwordStrength = zxcvbn(name);

    document.getElementById('test').innerHTML = JSON.stringify(passwordStrength);
};

That should work fine normally - now try blocking https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js using an adblocker or something, and it'll obviously start failing. This is essentially what's happening for the users, but it's blocked by their corporate firewall rather than a local adblocker.

BT643
  • 3,495
  • 5
  • 34
  • 55

3 Answers3

2

To confound the filter, you can try substituting the literal characters with JavaScript's syntax for the unicode representation of those characters.

This works even with identifiers!

var f\u006F\u006F = 'b\u0061\u0072';
console.log(foo); // outputs: bar
Wyck
  • 10,311
  • 6
  • 39
  • 60
1

You could download the built js file and alter the passwords list, to split up the string in between the NSFW words. Then your copy of the library instead.

In zxcvbn.js the insecure words are defined like this (shortened here for this example)

var frequency_lists;frequency_lists=
{passwords:"123456,password,eatshit,goodluck,starcraft"}

So, by doing this:

var frequency_lists;frequency_lists=
{passwords:"123456,password,eatsh" + "it,goodluck,starcraft"}

a firewall scanning for swear words shouldn't recognize that as a swear anymore.

EDIT: I might suggest a PR to their repo to have their code build with this format might be a better solution with the additional benefit of solving the issue for anyone else using this library, as well as allowing you to update to newer versions. But from quickly looking at the github, I see you'd need to be familiar with coffeescript + python. The original solution is much quicker and doesn't require knowledge in other languages.

Michael S
  • 726
  • 1
  • 10
  • 23
  • Nice, hadn't thought of this :) will try this and the above answer (maybe even both combined just to be sure!) when I can get back onto it. Thank you – BT643 May 19 '21 at 15:10
0

how about a simple error handling client-side and a proper validation server-side? Actually, you don't even need the validation, but if the typed/submitted password is sent to evaluation on server-side when client-side is not available may cover all the bases you need.

And if you need validation, well you should have it server-side, too, anyway, right?

formigarafa
  • 377
  • 1
  • 11