diff options
-rw-r--r-- | demo/sqlinj/populate.py | 58 | ||||
-rw-r--r-- | demo/sqlinj/server.py | 107 |
2 files changed, 165 insertions, 0 deletions
diff --git a/demo/sqlinj/populate.py b/demo/sqlinj/populate.py new file mode 100644 index 0000000000..16588865a6 --- /dev/null +++ b/demo/sqlinj/populate.py @@ -0,0 +1,58 @@ +# Populate the database for the SQL injection demo, +# it creates a DBS directory in the current working dir. +# Requires Gadfly on the python path, and a --allworkingmodules --oldstyle +# pypy-c. +# Passwords for the demo are just the reverse of user names. + +import md5 +import sys, os +import random + +os.mkdir("DBS") + +import gadfly + +conn = gadfly.gadfly() +conn.startup("db0", "DBS") + +names = ['bob', 'jamie', 'david', 'monica', 'rose', 'anna'] + +def make_pwd(name): + rname = list(name) + rname.reverse() + rname = ''.join(rname) + return md5.new(rname).hexdigest() + +pwds = [make_pwd(name) for name in names] + +products = [('superglue', 10.0, 5), + ('pink wallpaper', 25.0, 20), + ('red wallpaper', 20.0, 20), + ('gray wallpaper', 15.0, 20), + ('white wallpaper', 15.0, 20), + ('green wallpaper', 20.0, 20) ] + +cursor = conn.cursor() +cursor.execute("""create table purchases (pwd varchar, user varchar, + month integer, year integer, + product varchar, + qty integer, + amount float) + """) + + + +ins = "insert into purchases values (?,?,?,2007,?,?,?)" +for i in range(15): + uid = random.randrange(0, len(names)) + pwd = pwds[uid] + name = names[uid] + month = random.randrange(1, 13) + product, unitprice, maxqty = random.choice(products) + qty = random.randrange(1, maxqty) + data = (pwd, name, month, product, qty, qty*unitprice) + cursor.execute(ins, data) + +conn.commit() + +print "Done" diff --git a/demo/sqlinj/server.py b/demo/sqlinj/server.py new file mode 100644 index 0000000000..47258a53ff --- /dev/null +++ b/demo/sqlinj/server.py @@ -0,0 +1,107 @@ +"""SQL injection example, needs gadfly + (sf.net/projects/gadfly) to be on the python path. + + Use populate.py to create the example db. + + Passwords are the reverse of user names :). + + Query is the number of a calendar month, purchases + for the user with the password since including that month + are shown. + + Works with an --allworkingmodules --oldstyle pypy-c . +""" + +import sys + +import gadfly + +import BaseHTTPServer +import cgi +import md5 + +page=""" +<html> +<head> +<title>DEMO</title> +</head> +<body> +<form method="get" action="/"> +<label for="pwd">Passwd</label> +<input name="pwd" type="text" size="10"></input><br /> +<label for="query">Query</label> +<input name="query" type="text" size="20"></input><br /> +<input type="submit"> +</form> + +<div> +%s +</div> +</body> +</html> +""" + +table = """ +<table> +<th>customer</th> +<th>month</th> +<th>year</th> +<th>prod.</th> +<th>qty</th> +<th>amount</th> +%s +</table> +""" + +row = "<tr>"+"<td>%s</td>"*6 +"</tr>" + +def do_query(query): + conn = gadfly.gadfly("db0", "DBS") + cursor = conn.cursor() + pwd = md5.new(query['pwd'][0]).hexdigest() + q = query['query'][0] + + sel = ("""select user,month,year,product,qty,amount from purchases + where pwd='%s' and month>=%s + """ % (pwd, q)) + cursor.execute(sel) + rows = [] + for x in cursor.fetchall(): + rows.append(row % x) + results = table % ('\n'.join(rows)) + + conn.close() + return results + + + +class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + + def do_GET(self): + self.send_response(200, "OK") + self.end_headers() + parts = self.path.split('?') + if len(parts) > 1: + _, query = parts + query = cgi.parse_qs(query, strict_parsing=True) + else: + query = None + + if query is not None: + results = do_query(query) + else: + results = "no query" + + self.wfile.write(page % results) + + + +if __name__ == '__main__': + if len(sys.argv) > 1: + port = int(sys.argv[1]) + else: + port = 8000 + + server_address = ('', port) + httpd = BaseHTTPServer.HTTPServer(server_address, RequestHandler) + httpd.serve_forever() |