Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d325fb4
Fixing missing type definition that caused a compilation error
blaseur Aug 2, 2017
d427cdc
Changes to make typescript successfully compile on my machine
jtan189 Feb 20, 2019
c0d63a1
Added gitignore for password meter generated files.
jtan189 Feb 20, 2019
cb134ef
Implemented minNN guess number cutoff in typescript
jtan189 Feb 22, 2019
5f4283c
Added blacklist dimension support to password meter, including substr…
jtan189 Feb 28, 2019
ef84fee
Moved bloom-filter-js library to js/ dir.
jtan189 Feb 28, 2019
148254b
Added HIBP check to password meter.
jtan189 Feb 28, 2019
4e6b98c
Don't ignore transcompiled file.
jtan189 Feb 28, 2019
675e92e
comment tweak
jtan189 Feb 28, 2019
961d1a8
Consolidate scaling factor logic for meter stringency. Set to 67/12 e…
jtan189 Mar 1, 2019
7bba1b9
Fixed bug where interface would become unusable after clicking specif…
jtan189 Mar 1, 2019
3b87566
Added config option for randomizing the order of character classes in…
jtan189 Mar 4, 2019
a023593
Cleaned up and commented code.
jtan189 Mar 4, 2019
ecb32ec
Updated compiled js
jtan189 Mar 4, 2019
f94e4bb
Added ID fields and event triggers needed for userstudy instrumentation.
jtan189 Mar 6, 2019
08218a4
Changes to facilitate user study instrumentation.
jtan189 Mar 8, 2019
ef77b4e
Fixed bug where bar would not revert to reflect pre-concrete-password…
jtan189 Mar 8, 2019
7d1d74c
Updated password meter config in example html file.
jtan189 Mar 8, 2019
87eb0f4
Added option for specifying a URL prefix where static javascript file…
jtan189 Mar 19, 2019
09c9a85
When triggering event for password field changes, also pass the NN an…
jtan189 Apr 19, 2019
1c43280
Trigger blacklistedpassword event and pass relevant data.
jtan189 Apr 25, 2019
bc6797a
Instrumenting all compliance events
jtan189 Apr 25, 2019
461f9c3
debug
jtan189 Apr 25, 2019
12ba77d
idk
jtan189 Apr 25, 2019
e6f63d2
Clean up code
jtan189 Apr 26, 2019
e24832f
Remove console logging
jtan189 Jun 12, 2019
e7ef151
Added latest browserified password meter js.
jtan189 Jun 12, 2019
0dbdd59
Better debug logging.
jtan189 Jun 13, 2019
4f77f7b
Print debug info
jtan189 Jun 19, 2019
82a7617
Stop rev controlling compiled password meter js.
jtan189 Jun 19, 2019
0657951
neural network client function names changed. also more debug calls
jtan189 Jun 27, 2019
5a2fe9e
More debugging
jtan189 Jul 1, 2019
0d6fc86
Add in call to print out prefix probability to console.
jtan189 Jul 2, 2019
f8f8052
Don't load blacklists if not needed.
jtan189 Jul 3, 2019
e9ffb67
Change how NN/heuristic score drive the bar meter fill. Other cosmeti…
jtan189 Jul 4, 2019
9c93e6c
use heuristic score as a fallback
jtan189 Jul 5, 2019
f12110e
Don't print debug info to console in production
jtan189 Jul 15, 2019
73ec04d
Bug fix. var used before defined
jtan189 Oct 1, 2019
96e5fdc
Added script to decompress dictionaries used in the password meter.
jtan189 Jun 30, 2020
d31629c
Added decompress script
jtan189 Jul 7, 2020
ddde9bf
Bump version. Add license information for JavaScript libraries that w…
jtan189 Dec 15, 2020
e87cad3
Remove file (has an extra space at the end)
jtan189 Dec 15, 2020
f420557
Modify example code to use new minimum-strength and blocklist require…
jtan189 Dec 16, 2020
d275b3c
Clean up documentation. Move feedback about prohibited leaked passwor…
jtan189 Jan 13, 2021
e6b668c
Update PasswordMeter.js with newly transcompiled version.
jtan189 Jan 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
src/node_modules
src/package-lock.json
src/PasswordMeter.js
src/misc_scripts/*.txt

# emacs temp files
*~
34 changes: 16 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Password Meter

This project implements a data-driven password meter. Its effects on password security and usability were evaluated in the following publication: Ur et al. "Design and Evaluation of a Data-Driven Password Meter." In the Proceedings of CHI, 2017. https://dl.acm.org/citation.cfm?id=3026050
This project implements a data-driven password meter. Its effects on password security and usability were evaluated in the following publication: Ur et al. "Design and Evaluation of a Data-Driven Password Meter." In the Proceedings of CHI, 2017. https://dl.acm.org/citation.cfm?id=3026050.

The project is written in TypeScript, which transcompiles to JavaScript.
The original implementation of this password meter ([v1.0](https://github.com/cupslab/password_meter/releases/tag/v1.0)) has been extended to include additional support for minimum-strength and blocklist requirements ([v2.0](https://github.com/cupslab/password_meter/releases/tag/v2.0)). Password-policy configurations based on these new requirement types were evaluated in the following publication: J. Tan, L. Bauer, N. Christin, and L. F. Cranor. "Practical recommendations for stronger, more usable passwords combining minimum-strength, minimum-length, and blocklist requirements." In the Proceedings of CCS, 2020. https://dl.acm.org/doi/10.1145/3372297.3417882

An online demo of the meter is available at https://cups.cs.cmu.edu/meter/
This project uses the [Pwned Passwords API](https://haveibeenpwned.com/API/v3#PwnedPasswords) to check for previously leaked passwords.

The majority of this project is written in TypeScript, which transcompiles to JavaScript. Two JavaScript libraries ([hibp-js](https://github.com/mehdibo/hibp-js) and [bloom-filter-js](https://github.com/bbondy/bloom-filter-js)) were also used in this project, with minor modifications.

An online demo of the meter is available at https://cups.cs.cmu.edu/meter2/


## Contact
Expand All @@ -14,19 +18,17 @@ [email protected]

## Deploying (minimal customization required)

Many potential users of the meter will not need to re-transcompile from TypeScript to JavaScript. Instead, such users can use the code in the /example directory, which contains a ready-to-run environment for the password meter. The primary HTML file is index.html.

We expect that most people who take advantage of the example files will nonetheless edit three sets of common configurations that are made in "passwordMeterConfig" within the /example/index.html file:
Many potential users of the meter will not need to re-transcompile from TypeScript to JavaScript. Instead, such users can use the code in the /example directory, which contains a ready-to-run environment for the password meter. The primary HTML file is index.html. The password-policy requirements and other meter configuration can be set by editing parameters defined in config_policy_meter.js.

1) "ignoredWords" should be updated to contain a list of site-specific words that should count for nothing in the password. We currently provide a small set of examples specific to CMU.
We expect that most people who take advantage of the example files will edit two sets of common configurations that are made available in config_policy_meter.js:

2) A number of variables (length, classCount, classRequire, classAllow, forbidPasswords, forbidChars, repeatChars, and usernameDifference) define the site's mandated password-composition policy. In the example file, it is set to require only that passwords contain 8 or more characters and are not one of 25 extremely common passwords. The other dimensions are currently set to inactive, but can be enabled by simply editing these variables.
1) "domainSpecificWords" should be updated to contain a list of site-specific words that should count for nothing in the password. We currently provide a small set of examples specific to CMU.

3) An additional variable (forbiddenPasswords) specifies whether or not to forbid passwords on a larger blacklist of ~100,000 common passwords taken from Mark Burnett's Xato.net corpus. In our example, it is currently set to active. For our research supporting this decision, please see: http://www.blaseur.com/papers/usec2017-blacklists.pdf
2) A number of variables (minLogNnGuessNum, length, prohibitKnownLeaked, etc.) define the site's mandated password-composition policy. In the example file, it is set to require a 1c12+NN10 policy that also prohibits known leaked passwords reported by the Pwned Passwords API. The other dimensions are currently set to inactive, but can be enabled by simply editing these variables.

Beyond these configuration decisions, we expect that people who deploy our meter will edit the layout in /example/index.html and /example/config.css

Note that running the meter's code locally (e.g., from your computer's local hard disk) with browsers' default settings will not load the dictionary files (dictionary-*), and as a result no feedback will be given based on the use of dictionary words or common passwords, nor will the blacklist be active. In contrast, if loaded from a web server (e.g., Apache), these files will be loaded correctly.
Note that running the meter's code locally (e.g., from your computer's local hard disk) with browsers' default settings will not load the dictionary files (dictionary-*), and as a result no feedback will be given based on the use of dictionary words or common passwords. In contrast, if loaded from a web server (e.g., Apache), these files will be loaded correctly.

Note also that the meter expects all files to be in the same directory as each other.

Expand All @@ -38,7 +40,7 @@ Note also that the meter expects all files to be in the same directory as each o
* Then run npm run do-browserify to generate the PasswordMeter.js file
* Place the PasswordMeter.js file with the other web files (i.e., in the /example directory)

Finally, the neural network that estimates password strength needs to be trained for a site's particular password-composition policy. The parameter files must be provided in the configuration. The example neural network files we provide (/example/basic_3M.*) are trained for a 1class8 policy and will not provide accurate strength estimates for passwords created under different policies. For more detail on training the neural network, please see https://github.com/cupslab/neural_network_cracking
Finally, the neural network that estimates password strength needs to be trained for a site's particular password-composition policy. The parameter files must be provided in the configuration. The example neural network files we provide (/example/tfjs_1c8/*) are trained for a 1class8 policy and may not provide accurate strength estimates for passwords created under different policies. For more detail on training the neural network, please see https://github.com/cupslab/neural_network_cracking


## Dependencies
Expand All @@ -65,17 +67,15 @@ To set up the meter, define the following global variables for the above depende

We label each file with its intended purpose within the meter: main file; neural network computation; visual layout; dictionary; required external library

* **basic_3M.info_and_guess_numbers.no_bloomfilter.json** (Neural network computation) A JSON encoding of a pre-computed mapping of estimating a password's guess number from its probability by using Monte Carlo methods. This is a companion file to the one that follows. This file is for a 1class8 policy, and for other policies should be retrained using https://github.com/cupslab/neural_network_cracking

* **basic_3M.weight_arch.quantized.fixed_point1000.zigzag.nospace.json** (Neural network computation) A JSON encoding of the artificial neural network we computed using a 3~MB (before optimizations and compression) network in which probabilities have been quantized and stored used fixed-point encoding and ZigZag encoding. The weights have been quantized to three decimal digits, as well. This model ignores letter capitalization, which must be post-processed. This file is for a 1class8 policy, and for other policies should be retrained using https://github.com/cupslab/neural_network_cracking
* **tfjs_1c8/** Contains files describing TensorFlowJS saved model parameters, architecture, and JSON encoding of a pre-computed mapping of estimating a password's guess number from its probability by using Monte Carlo methods. These files are for a 1class8 policy, and for other policies should be retrained using https://github.com/cupslab/neural_network_cracking

* **bootstrap.min.css** (Required external library) The Bootstrap library (version 3.3.6), minified http://getbootstrap.com/

* **bootstrap.min.js** (Required external library) The Bootstrap library (version 3.3.6), minified http://getbootstrap.com/

* **config.css** (Visual layout) The primary configuration settings for the meter's visual design are located in this file. These settings include colors, fonts, sizes, and border radii.

* **dictionary-blacklist1c8-compressed.txt** (Dictionary) An LZW compressed version of the 96,480 passwords containing at least 8 characters that appear in the Xato.net corpus of passwords at least four times. These form our optional blacklist of common 1class8 passwords.
* **dictionary-blacklist1c8-compressed.txt** (Dictionary) An LZW compressed version of the 96,480 passwords containing at least 8 characters that appear in the Xato.net corpus of passwords at least four times.

* **dictionary-englishwords-compressed.txt** (Dictionary) An LZW compressed version of 80,031 frequently used English words taken from the intersection of the BYU Corpus of Contemporary American English (COCA) and the UNIX dictionary.

Expand Down Expand Up @@ -104,12 +104,10 @@ We label each file with its intended purpose within the meter: main file; neural

We tested and iteratively updated many prioritizations of the feedback we provided users in the standard meter. For each advanced heuristic, if the associated function has feedback relevant to that particular password, it returns a non-empty string for both publicFeedback and sensitiveFeedback. If it does not have feedback, which occurs when that heuristic does not indicate a predictable pattern, it returns the empty string. We traverse the list of functions in descending priority for the first (up to) three pieces of feedback to give the user. If, however, our scoring functions rate the password such that its score fills the bar, we ignore all text feedback and tell the user that his or her password appears strong.

The list of functions that provide feedback, in descending order of priority, is as follows:
The list of functions that provide feedback, in descending order of priority, includes:

* **contextual()** returns the password after removing the longest string of five or more contiguous characters of the password that overlap (case-insensitive) with the user's chosen username. If there is no such overlap, the function returns the original password.

* **blacklist()** returns the password after removing all occurences of a service-specific substring blacklist of terms very closely related to the service. The site-specific blacklist for Carnegie Mellon, for instance, might contain terms like "carnegie," "mellon," "cmu," "education," "tartans," "andrew," and other terms closely associated with the institution. If there is no such overlap, the function returns the original password.

* **combinedDictCheck()** returns three values. First, it returns the number of characters in the password contained from any of the following sources: the 234 most popular pet names; the 2,500 most popular male and 2,500 most popular female names according to the U.S. census; the top 50,000 three-word phrases used on Wikipedia; frequently used English words taken from the intersection of the BYU Corpus of Contemporary American English (COCA) 100,000 most frequent 1-grams and the Unix dictionary; the 100,000 top single words (1-grams) used on Wikipedia. For each list, we removed those that were internal duplicates (e.g., some common male and female names are identical, and some distinct three-word phrases appear the same after removing spaces and punctuation), and we also removed any that appeared on a list above it (following the order listed above) or was a keyboard pattern, string of a single character repeated, or alphabetic/numeric sequence. In addition to checking for these words in a case-insensitive manner, we also evaluate whether a transformation of these words is present by reversing all instances of the 10 most common character substitutions in passwords. For instance, if the user's password contains a "4," we will evaluate whether replacing that character by an "a" or "for" leads to the password containing a dictionary word. The commonness of the substitution (what percentage of all substitutions follow that particular rule is the second value returned by this function. It also returns the number of distinct dictionary tokens (e.g., a password that contains two separate dictionary words contains two tokens) as the third value.

* **keyboardPatterns()** returns the total number of characters of a password contained in one or more keyboard patterns. We define a keyboard pattern to be 4+ characters in a row for which the inter-key x-y coordinate change on a physical QWERTY keyboard layout is the same. For instance, "qetu" would be a keyboard pattern because each inter-key coordinate change is 2 keys to the right horizontally, and no change vertically. Note that we only consider a string to be a keyboard pattern if the inter-key vector on a QWERTY keyboard is identical. While some keyboard patterns in practice could include snake-like bends, they would lead to many false positives (e.g., "reds," "polk") and common keyboard patterns of that type would be identified as a common password substring, so we do not look for them.
Expand Down
3 changes: 3 additions & 0 deletions example/LICENSES
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
lz-string was licensed under the WTFPL
bootstrap was licensed under the MIT license
jquery was licensed under the Apache license
hibp.js was licensed under the MIT license
bloom-filter.js was licensed under the Mozilla Public License 2.0
There are no licensing or attribution requirements on the Pwned Passwords API.

Phrase and word corpora were derived from the following sources:
-Wikipedia database download (dual licensed under GFDL and CC-BY-SA)
Expand Down
Loading