The code is very dangerous...all owing 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=='insta ll_django': sub.Popen(insta ll_django, ...)
so that only trusted code is run, not arbitrary things like
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. :)
>
The code is very dangerous...all owing 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.
>
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.
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_c ommand,
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.
>
>
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_c ommand,
>
>
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 ...
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.saxutil s import quoteattr
def main(fs,argv=No ne,log=None,deb ug=False):
if argv is None:
argv=sys.argv
# logic here
if __name__=='__ma in__':
log=None
if LOGGING:
log=openLog(LOG FILE_NAME)
fs=cgi.FieldSto rage(keep_blank _values=1)
try:
main(fs,argv=sy s.argv,log=log, debug=DEBUG)
except StandardError, err:
mesg="General programming error"
bail(mesg,devel =mesg+":
error=%(err)s", log=log,debug=D EBUG,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.
In message <mailman.1374.1 160073684.10491 .python-list@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.
Comment