aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demo/sqlinj/populate.py58
-rw-r--r--demo/sqlinj/server.py107
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()