Sunday, September 19, 2010

Common Web Site Errors

In a recent article at simple-talk, the author, Jeremy Jarrell, says this:

Earlier this year the SANS Institute released its 2010 edition of the Top 25 Most Dangerous Software Errors…sort of a ‘Greatest Hits’ of epic failures in software security. What’s so disturbing about this list is that even though it’s updated every year, the vast majority of errors can easily be avoided with just a bit of forethought.
Then he mentions one of the top errors:

...would it surprise you to know that the #11 programming error of 2010 was “Use of Hard-Coded Credentials”?
"Use of hard-coded credentials?" But I always hard-code the MySQL user's password in my Python CGI scripts. Maybe I should fix that. So, since this error should "easily be avoided with just a bit of forethought," I decided I would try to avoid hard-coding the MySQL user's password in a Python CGI script.

My conclusion: The reason this is such a common error is that all the advice on the Internet urges you to do it this way. In fact, there does not appear to be any alternative to doing it this way.

Here are some of the sites I visited, and how they suggest connecting to a MySQL database in a Python CGI script.

Of course, I am probably just too simple-minded to find the real answer. So you guys out there that know how to do it should let me know. Thanks.





The following sample is provided at
http://www.tutorialspoint.com/python/python_database_access.htm
The password is "test123"

#!/usr/bin/python

import MySQLdb

# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )





The following sample is provided at
http://mysql-python.sourceforge.net/MySQLdb.html
The password is "moonpie"

#!/usr/bin/python
import MySQLdb
db=MySQLdb.connect(passwd="moonpie",db="thangs")





The following sample is provided at
http://www.devshed.com/c/a/Python/MySQL-Connectivity-With-Python/2/
The password is "secret"

#!/usr/bin/python
# connect
db = MySQLdb.connect(host="localhost", user="joe", passwd="secret",
db="db56a")





The following sample is provided at
http://www.palewire.com/posts/2008/04/26/python-recipe-connect-to-mysql-
database-execute-a-query-print-the-results/
The password is "password"

#!/usr/bin/python
host = 'localhost'
user = 'user'
password = 'password'
conn = MySQLdb.Connection(db=database, host=host, user=user, passwd=password)
mysql = conn.cursor()





The following sample is provided at
http://www.cs.wisc.edu/twiki/bin/view/CSDocs/MySQLDatabaseServiceInfo#Python
The password is "database user password"

#!/usr/bin/python
#!/s/python-2.5.2/bin/python
import MySQLdb
db=MySQLdb.connect (host='mysql.cs.wisc.edu', user='database user',
passwd='database user password', db='database')





The following sample is provided at
http://www.howtoforge.com/creating-advanced-mysql-based-vhosts-on-lighttpd-debian-etch
The password is not evident from this code. However, it will only be secure if executed from the command-line, where a real human being can supply the password as the third argument to the script. If this script is called from a CGI script, then the third argument will have to be embedded in the CGI script code. So this sample does not really solve the problem; it just pushes it back by one layer.

#!/usr/bin/env python
import sys
import MySQLdb

# load configuration data from the database
db=MySQLdb.connect(host='localhost', db=sys.argv[1], user=sys.argv[2], passwd=sys.argv[3])
cur = db.cursor()
cur.execute("SELECT * FROM domains")
rs=cur.fetchall()
db.close()





The following sample is provided at
http://www.devshed.com/c/a/Python/Database-Programming-in-Python-Accessing-MySQL/1/
The password is "adm1n"

db= MySQLdb.connect(host=’Demo’, user=’root’ , passwd=’adm1n’, db=’test’)





The following sample is provided at
http://docs.webfaction.com/user-guide/databases.html
The password is "averysecurepassword"

import MySQLdb
db = MySQLdb.connect(host='localhost',
user='user123_mysql_db',
passwd='averysecurepassword',
db='user123_mysql_db',)
cursor = db.cursor()
cursor.execute("""SELECT * FROM names""")
result = cursor.fetchall()
print result





The following sample is provided at
http://bytes.com/topic/python/answers/868294-encrypt-password

The password is not evident from this code. Unfortunately, this code does not actually work unless a .my.sql file is set up for user "root", and the current user is named "root". This example is taken from a Tkinter GUI app, not a CGI web app.

import MySQLdb
import _mysql_exceptions as DB_EXC
from hashlib import md5
cxn = MySQLdb.connect(user ='root')
cur = cxn.cursor()

For example, if you set up a specific user for the database, and code this in your CGI script:

conn = MySQLdb.connect(host='localhost', user='expense_user')

The script fails with the following message in the Apache error.log:

1045, "Access denied for user 'expense_user'@'localhost' (using password: NO)"





P.S. added at 1:45, Monday, September 20. Of course, almost as soon as I posted this I happened across a book with the answer:

MySQL Stored Procedure Programming, 1st Edition

Look in section 16.2.1, Creating a Connection. I have not tried the suggestion, but it looks promising.