[Twisted-Python] Potential PB Security Problem (And Solution)

Glyph Lefkowitz glyph at twistedmatrix.com
Sat Feb 16 06:42:48 EST 2002

On Fri, 2002-02-15 at 22:04, Kevin Turner wrote:
> On Fri, 2002-02-15 at 19:12, Christopher Armstrong wrote:
> > For as long as I remember, that was *never* the point. Haven't you ever
> > heard glyph shouting from on high, "Explicit is better than implicit!"?
> Funny words for a sect which celebrates in masqurading objects and
> generally deplores strict type checking.

Dynamic typing is very cool, for reasons I've described in detail
elsewhere.  Hence, I want to make it still be easy to write secure PB
code without mandating the writing of IDLs.  Assuming that whatever code
you write *must* be secure, which is more of a hindrance:
foo.callRemote("bar") or requiring a full interface definition before
you can even publish your object?

The distinction between masquerading locally (fooling yourself) and
masquerading remotely (fooling others) is the difference between having
a vivid imagination and being a con artist...

> > Well, the point was, the code wasn't *meant* to pass privelaged
> > information to an object across the wire - notice that it was a Copied.
> > This could also be done for more things than Copied - imagine a method
> > that takes a list as one of its arguments and appends some secure data
> > to it. You could spoof a list with a remote object that has an append()
> > method.
> What do you mean, "wasn't meant to pass privledged information"?  Your
> example has you appending the "secure data" to a list that's from who
> knows where!  You have no idea who holds a reference to that list, or
> who will hold references to the list (or certain items on the list) in
> the near future.  And, as a happy little object, I don't see why you
> should care.  You perform your operation with the given parameters, and
> that's all your job is, isn't it?

There are two kinds of "who" here.  One "who" is to know the objects
that will have knowledge of your object.  That's encapsulation, which is
all well and good, but we break it sometimes, for various reasons;
python's nifty because it lets us do that when necessary.  The other
"who" is more important, though: it's the actual *people* that will have
access to the information that you're sending through that method call.

> I guess there's the "Referenceable vs Copyable" facet which I haven't
> been paying a lot of attention to in this discussion.  When I choose
> between those two spreadable flavours (the module name is spelled wrong,
> BTW), I am thinking about what goes over the wire, but only in terms of
> how much it will change, how much the states of the objects need to be
> synchronized, how much traffic it's generating, etc.  But I've never
> seen the use of Copyable as a security option.  If I had data I did not
> want getting outside, I do not think I should entrust it to *any* object
> which came from Outside, whether it be a RemoteCopy or RemoteCache or a
> list-like object with whiskers.

RemoteCopy and RemoteCache are both local classes; e.g. any information
you pass to methods that exist on them gets dealt with locally.  At
least in the code I'm writing for work, I'll often want to embed
"privileged" code in a RemoteCopy class, since it is dealing with
*information* from the "outside", but behavior locally.  For mirroring
the view of a simulation on a server, this is a common design pattern,
I'd imagine.

The proposal on the table makes the locality of the behavior much more
explicit -- unless your method begins with 'callRemote', the behavior
you're invoking will *definitely* be local.  Attempts to invoke
(potentially) remote behavior without first saying so will just blow up.

> I guess it's only fair to admit that I've written very little
> application code with twisted.spread and read even less, so it's
> entirely possible that I lack the experience to understand the issues
> here...  but some things bein' said just don't ring true to me.


Seriously, thanks for your response; this is exactly the sort of
discussion I wanted to generate.  You haven't convinced me that I was
wrong yet ;-), but I would like it if the motivations for doing this are
clearly understood.

If you haven't read much PB code, the problem I'm describing might seem
a trivial concern, but I've found at least two instances of this problem
"in the wild".  One was a mistake made by me and one was someone else. 
Neither could be made to divulge critical information, but both could be
exploited to give a user an unfair advantage or consume a large
proportion of the server's CPU/bandwidth.

Do you have a solution that's less aesthetically unpleasant?  I think
that this is a good compromise all around (mumble, frotz, I want macros
and promises and continuations so I can say [wait-for [tell obj message
arg arg arg]]).  But then again, I actually find it *more* aesthetically
pleasant to say THIS HERE IS LIKELY TO BE REMOTE.  Despite the other
advantages of moving to PB methods returning Deferreds, I was glad that
I could previously grep for 'pbcallback' and get most of the methods
that would be invoked remotely.

> "So-at-least-ONE-of-us-has-been-replaced-by-an-evil-robot"-ly yours,

Who would want to replace me with another evil robot?

"Cannot stand to be one of many -- I'm not what they are."
        -Guster, "Rocketship"
                glyph lefkowitz; ninjaneer, freelance demiurge
    glyph @ [ninjaneering|twistedmatrix].com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20020216/9c34ec4d/attachment.pgp 

More information about the Twisted-Python mailing list