[mentors-ops] r45 - in website/cgi-bin: . Mentors

chaas at mentors.debian.net chaas at mentors.debian.net
Sat Dec 31 14:17:13 CET 2005


Author: chaas
Date: 2005-12-31 14:17:12 +0100 (Sat, 31 Dec 2005)
New Revision: 45

Modified:
   website/cgi-bin/Mentors/Signup.py
   website/cgi-bin/Mentors/Web.py
   website/cgi-bin/ibeodb
Log:
 * Remove lots of sql injections (stupid me)
 * Password recovery works again. (Bullet proof)


Modified: website/cgi-bin/Mentors/Signup.py
===================================================================
--- website/cgi-bin/Mentors/Signup.py	2005-12-30 23:37:02 UTC (rev 44)
+++ website/cgi-bin/Mentors/Signup.py	2005-12-31 13:17:12 UTC (rev 45)
@@ -276,8 +276,8 @@
    #      - SSH2 public key
    def signup_validate(self):
       dbcursor = self.db.cursor()
-      query = "SELECT COUNT(id) AS count FROM %(users)s WHERE email='%(email)s'" % { 'email':self.formfields.getvalue('email'), 'users':Config.DatabaseTableUsers }
-      dbcursor.execute(query)
+      query = """SELECT COUNT(id) AS count FROM %s WHERE email=%%s""" % Config.DatabaseTableUsers
+      dbcursor.execute(query, ( self.formfields.getvalue('email') ))
       result = dbcursor.fetchone()
       if self.formfields.getvalue('user') == '':
          return "Full name is a required field."
@@ -292,17 +292,17 @@
       if self.formfields.getvalue('gpgkey') == '':
          return "Please provide your gpgkey."
 
-      query = "SELECT COUNT(id) AS count FROM %(users)s WHERE gpgkey = '%(gpgkey)s'" % { 'gpgkey':self.formfields.getvalue('gpgkey'), 'users':Config.DatabaseTableUsers }
-      dbcursor.execute(query)
-      result = dbcursor.fetchone()
-      if result["count"] != 0:
-         return "GPG key already exists in database"
-
       regex1 = re.compile("^-----BEGIN\sPGP\sPUBLIC\sKEY\sBLOCK-----")
       regex2 = re.compile("-----END\sPGP\sPUBLIC\sKEY\sBLOCK-----$")
       if regex1.search(self.formfields.getvalue('gpgkey')) == None or regex2.search(self.formfields.getvalue('gpgkey')) == None:
          return "This is not a GPG public key."
 
+      query = """SELECT COUNT(id) AS count FROM %s WHERE gpgkey = %%s""" % Config.DatabaseTableUsers
+      dbcursor.execute(query, ( self.formfields.getvalue('gpgkey') ) )
+      result = dbcursor.fetchone()
+      if result["count"] != 0:
+         return "GPG key already exists in database"
+
       return self.signup_putindatabase()
 
    def signup_putindatabase(self):
@@ -317,8 +317,11 @@
 
       # Put data in database
       dbcursor = self.db.cursor()
-      query = "INSERT INTO %(users)s(realname, email, country, ircnick, gpgkey, status, password, hash) VALUES('%(user)s', '%(email)s', '%(country)s', '%(nickname)s', '%(gpgkey)s', 'new', MD5('%(pwd)s'), '%(hash)s')" % list
-      dbcursor.execute(query)
+      query = """INSERT INTO %s(realname, email, country, ircnick, gpgkey,
+      status, password, hash) VALUES(%%s, %%s, %%s, %%s, %%s, 'new', MD5(%%s),
+         %%s)""" % Config.DatabaseTableUsers
+      dbcursor.execute(query, ( list['user'], list['email'], list['country'],
+      list['nickname'], list['gpgkey'], list['pwd'], list['hash'] ))
 
       # Send confirmation email to user.
       return self.signup_sendmail(hash)
@@ -326,12 +329,12 @@
    def signup_sendmail(self, hash):
       message = """Thank you for your interest in mentors.debian.net. You are just one step away from having your account set up so you can start uploading your own packages. This email has been sent to you to confirm that the email address is in fact yours.
 
-Please click on http://mentors-test.workaround.org/cgi-bin/signup?valid=%(hash)sthis link to have your account setup.
+Please click on http://mentors-test.workaround.org/cgi-bin/signup?valid=%(hash)s this link to have your account setup.
 
 If you did not want to get an account at mentors.debian.net please accept our apologies. Someone seems to have abused your email address. Just reply to this mail so we can permanently block your email address.""" % { 'hash':hash }
 
       mail = Email.email()
-      return mail.sendmail('support at mentors.debian.net', self.formfields.getvalue('email'), message, 'Confirmation email.')
+      return mail.sendmail(Config.EmailSender, self.formfields.getvalue('email'), message, 'Confirmation email.')
 
    def signup_getform(self):
       formlist = { }
@@ -362,13 +365,13 @@
       if len(hash) != 40:
          return """Invalid hash or user has not signed up yet. Please signup first."""
       dbcursor = self.db.cursor()
-      query = "SELECT id FROM %(users)s WHERE hash='%(hash)s'" % { 'hash':hash, 'users':Config.DatabaseTableUsers }
-      dbcursor.execute(query)
+      query = """SELECT id FROM %s WHERE hash=%%s""" % Config.DatabaseTableUsers
+      dbcursor.execute(query, ( hash ))
 
       result = dbcursor.fetchone()
       if result != None:
-         query = "UPDATE %(users)s SET status='active', hash='' WHERE id='%(id)s'" % { 'id':result['id'], 'users':Config.DatabaseTableUsers }
-         dbcursor.execute(query)
+         query = """UPDATE %s SET status='active', hash='' WHERE id=%%s""" % Config.DatabaseTableUsers
+         dbcursor.execute(query, ( result['id'] ))
          return True
       return """No user with this hash in database."""
 

Modified: website/cgi-bin/Mentors/Web.py
===================================================================
--- website/cgi-bin/Mentors/Web.py	2005-12-30 23:37:02 UTC (rev 44)
+++ website/cgi-bin/Mentors/Web.py	2005-12-31 13:17:12 UTC (rev 45)
@@ -188,7 +188,7 @@
    # Load session information from MySQL database
    def load_session(self, sessionid, ipaddress):
       dbcursor = self.db.cursor()
-      dbcursor.execute("select * from sessions where sessionid=%s and ipaddress=%s", (sessionid, ipaddress) )
+      dbcursor.execute("SELECT * FROM sessions WHERE sessionid=%s AND ipaddress=%s", (sessionid, ipaddress) )
       entry = dbcursor.fetchone()   # becomes None if nothing was fetched
       return entry
 
@@ -196,8 +196,7 @@
    def save_session(self, sessionid):
       self.debug.append("Saving session")
       dbcursor = self.db.cursor()
-      dbcursor.execute("""replace into sessions SET sessionid=%s,time=now(),ipaddress=%s,username=%s""",
-         (sessionid, self.client_ip, self.user_logged_in))
+      dbcursor.execute("""REPLACE INTO sessions SET sessionid=%s,time=now(),ipaddress=%s,username=%s""", (sessionid, self.client_ip, self.user_logged_in))
 
    # Remove a session from the MySQL database
    def del_session(self, sessionid):
@@ -208,8 +207,8 @@
    # Check if the email address and passwords match
    def login(self, email, password):
       dbcursor = self.db.cursor()
-      query = "SELECT COUNT(*) AS count FROM %(users)s WHERE email='%(email)s' AND password=MD5('%(pwd)s')" % { 'email':email, 'pwd':password, 'users':Config.DatabaseTableUsers }
-      dbcursor.execute(query)
+      query = "SELECT COUNT(*) AS count FROM %s WHERE email=%%s AND password=MD5(%%s)" % Config.DatabaseTableUsers
+      dbcursor.execute(query, ( email, password ))
       entry = dbcursor.fetchone()   # becomes None if nothing was fetched
       if entry['count'] >= 1:   # actually there should be no more than one user
          return True

Modified: website/cgi-bin/ibeodb
===================================================================
--- website/cgi-bin/ibeodb	2005-12-30 23:37:02 UTC (rev 44)
+++ website/cgi-bin/ibeodb	2005-12-31 13:17:12 UTC (rev 45)
@@ -2,6 +2,10 @@
 
 import Mentors.Web
 import Mentors.Email
+import Mentors.Database
+import sys
+sys.path.append('/etc/mentors')
+import Config # global config from /etc/mentors
 
 web = Mentors.Web.CGI(cginame='ibeodb')
 web.start()
@@ -10,27 +14,38 @@
    return web.generate_session_id()
 
 def sendmail():
+   hash = generate_hash()
    if web.formfields.has_key("email"):
-      query = "SELECT password FROM users WHERE email='%s'" % web.formfields.getvalue("email")
+      query = "UPDATE %s SET hash=%%s WHERE email=%%s LIMIT 1" % Config.DatabaseTableUsers
    else:
       return False
 
    dbcurs = web.db.cursor()
-   dbcurs.execute(query)
-   result = dbcurs.fetchone()
-   if result == None:
+   result = dbcurs.execute(query, ( hash, web.formfields.getvalue("email") ))
+   if result == 0:
       return False
-   else:
-      passwd = result["password"]
 
-   msg = """Email: %(email)s
-Password: %(pwd)s""" % { 'email':web.formfields.getvalue("email"), 'pwd':passwd }
+   msg = """Please click 
+http://mentors-test.workaround.org/cgi-bin/ibeodb?hash=%s to reenter
+a password""" % hash
+
    email = Mentors.Email.email()
-   email.sendmail("support at mentors.debian.net", web.formfields.getvalue("email"), msg, "Password from mentors.debian.net")
+   email.sendmail(Config.EmailSender, web.formfields.getvalue("email"), msg,
+         "Password recovery service from mentors.debian.net")
    return True
 
 def pwrecovery():
-   print """
+   hash = ""
+   if web.formfields.has_key('hash'):
+      conn = Mentors.Database.Database()
+      dbcurs = conn.cursor()
+      query = """SELECT COUNT(id) AS count FROM %s WHERE hash=%%s""" % Config.DatabaseTableUsers
+      dbcurs.execute(query, ( web.formfields.getvalue('hash') ))
+      result = dbcurs.fetchone()
+      if result['count'] != 0:
+         hash = web.formfields.getvalue('hash')
+      
+   recovery = """
         <h1>Password recovery.</h1>
         Please enter your email address. Your password will be e-mailed to you at the e-mail address you registered with the system.<br /><br />
         <fieldset>
@@ -38,11 +53,23 @@
            <form action='/cgi-bin/ibeodb' method='post' enctype='multipart/form-data'>
               <table>
                  <tr>
-                    <td>E-mail:</td>
+                    <td>E-mail address:</td>
                     <td><input type='text' name='email' /></td>
+                 </tr>"""
+   if hash != "":
+      recovery += """<tr>
+                    <td>Password:</td>
+                    <td><input type='password' name='pwd' /></td>
                  </tr>
                  <tr>
+                    <td>Reenter Password:</td>
                     <td>
+                        <input type='password' name='repwd' />
+                        <input type='hidden' name='hash' value='%s' />
+                    </td>
+                 </tr>""" % hash
+   recovery += """<tr>
+                    <td>
                        <input type='submit' name='submit-ibeodb' value="Submit" />
                        <input type='reset' name='reset' value="Reset" />
                     </td>
@@ -52,20 +79,33 @@
         </fieldset>
    """
 
-if web.formfields.has_key("submit-ibeodb"):
+   return recovery
+
+if web.formfields.has_key("pwd"):
+   if web.formfields.getvalue("pwd") == web.formfields.getvalue("repwd"):
+      query = """UPDATE %s SET hash='', password=MD5(%%s) WHERE hash=%%s
+      AND email=%%s""" % Config.DatabaseTableUsers
+      conn = Mentors.Database.Database()
+      dbcurs = conn.cursor()
+      result = dbcurs.execute(query, ( web.formfields.getvalue("pwd"),
+               web.formfields.getvalue("hash"), web.formfields.getvalue("email") ))
+      if result == 1:
+         print """Password change successful!"""
+      else:
+         print """Password is not changed! (Uncorrect email address)"""
+         print pwrecovery()
+   else:
+      print """Passwords don't match"""
+      print pwrecovery()
+elif web.formfields.has_key("submit-ibeodb"):
    if sendmail():
-      print """Successfully send the email."""
+      print """Successfully sent the email."""
    else:
       print """Wrong email address or not registered in the system."""
 else:
-   pwrecovery()
+   print pwrecovery()
 
 web.end()
 
-# email invullen
-# send email plus link hash + hash
-# geef form weer om password te veranderen
-# change password.
-
 # vim:set shiftwidth=3 expandtab textwidth=78 smarttab autoindent:
 




More information about the mentors-ops mailing list