Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Creating instances of untrusted new-style classes

1 view
Skip to first unread message

Devan L

unread,
May 25, 2006, 9:06:09 PM5/25/06
to
Is there any safe way to create an instance of an untrusted class
without consulting the class in any way? With old-style classes, I can
recreate an instance from another one without worrying about malicious
code (ignoring, for now, malicious code involving attribute access) as
shown below.

>>> import types
>>> class Foo:
... def __init__(self, who, knows, what, args):
... self.mystery_args = (who, knows, what, args)
... print "Your code didn't expect the Spanish inquisition!"
...
>>> f = Foo('spam','eggs','ham','bacon') # This would be in a restricted environment, though.
Your code didn't expect the Spanish inquisition!
>>> types.InstanceType(Foo, f.__dict__) # This wouldn't, but we never run that code, anyways.
<__main__.Foo instance at 0x008B5FD0>
>>>

I'm not sure how to do the same for new-style classes, if it's at all
possible to do from within Python. Is there any way to accomplish this,
or is there no practical way to do so?

Thanks,
- Devan

Ben Finney

unread,
May 26, 2006, 12:08:16 AM5/26/06
to pytho...@python.org
"Devan L" <dev...@gmail.com> writes:

> Is there any safe way to create an instance of an untrusted class

Why are you instantiating classes you don't trust?

> without consulting the class in any way?

If you don't "consult the class", how can the instance be created
properly?

--
\ "It's easy to play any musical instrument: all you have to do |
`\ is touch the right key at the right time and the instrument |
_o__) will play itself." -- Johann Sebastian Bach |
Ben Finney

Devan L

unread,
May 26, 2006, 12:29:31 AM5/26/06
to
Ben Finney wrote:
> "Devan L" <dev...@gmail.com> writes:
>
> > Is there any safe way to create an instance of an untrusted class
>
> Why are you instantiating classes you don't trust?
>
> > without consulting the class in any way?
> If you don't "consult the class", how can the instance be created
> properly?
>

When my program runs (CGI), the following happens:
* User enters source, which is executed in a restricted environment,
which unserializes a previously serialized environment if there is one.

* The restricted environment is serialized, including any instances
they may have instantiated.

So when I unserialize their instances, I have to recreate them, but
without calling any of their code (I can't run the unserializing code
in a restricted environment). Instances of old-style classes can be
created without touching the actual old-style class code, but I'm not
sure how, if it's possible, to do the same with new-style classes


- Devan

Michael Spencer

unread,
May 26, 2006, 12:50:58 AM5/26/06
to pytho...@python.org
>>> class A(object):
... def __init__(self, *args):
... self.args = args
... print "Calling __init__"
...
>>> a = A("new","style")
Calling __init__
>>> b = object.__new__(A)
>>> b.__dict__ = a.__dict__.copy()
>>> b.args
('new', 'style')
>>> type(a) is type(b)
True
>>>

HTH

Michael

Devan L

unread,
May 26, 2006, 1:01:06 AM5/26/06
to

Michael Spencer wrote:
> Devan L wrote:
> > Is there any safe way to create an instance of an untrusted class
> > without consulting the class in any way? With old-style classes, I can
> > recreate an instance from another one without worrying about malicious
> > code (ignoring, for now, malicious code involving attribute access) as
> > shown below.
> >
[snip my example]

> >
> > I'm not sure how to do the same for new-style classes, if it's at all
> > possible to do from within Python. Is there any way to accomplish this,
> > or is there no practical way to do so?
> >
> > Thanks,
> > - Devan
> >
> >>> class A(object):
> ... def __init__(self, *args):
> ... self.args = args
> ... print "Calling __init__"
> ...
> >>> a = A("new","style")
> Calling __init__
> >>> b = object.__new__(A)
> >>> b.__dict__ = a.__dict__.copy()
> >>> b.args
> ('new', 'style')
> >>> type(a) is type(b)
> True
> >>>
>
> HTH
>
> Michael

Thanks, now I just have to figure out all the meddling small details I
put off before!

-Devan

greg

unread,
May 26, 2006, 4:33:03 AM5/26/06
to
Michael Spencer wrote:

> >>> class A(object):
> ...
> >>> b = object.__new__(A)

Note that you'll need to be a bit cleverer if the
class might be derived from some other built-in
type:

>>> class A(list):
... pass
...
>>> b = object.__new__(A)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object.__new__(A) is not safe, use list.__new__()
>>> b = list.__new__(A)
>>> b
[]

I'm not sure what is the easiest way to figure out
what base class to use, though. One way would be
to work your way backwards along the __mro__ until
one of them succeeds, but there's probably a more
direct way.

--
Greg

0 new messages