[Dev] Coding guidelines: checking parameters
Heikki Toivonen
heikki at osafoundation.org
Thu Aug 5 11:51:10 PDT 2004
One security mantra is to "check all inputs". Obviously this means to
check all input you read from files, users, network and so forth. But it
also means that your functions should check all parameters.
This last piece seems to go against Python principles. In Python, the
idiom is to just use the things and rely on Python throwing exceptions.
And in fact, checkin parameters is made even harder in Python because
you can't even rely on the type of the parameters. All in all, lots of
problems from security perspective.
We discussed in the IRC hours that I should give an example how this
could be problematic. These are a bit contrived, but should make the point.
# no parameter checks
class Session:
def sessionadder(s):
if not hasattr(self, 'sessions'):
self.sessions = s
return
sessions += s
Here, the first caller always succeeds. The second one succeeds if the
type of s is the same on the second call and it supports addition. The
assumption is you only add positive integers to sessions, but it is not
enforced. Further let's assume that the first ten sessions are granted
extra privileges, and you can see how this could become catastrophic.
Another example with exceptions:
# exceptions not taken into account
class MyURL:
def check(self, url, port=80):
self.isSafe = True
if url.lower()[6] != 'https:':
self.isSafe = False
try:
myurl = MyURL().check(123456789034567)
except:
pass
if myurl.isSafe:
# Ok, we checked that it is https site, send the credit card number
Here the caller assumed check() would be able to cope with numeric
internet addresses, and that it would be automatically able to fill in
the protocol.
Obviously bad code, but that's where security problems come from. Real
world cases may not be this simple, and can be hard to figure out. And I
think these kinds of problems can happen more easily when the language
itself encourages you to not check inputs.
The fix here should not be to rely on fixing the callers, because you
can never fix all the callers, especially since there can be new callers
you have no control over.
The fix is to fix the sessionadder() and check() functions. Your
functions should fail in safe ways. It's easy to say: "Don't set
permanent state until you are sure nothing can go wrong." But how do you
do that when almost everything can throw an exception?
What is the Pythonic way to be robust in the face of bad (even
malicious) callers and fail safe?
--
Heikki Toivonen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
Url : http://lists.osafoundation.org/pipermail/dev/attachments/20040805/01973d31/signature.bin
More information about the Dev
mailing list