Bug 909738 - python-pwquality does not detect some dictionary words in passwords
Summary: python-pwquality does not detect some dictionary words in passwords
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: cracklib
Version: 24
Hardware: x86_64
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Tomas Mraz
QA Contact: Fedora Extras Quality Assurance
URL: https://sourceforge.net/p/cracklib/fe...
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2013-02-10 19:51 UTC by Bengt Lüers
Modified: 2016-07-19 12:09 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2016-07-19 12:09:09 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
false negatives found using my script (920.00 KB, application/octet-stream)
2013-02-10 22:39 UTC, Bengt Lüers
no flags Details
Script to test the cracklib detection using nltk corpus (431 bytes, text/x-python)
2013-02-10 22:42 UTC, Bengt Lüers
no flags Details
Output of the script describing positives for other reasons than dictionary matching (8.41 KB, text/plain)
2013-02-11 00:18 UTC, Bengt Lüers
no flags Details
Script to test the cracklib detection using nltk corpus (469 bytes, text/plain)
2013-02-11 00:23 UTC, Bengt Lüers
no flags Details
Script to test the cracklib detection using nltk corpus (469 bytes, text/x-python)
2013-02-11 00:24 UTC, Bengt Lüers
no flags Details
false negatives found using my script (2.38 MB, application/octet-stream)
2013-02-11 00:26 UTC, Bengt Lüers
no flags Details
check the candidate password after stripping out more character classes (916 bytes, patch)
2013-02-18 23:26 UTC, Nalin Dahyabhai
no flags Details | Diff

Description Bengt Lüers 2013-02-10 19:51:53 UTC
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

Comment 1 Bengt Lüers 2013-02-10 22:06:04 UTC
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".

Comment 2 Bengt Lüers 2013-02-10 22:39:07 UTC
Created attachment 695943 [details]
false negatives found using my script

Comment 3 Bengt Lüers 2013-02-10 22:42:06 UTC
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.

Comment 4 Bengt Lüers 2013-02-10 22:42:52 UTC
Created attachment 695944 [details]
Script to test the cracklib detection using nltk corpus

Comment 5 Bengt Lüers 2013-02-11 00:18:21 UTC
Created attachment 695957 [details]
Output of the script describing positives for other reasons than dictionary matching

Comment 6 Bengt Lüers 2013-02-11 00:23:20 UTC
Created attachment 695958 [details]
Script to test the cracklib detection using nltk corpus

Comment 7 Bengt Lüers 2013-02-11 00:24:28 UTC
Created attachment 695959 [details]
Script to test the cracklib detection using nltk corpus

Comment 8 Bengt Lüers 2013-02-11 00:26:04 UTC
Created attachment 695960 [details]
false negatives found using my script

Comment 9 Bengt Lüers 2013-02-11 00:44:48 UTC
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.

Comment 10 Nalin Dahyabhai 2013-02-18 23:10:57 UTC
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.

Comment 11 Nalin Dahyabhai 2013-02-18 23:26:27 UTC
Created attachment 699220 [details]
check the candidate password after stripping out more character classes

Comment 12 Bengt Lüers 2013-02-19 00:44:52 UTC
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/

Comment 13 Tomas Mraz 2013-02-19 07:24:18 UTC
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.

Comment 14 Nalin Dahyabhai 2013-02-19 19:43:18 UTC
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.

Comment 15 Fedora Admin XMLRPC Client 2013-06-10 17:34:56 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.

Comment 16 Fedora End Of Life 2013-12-21 15:22:01 UTC
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.

Comment 17 Alicja Kario 2014-01-03 11:35:33 UTC
Issue still present in Fedora 19.

Comment 18 Fedora End Of Life 2015-01-09 22:04:03 UTC
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.

Comment 19 Alicja Kario 2015-01-12 12:46:50 UTC
reproducible with cracklib-2.9.1-5.fc21.x86_64

Comment 20 Fedora End Of Life 2015-11-04 15:43:59 UTC
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.

Comment 21 Alicja Kario 2015-11-05 11:33:21 UTC
reproducible with cracklib-2.9.1-5.fc22.x86_64

Comment 22 Fedora End Of Life 2016-07-19 10:06:51 UTC
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.

Comment 23 Alicja Kario 2016-07-19 11:51:27 UTC
Still an issue with cracklib-2.9.6-2.fc24.x86_64 and libpwquality-1.3.0-4.fc24.x86_64

Comment 24 Tomas Mraz 2016-07-19 12:09:09 UTC
I am not planning to work on this cracklib enhancement in near future. It would be best tracked in upstream cracklib.


Note You need to log in before you can comment on or make changes to this bug.