Description of problem: When using libpwquality via python-libpwquality, PWQuality fails to detect some dictionary words. Version-Release number of selected component (if applicable): $ LANG=en_US sudo yum info python-pwquality [...] Name : python-pwquality Arch : x86_64 Version : 1.2.1 Release : 1.fc18 Size : 20 k Repo : installed From repo : updates Summary : Python bindings for the libpwquality library URL : http://libpwquality.fedorahosted.org/ License : BSD or GPLv2+ Description : This is pwquality Python module that provides Python bindings : for the libpwquality library. These bindings can be used : for easy password quality checking and generation of random : pronounceable passwords from Python applications. How reproducible: Steps to Reproduce: 1. Open an interactive Python console: $ python 2. Execute tests: >>> pwquality.PWQSettings().check("egac9647") 7 >>> pwquality.PWQSettings().check("cage9647") 7 3. Notice that the word "cage" was not detected as part of the password, normal and reversed. Actual results: pwquality.PWQSettings().check() returns an entropy estimation. Expected results: A pwquality.PWQError like this: >>> pwquality.PWQSettings().check("password") Traceback (most recent call last): File "<stdin>", line 1, in <module> pwquality.PWQError: (-22, 'The password fails the dictionary check - it is based on a dictionary word') Additional info: Fedora Feature which libPWQualtiy serves: http://fedoraproject.org/wiki/Features/PasswordQualityChecking
The Package libpwquality describes itself to use cracklib dictionaries: $ LANG=en_US sudo yum info libpwquality [...] Installed Packages Name : libpwquality Arch : x86_64 Version : 1.2.1 Release : 1.fc18 Size : 218 k Repo : installed From repo : updates Summary : A library for password generation and password quality checking URL : http://libpwquality.fedorahosted.org/ License : BSD or GPLv2+ Description : This is a library for password quality checks and generation : of random passwords that pass the checks. : This library uses the cracklib and cracklib dictionaries : to perform some of the checks. The pwquality.conf manual page explains the dictpath setting to specify the path under which the dictionaries are found, not the specific dictionary to be used: $ man pwquality.conf [...] dictpath Path to the cracklib dictionaries. Default is to use the crack‐ lib default. The dictpath is not set in my pwquality.conf: $ tail -2 /etc/security/pwquality.conf # Path to the cracklib dictionaries. Default is to use the cracklib default. # dictpath = I have these cracklib dictionaries installed: $ ls -lh /usr/share/cracklib/*.pwd -rw-r--r--. 1 root root 230K 19. Dez 18:47 /usr/share/cracklib/cracklib-small.pwd -rw-r--r--. 1 root root 8,3M 19. Dez 18:47 /usr/share/cracklib/pw_dict.pwd CrackLib also fails to detect the dictionary word, normal and reversed: $ cracklib-check cage9687 cage9687: OK egac9687 egac9687: OK The description of the cracklib package hints that the package cracklib-dicts contains the actual dictionaries: $ LANG=en_US yum info cracklib [...] Name : cracklib Arch : x86_64 Version : 2.8.22 Release : 2.fc18 Size : 202 k Repo : installed From repo : koji-override-0 Summary : A password-checking library URL : http://sourceforge.net/projects/cracklib/ License : LGPLv2+ Description : CrackLib tests passwords to determine whether they match certain : security-oriented characteristics, with the purpose of stopping : users from choosing passwords that are easy to guess. CrackLib : performs several tests on passwords: it tries to generate words : from a username and gecos entry and checks those words against the : password; it checks for simplistic patterns in passwords; and it : checks for the password in a dictionary. : : CrackLib is actually a library containing a particular C function : which is used to check the password, as well as other C : functions. CrackLib is not a replacement for a passwd program; it : must be used in conjunction with an existing passwd program. : : Install the cracklib package if you need a program to check users' : passwords to see if they are at least minimally secure. If you : install CrackLib, you will also want to install the cracklib-dicts : package. The cracklib-dicts package describes /usr/share/dict/words to be the normal path for dictionaries, not /usr/share/cracklib/, where I found mine. $ LANG=en_US yum info cracklib-dicts [...] Installed Packages Name : cracklib-dicts Arch : x86_64 Version : 2.8.22 Release : 2.fc18 Size : 8.9 M Repo : installed From repo : koji-override-0 Summary : The standard CrackLib dictionaries URL : http://sourceforge.net/projects/cracklib/ License : LGPLv2+ Description : The cracklib-dicts package includes the CrackLib dictionaries. : CrackLib will need to use the dictionary appropriate to your : system, which is normally put in /usr/share/dict/words. : Cracklib-dicts also contains the utilities necessary for the : creation of new dictionaries. : : If you are installing CrackLib, you should also install : cracklib-dicts. The path referenced by the description of the cracklib-dicts packge is empty: $ LANG=en_US ls -lh /usr/share/dict/ total 0 There is is a link to the bigger dictionary (pw_dict.pwd) in the cracklib-dicts package: $ repoquery -lq cracklib-dicts | xargs ls -lh lrwxrwxrwx. 1 root root 36 9. Jan 18:14 /usr/lib64/cracklib_dict.hwm -> ../../usr/share/cracklib/pw_dict.hwm lrwxrwxrwx. 1 root root 36 9. Jan 18:14 /usr/lib64/cracklib_dict.pwd -> ../../usr/share/cracklib/pw_dict.pwd lrwxrwxrwx. 1 root root 36 9. Jan 18:14 /usr/lib64/cracklib_dict.pwi -> ../../usr/share/cracklib/pw_dict.pwi lrwxrwxrwx. 1 root root 15 9. Jan 18:14 /usr/sbin/mkdict -> cracklib-format lrwxrwxrwx. 1 root root 15 9. Jan 18:14 /usr/sbin/packer -> cracklib-packer -rw-r--r--. 1 root root 1,0K 19. Dez 18:47 /usr/share/cracklib/cracklib-small.hwm -rw-r--r--. 1 root root 230K 19. Dez 18:47 /usr/share/cracklib/cracklib-small.pwd -rw-r--r--. 1 root root 13K 19. Dez 18:47 /usr/share/cracklib/cracklib-small.pwi -rw-r--r--. 1 root root 1,0K 19. Dez 18:47 /usr/share/cracklib/pw_dict.hwm -rw-r--r--. 1 root root 8,3M 19. Dez 18:47 /usr/share/cracklib/pw_dict.pwd -rw-r--r--. 1 root root 448K 19. Dez 18:47 /usr/share/cracklib/pw_dict.pwi [...] There are python bindings for cracklib in the package cracklib-python. Using these I could specify the bigger dictionary to be used, but still got the same result: $ python >>> import cracklib >>> cracklib.FascistCheck("cage9573", "/usr/share/cracklib/pw_dict") 'cage9573' >>> cracklib.VeryFascistCheck("cage9573", "/usr/share/cracklib/pw_dict") 'cage9573' So it seems to me the dictionary contained in cracklib-dicts really does not contain "cage".
Created attachment 695943 [details] false negatives found using my script
I wrote a little python script to find more false negatives for words wrapped with numbers: import cracklib import nltk with open("false_negatives.words", "w") as false_negatives_file: for word in nltk.corpus.words.words() + nltk.corpus.stopwords.words('english') + ["cage"]: password = "2938" + word + "7384" try: cracklib.FascistCheck(password, "/usr/share/cracklib/pw_dict") except ValueError as exception: continue false_negatives_file.write("%s\n" % word) There were about 50.000 results: $ wc -l false_negatives.words 50118 false_negatives.words $ tail false_negatives.words dressmakership dressmakery dressmaking dressy drest drew drewite Dreyfusism Dreyfusist Both files (the script and the result) have been attached to this bugreport.
Created attachment 695944 [details] Script to test the cracklib detection using nltk corpus
Created attachment 695957 [details] Output of the script describing positives for other reasons than dictionary matching
Created attachment 695958 [details] Script to test the cracklib detection using nltk corpus
Created attachment 695959 [details] Script to test the cracklib detection using nltk corpus
Created attachment 695960 [details] false negatives found using my script
On second glance the problem is far worse. Almost all input words, wrapped in numbers get accepted as passwords except some that are rejected for other reasons than being a dictionary word. Updated script stdout and resultfile are attached.
I can confirm that the default dictionary contains both 'english' and 'cage', so that's not what's happening here. The cracklib package isn't catching dictionary entries with digits prepended and appended because, to be as literal as possible, that's not something cracklib checks for. The main checking function in cracklib is primarily concerned with people attempting to generate passwords by starting with dictionary words and performing some combination of operations on them in order to derive a password. It tries to catch cases of this by guessing what such a process might have started with in order to produce a supplied password, and checking if that guess is in its dictionary of known words. If that doesn't catch a candidate password that you think it should catch, then depending on why it didn't catch it, either the dictionary needs to be modified to include the base word, or the library needs to have rules added so that it'll notice that the candidate password could have been derived from a word in the dictionary that it already has. In this case, it appears the latter is called for.
Created attachment 699220 [details] check the candidate password after stripping out more character classes
Extending the library seems the right thing to do to me, since I consider passwords with appended and prepended digits fairly common. I know of someone who used to change the password for new accounts every year, because he heard it is bad to have the same password everywhere and one new password every year seemed manageable. He replaced the last two characters of the password from last year with the last two digits of the current year. m( Appending combinations of numbers and punctuation seems popular, too: http://xkcd.com/936/
I'd say that only a limited amount of digits should be stripped otherwise we would reject passwords that indeed contain a dictionary word but they are fairly safe anyway because they contain many additional digits that cannot be easily bruteforced.
That's a valid concern. Jan expressed a similar one in the upstream ticket tracker. That would require more involved changes, though, as the library doesn't currently have rules for that, and I don't have a clear idea of how they'd be expected to work. And without a very clear idea of that, I think we're just talking about reimplementing the passwdqc package, poorly.
This package has changed ownership in the Fedora Package Database. Reassigning to the new owner of this component.
This message is a reminder that Fedora 18 is nearing its end of life. Approximately 4 (four) weeks from now Fedora will stop maintaining and issuing updates for Fedora 18. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as WONTFIX if it remains open with a Fedora 'version' of '18'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version prior to Fedora 18's end of life. Thank you for reporting this issue and we are sorry that we may not be able to fix it before Fedora 18 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior to Fedora 18's end of life. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
Issue still present in Fedora 19.
This message is a notice that Fedora 19 is now at end of life. Fedora has stopped maintaining and issuing updates for Fedora 19. It is Fedora's policy to close all bug reports from releases that are no longer maintained. Approximately 4 (four) weeks from now this bug will be closed as EOL if it remains open with a Fedora 'version' of '19'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora 19 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior this bug is closed as described in the policy above. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
reproducible with cracklib-2.9.1-5.fc21.x86_64
This message is a reminder that Fedora 21 is nearing its end of life. Approximately 4 (four) weeks from now Fedora will stop maintaining and issuing updates for Fedora 21. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a Fedora 'version' of '21'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora 21 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior this bug is closed as described in the policy above. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
reproducible with cracklib-2.9.1-5.fc22.x86_64
Fedora 22 changed to end-of-life (EOL) status on 2016-07-19. Fedora 22 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora please feel free to reopen this bug against that version. If you are unable to reopen this bug, please file a new report against the current release. If you experience problems, please add a comment to this bug. Thank you for reporting this bug and we are sorry it could not be fixed.
Still an issue with cracklib-2.9.6-2.fc24.x86_64 and libpwquality-1.3.0-4.fc24.x86_64
I am not planning to work on this cracklib enhancement in near future. It would be best tracked in upstream cracklib.