From dev-return-19730-apmail-apr-dev-archive=apr.apache.org@apr.apache.org Fri Feb 01 21:34:51 2008 Return-Path: Delivered-To: apmail-apr-dev-archive@www.apache.org Received: (qmail 85839 invoked from network); 1 Feb 2008 21:34:51 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Feb 2008 21:34:51 -0000 Received: (qmail 54560 invoked by uid 500); 1 Feb 2008 21:34:40 -0000 Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 54517 invoked by uid 500); 1 Feb 2008 21:34:40 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Id: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 54506 invoked by uid 99); 1 Feb 2008 21:34:40 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Feb 2008 13:34:40 -0800 X-ASF-Spam-Status: No, hits=3.2 required=10.0 tests=HTML_MESSAGE,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [209.85.198.191] (HELO rv-out-0910.google.com) (209.85.198.191) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Feb 2008 21:34:11 +0000 Received: by rv-out-0910.google.com with SMTP id g13so999522rvb.43 for ; Fri, 01 Feb 2008 13:34:16 -0800 (PST) Received: by 10.141.43.5 with SMTP id v5mr2820184rvj.216.1201901656027; Fri, 01 Feb 2008 13:34:16 -0800 (PST) Received: by 10.141.201.17 with HTTP; Fri, 1 Feb 2008 13:34:15 -0800 (PST) Message-ID: Date: Fri, 1 Feb 2008 16:34:15 -0500 From: "Scott Sanders" Sender: scott@jssjr.com To: dev@apr.apache.org Subject: Re: Possible bug in apr_dbd_mysql In-Reply-To: <47A28793.7080205@bellatlantic.net> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_22789_15027156.1201901656020" References: <47A28793.7080205@bellatlantic.net> X-Google-Sender-Auth: 452e03f4b4a6be88 X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_22789_15027156.1201901656020 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline On 1/31/08, Tom Donovan wrote: > > Scott Sanders wrote: > > Hi, > > > > After much frustration I was able to get apr_dbd_mysql compiled and > > working on my machine. However, when testing the module I believe I > ... > > but in my environment that's OK. My initial apache config to secure this > > section of the site with basic auth set the AuthDBDUserPWQuery to > > "SELECT pwd2 FROM users WHERE email=%s AND active=1". This worked and > > prevented invalid users (and inactive users) from authenticating, but if > > the pwd2 field was empty then any password would succeed. If pwd2 was > > NULL then the user was rejected, and if pwd2 had a string in it the user > > was rejected (excepting, of course, when pwd2 had the proper encrypted > > content). > > I find that only an empty password works when AuthDBDUserPWQuery retrieves > a value of ''. Entering > a non-empty password (in Firefox) gives a "Password Mismatch" error. I'm > using Apache 2.2.8 on Windows. I am able to reproduce this bug on another machine. Apache 2.2.8, MySQL 5.0.22, APR 1.2.12, APR-Util 1.2.12 installed on CentOS 5 x86. Test table and data created with: CREATE TABLE accounts ( id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, user VARCHAR(64), pass VARCHAR(64) NOT NULL); INSERT INTO accounts (user) VALUES ('scott'); This results in a 'SELECT * FROM accounts' returning: +----+-------+------+ | id | user | pass | +----+-------+------+ | 1 | scott | | +----+-------+------+ > This has got to be a bug in the apr_dbd_mysql code, but I unfortunately > > don't have time right now to track it down and provide a patch. To solve > > Not really. An empty string is not prohibited as a password unless you > prohibit it. > An empty-string is also the valid hash of an empty-string password. > > On Windows, BEOS, and Netware - plain-text passwords are used if there is > no prefix. > '' is a valid plain-text password. > > On Linux, crypt is used if there is no prefix. > > hash = crypt_r(password, salt, buffer) > > returns an empty-string as the hash when called with an empty-string > password and an empty-string > salt. I expect most other Unix systems do the same. Having an empty password is perfectly valid, however, the bug is that as long as the user is valid (i.e. the AuthDBDUserPWQuery doesn't return an empty set) and the password field in the database is empty, any password will authenticate the user. To show this, I set up apache's default config and used a config like follows (note that this dir is my docroot): DBDriver mysql DBDParams "dbname=test,user=root,pass=password" DBDMin 1 DBDKeep 2 DBDMax 10 DBDExptime 60 Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all AuthType Basic AuthName "Company RSS Feed" AuthBasicProvider dbd AuthzUserAuthoritative On AuthDBDUserPWQuery "SELECT pass FROM accounts WHERE user=%s" Require valid-user After starting apache, access the server, and attempt to auth using the user scott and any password you choose; it will succeed and you will be taken to the "It works!" page. > my problem I changed my query to "SELECT pwd2 FROM users WHERE email=%s > > AND active=1 AND pwd2 !=''" but this is an ugly hack. Where is the > > bugzilla to file this? > > It doesn't seem ugly to me. If you insist on storing '' in pwd2, yet you > don't want it treated as a > valid password; then enforcing your rule in SQL seems reasonable. > > Existing sites may already use an empty-string password when they want the > user to voluntarily enter > a (valid) username but they don't require any password to verify it. Not > the usual case, but it > doesn't seem necessary to break their scheme just to allow for storing > empty passwords and then > denying them. As you pointed out, storing a NULL as the password hash > will always reject a login > attempt. > > -tom- I admit I have not turned on debugging and traced into the problem yet. Any tips on where to start looking would be appreciated. -Scott ------=_Part_22789_15027156.1201901656020 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline On 1/31/08, Tom Donovan <donovant@bellatlantic.net> wrote:
Scott Sanders wrote:
> Hi,
>
> After much frustration I was able to get apr_dbd_mysql compiled and
> working on my machine. However, when testing the module I believe I
...
> but in my environment that's OK. My initial apache config to secure this
> section of the site with basic auth set the AuthDBDUserPWQuery to
> "SELECT pwd2 FROM users WHERE email=%s AND active=1". This worked and
> prevented invalid users (and inactive users) from authenticating, but if
> the pwd2 field was empty then any password would succeed. If pwd2 was
> NULL then the user was rejected, and if pwd2 had a string in it the user
> was rejected (excepting, of course, when pwd2 had the proper encrypted
> content).

I find that only an empty password works when AuthDBDUserPWQuery retrieves a value of ''.  Entering
a non-empty password (in Firefox) gives a "Password Mismatch" error.  I'm using Apache 2.2.8 on Windows.

I am able to reproduce this bug on another machine. Apache 2.2.8, MySQL 5.0.22, APR 1.2.12, APR-Util 1.2.12 installed on CentOS 5 x86. Test table and data created with:

CREATE TABLE accounts (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
user VARCHAR(64),
pass VARCHAR(64) NOT NULL);

INSERT INTO accounts (user) VALUES ('scott');

This results in a 'SELECT * FROM accounts' returning:

+----+-------+------+
| id | user  | pass |
+----+-------+------+
|  1 | scott |      |
+----+-------+------+


> This has got to be a bug in the apr_dbd_mysql code, but I unfortunately
> don't have time right now to track it down and provide a patch. To solve

Not really.  An empty string is not prohibited as a password unless you prohibit it.
An empty-string is also the valid hash of an empty-string password.

On Windows, BEOS, and Netware - plain-text passwords are used if there is no prefix.
'' is a valid plain-text password.

On Linux, crypt is used if there is no prefix.

   hash = crypt_r(password, salt, buffer)

returns an empty-string as the hash when called with an empty-string password and an empty-string
salt.  I expect most other Unix systems do the same.

Having an empty password is perfectly valid, however, the bug is that as long as the user is valid (i.e. the AuthDBDUserPWQuery doesn't return an empty set) and the password field in the database is empty, any password will authenticate the user.

To show this, I set up apache's default config and used a config like follows (note that this dir is my docroot):

DBDriver mysql
DBDParams "dbname=test,user=root,pass=password"

DBDMin  1
DBDKeep 2
DBDMax  10 
DBDExptime 60

<Directory "/home/ssanders/dev/apr_dbd_mysql-bug_proof/local/http/htdocs">
    Options Indexes FollowSymLinks

    AllowOverride None

    Order allow,deny
    Allow from all
  AuthType Basic
  AuthName "Company RSS Feed"
  AuthBasicProvider dbd
  AuthzUserAuthoritative On

  AuthDBDUserPWQuery "SELECT pass FROM accounts WHERE user=%s"
  Require valid-user
</Directory>

After starting apache, access the server, and attempt to auth using the user scott and any password you choose; it will succeed and you will be taken to the "It works!" page.

> my problem I changed my query to "SELECT pwd2 FROM users WHERE email=%s
> AND active=1 AND pwd2 !=''" but this is an ugly hack. Where is the
> bugzilla to file this?

It doesn't seem ugly to me.  If you insist on storing '' in pwd2, yet you don't want it treated as a
valid password; then enforcing your rule in SQL seems reasonable.

Existing sites may already use an empty-string password when they want the user to voluntarily enter
a (valid) username but they don't require any password to verify it.  Not the usual case, but it
doesn't seem necessary to break their scheme just to allow for storing empty passwords and then
denying them.  As you pointed out, storing a NULL as the password hash will always reject a login
attempt.

-tom-

I admit I have not turned on debugging and traced into the problem yet. Any tips on where to start looking would be appreciated.

-Scott


------=_Part_22789_15027156.1201901656020--