Description

I am the author of the EmailActivation plugin. It is a bit unusual in they when it creates an account it is disabled and must be enabled by clicking on a URL that is emailed. It was reported to me that a spam bot was managing to create spam without doing the equivalent of clicking on the URL.

Steps to reproduce

Sorry, I know of no easy way to do this other than by writing a SPAM bot imitator. I reproduced it by hacking auth.py to make it appear like it always had a valid cookie.

Details

It turns out it was doing this by forging a MOIN login cookie which is easy to do in pre 1.6. Moin isn't checking if the account was disabled when a valid looking cookie was presented, and so the bot could post the spam.

One problem is in user.py. load_from_id will mark the user valid if a valid username and password is presented without checking if the account is disabled. This is true for 1.5.x and 1.6.

Moin 1.5.x also has a problem in auth.py, which if presented with a valid cookie doesn't check if the user is valid or not. I see the auth code has been re-written for 1.6, and the re-write fixed the problem.

A patch that applies to 1.5.x. The patch to user.py works for 1.6:

   1 diff -Nur moin-1.5.8/MoinMoin/user.py moin-1.5.8.new/MoinMoin/user.py
   2 --- moin-1.5.8/MoinMoin/user.py	2006-10-08 23:06:37.000000000 +1000
   3 +++ moin-1.5.8.new/MoinMoin/user.py	2007-11-15 17:21:35.000000000 +1000
   4 @@ -366,6 +366,9 @@
   5          changed = 0
   6  
   7          if check_pass:
   8 +	    # Disabled users can't be validated even if they know the password
   9 +	    if self.disabled:
  10 +	        return
  11              # If we have no password set, we don't accept login with username
  12              if not user_data['enc_password']:
  13                  return
  14 diff -Nur moin-1.5.8/MoinMoin/auth.py moin-1.5.8.new/MoinMoin/auth.py
  15 --- moin-1.5.8/MoinMoin/auth.py	2007-02-08 00:31:27.000000000 +1000
  16 +++ moin-1.5.8.new/MoinMoin/auth.py	2007-11-15 17:20:34.000000000 +1000
  17 @@ -150,6 +150,9 @@
  18          u = user.User(request, id=cookie['MOIN_ID'].value,
  19                        auth_method='moin_cookie', auth_attribs=())
  20  
  21 +	if not u.valid:
  22 +	    return user_obj, True
  23 +
  24          if logout:
  25              u.valid = 0 # just make user invalid, but remember him
  26  
disabled-login-fix.patch.txt

Workaround

None.

Discussion

Q: My first impression is that the user.py patch can not really work for 1.6. Did you test it with 1.6?

A: I only checked the patch for user.py applied to 1.6, which is does. The area changed seems identical in both.

Q: I also do not see how it works for 1.5. As far as I could see, self.valid is only set to 1 at the end of the function if the user is not disabled. The place where your patch checks self.disabled is before that self.disabled attribute can get set to anything else than 0. Thus it would be nice if you could supply some script that reproduces the problem or show more exactly where things go wrong.

A: Yes, I agree. I made two changes - one in auth.py and one in user.py. They did fix the problem. In retrospect it seems the change in user.py was superfluous.

Plan

The authentication system has been revamped and the cookie is no longer fakable. -- JohannesBerg 2008-03-18 14:53:45


CategoryMoinMoinBugFixed

MoinMoin: MoinMoinBugs/DisabledLoginsAllowed (last edited 2008-03-18 14:53:45 by JohannesBerg)