On Sat, 20 Feb 2010 06:33:04 am Kent Johnson wrote: > It sounds like you are looking for eval() > > (Standard warning - use eval() only on trusted data)
This is the tutor list, aimed at beginners to Python, many of whom are also beginners to programming as well. Even experienced programmers often get security very, very, very badly wrong. Do you think that a glib eight-word one-line "standard warning" really is sufficient? James, if you are still reading, I should expand on Kent's warning. The eval function, like exec, can be very dangerous in the wrong hands. There is a whole class of very, very common security bugs caused by functions like eval: http://en.wikipedia.org/wiki/Code_injection The way the bug works is that the programmer writes a function that takes some data, and directly or indirectly applies eval to it: >>> def mylist(string): ... # Convert a string to a list. ... string = string.strip() ... if string.startswith('[') and string.endswith(']'): ... return eval(string) ... else: ... raise ValueError('not a list') ... >>> mylist(" [1, 2, 3] ") [1, 2, 3] This seems pretty innocuous, but it contains a deadly land-mine. This function then gets used in an application that uses strings produced by untrusted users. Say, it ends up in a web application, and the user types text into a field and the application ends up calling mylist on the contents of that field. Then, some malicious user types this into the input form: "[] or __import__('os').system('echo YOUR SYSTEM IS MINE') or [1,2,3]" (only imagine something much worse than an echo command) and your web application does this: >>> s = "[] or __import__('os').system('echo YOUR SYSTEM IS MINE') or [1,2,3]" >>> mylist(s) YOUR SYSTEM IS MINE [1, 2, 3] You have just had your web server compromised by a code injection bug. (A web application is only one example of how you can get untrusted data into your app. It is the biggest risk though.) Now, you might think that you can work around this by clever programming. Well, maybe, but sanitising strings so they are safe is a VERY difficult job. And naturally if you aren't aware they need to be sanitised, you won't do it. My advice to anyone thinking they need to use eval or exec is: (1) Don't do it. (2) If you think you need to use them, you probably don't. (3) If you really, really need to use them, then use the most restrictive environment possible. Instead of eval(s), use: eval(s, {'__builtins__': None}, {}) which gives you some protection against naive attackers. The really clever ones will still break it. (4) Sanitise your data. Don't use Javascript to sanitise it at the browser, because the Bad Guys know how to bypass your Javascript checks. If you're expecting (say) a list of integers, then there is no reason for the list to contain *any* alphabetic characters or underscores, and if there are any, reject the string and report an error: def sanitise(string): safe = "1234567890[], \n\t" for c in string: if c not in safe: raise ValueError('unsafe string') If your needs are more complicated, then sanitising the string becomes exponentially more difficult. It will probably be less work to write your own safe parser than to sanitise the input. Have I scared you about using eval? If so, good. Don't let eval or exec anywhere near data provided by untrusted users, and don't confuse authentication with trust. -- Steven D'Aprano _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor