[mod_python] Approach to mod_python "secure" code

fizban fizban at paranoici.org
Fri Nov 17 12:38:17 EST 2006

Deron Meranda wrote:
> On 11/17/06, fizban <fizban at paranoici.org> wrote:
>> 1* take req.uri, str() it (just in case?) and split('/') it.
>> [stuff = str(req.uri).split('/')
> There's no need to str() it.  It's already a string.  It will also have
> been url decoded.

Ok, I see.

>> 3* if stuff[1] is valid, and it is in a tuple containing a list of
>> special sections with a matching function, we run that function
>> [eval("%s(%s)" % (section, "req"))].
> This should be secure, if you are definitely checking the string
> against a known acceptible list of them.
> But it's bad Python form!  eval should only be used as a last
> resort (unless you don't care about form/style).  It's almost
> never necessary.  This is a bad habit encouraged by PHP that
> you will want to unlearn quickly.

Heh, I was actually told to do so by someone more skilled in python than
me, let's blame him! I've never used eval myself.

I do care about form/style for this particular project -- I'm also
considering to release the code. It wouldn't probably be used by many
(it's pretty specific for this kind of site, so not much portable), but
maybe I can help convert someone else to python/mod_python, or help
similar projects dealing with their sites.

> The simplest way to do this without eval is to change your
> list into a dictionary.  Assuming you have something like
>   allowed_sections = ['one', 'two', 'three']
> change it to
>   def one(req): ...
>   def two(req): ...
>   def three(req): ...
>   section_mapping = { 'one': one,  'two': two,  'three': three }
> and then rather than eval call them as
>   try:
>       section_mapping[section]( req )
>   except KeyError:
>       raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND

Ok cool, I'll do that

> Another common way is to put all your functions inside a class
> and use getattr and such.  You might want to get the O'Reilly
> book "Python Cookbook" to learn more techniques of Python
> programming.

I'm not a big fan of classes actually.. and it's not because of my PHP
"background".. But I'll sure get that book

> Lets just say that what you've shown us shouldn't be insecure,
> but we can't say it's secure either.  There's so much that's not
> even talked about.  For example the whole user authentication,
> SSL, use of database queries, embedded/hardcoded passwords
> (which are a definte no-no, especially if you have PythonDebug
> turned on).

Yeah, PythonDebug will be off when we get in "production".. and
embedded/hardcoded passwords are bad in all the cases I can think at :)

However, I think I mis-used "userbase". The userbase is actually the
visitors plus the kiddies we attract because it's the site of a pretty
well known project. The "admin" zone has always been protected in
various ways (like, letting it being accessed by known IP and using a
login/pass, etc etc), and the protection method is likely to stay the
same. Also, I'll set it up to be dealt with another handler.
I think I'll let apache alone dealing with ip and login/password
restrictions.. Unless there's some good reason not to do so when using a
custom handler.. is there?

> Just be cautious of where the data came from and how you
> use it and you should be fine.

> As for 404s, don't worry about any "impression".  Use the correct
> code for the correct situation.  The only case where I might deviate
> from this is to send 302 rather than the recommended 307, since
> many old browsers (IE) don't understand 307.

Oh, I didn't know IE doesn't deal with 307, good to know!

> Also you may want to use the symbolic names, such as
> apache.HTTP_NOT_FOUND, provided by the modpython.apache
> module rather than numbers, as it makes your code more readable.

Yep, I'm already doing so -- I was just being lazy so I used the numeric
error in the email :-)

> Good luck.




More information about the Mod_python mailing list