[Python-Dev] PEP 215 redux: toward a simplified consensus? (original) (raw)

Jeff Epler jepler@unpythonic.dhs.org
Mon, 25 Feb 2002 15:20:36 -0600


On Mon, Feb 25, 2002 at 03:55:15PM -0500, Fred L. Drake, Jr. wrote:

Paul Prescod writes: > Plus, operator-based evaluation has some security implications that > compile time evaluation does not. In particular, if the left-hand thing > can be any string then you have the potential of accidentally allowing > the user to supply a string that allows him/her to introspect your local > variables. That can't happen if the interpolation is done at compile > time.

I'm not sure I understand this.

Imagine that you have: def print_crypted_passwd(name, plaintext, salt="Xx"): crypted = crypt.crypt(plaintext, salt) print _("""%(name)s, your crypted password is %(crypted)s.""") % locals()

and that some crafty devil translates this as msgstr "%(name)s, your plaintext password is %(plaintext). HA HA HA"

i.e., the translator (or other person who can influence the format string) can access other information in the dict you pass in, even if you didn't intend it.

Personally, I tend to view this as showing that using % locals() is unsanitary. But that means that the problem is in using the locals() dictionary, a problem made worse by making the use of locals() implicit.

(And under $-substitution, if locals() is implicit, how do I substitute with a dictionary other than locals()?

def print_crypted_passwd(accountinfo):
print "%(name)s, your crypted password is %(crypted)s." \
        % accountinfo.__dict__

vs def print_crypted_passwd(accountinfo): def really_subst(name, crypted): return """name, your crypted password is $crypted" print really_subst(accountinfo.name, accountinfo.crypted) or def print_crypted_passwd(accountinfo): name = accountinfo.name crypted = accountinfo.crypted print """name, your crypted password is $crypted" ???)

Jeff