[Python-Dev] PEP 215 redux: toward a simplified consensus?
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