[tahoe-dev] Authority to DoS via WAPI
Toby Murray
toby.murray at comlab.ox.ac.uk
Wed Jan 14 16:42:47 PST 2009
On Wed, 2009-01-14 at 16:09 -0800, Brian Warner wrote:
> > > One hack would be to use the fact that HTTP GETs can't be used to cause
> > > side-effects on Tahoe. If you give someone access to a web proxy which
> > > passes GETs through but rejects PUTs, POSTs, and DELETEs, then they'll
> > > have read-only access to the whole grid.
> >
> > This isn't quite the same thing.
>
> Well, true.. that's why we've got this "Accounting" project in the works to
> control space usage, as opposed to controlling directory modification. These
> are independent authorities, so they'll have independent controls.
I see where you're going with this and take your point. However, I'm
still not convinced for the need to provide ambient authority to upload
to the grid. Were these operations included in the API other than for
bootstrapping?
> > I'd prefer a design in which at the time that a grid is created, the
> > introducer creates a single write-cap to a directory (the "root" of the
> > grid). One then needs to use this writecap to add any content to the
> > grid by creating other directories and files that live within them etc.
>
> Ok, but then anyone who is given that writecap (or a writecap to some
> subdirectory) gets the ability to upload gigantic files and consume as much
> space as they like.
Indeed. Not really any easy fix here I guess. The Accounting stuff is
needed in either case. Perhaps I'm just uncomfortable with the current
api "only" because it violates capability discipline.
At any rate, I've appended a patch (to apply in src/allmydata with -p1)
to turn off the "ambient authority" wapi interfaces unless
"web.ambient_authority = true" is in the [node] section of tahoe.cfg
I expect this isn't the best way to implement this and that it's
probably not a feature you want in mainline, or else it would have been
implemented already, but thought it might be worth sharing anyway.
Cheers again for such a cool system.
Toby
*** allmydata/web/root.py 2008-12-01 23:27:15.000000000 +0000
--- allmydata.patched/web/root.py 2009-01-15 00:36:08.000000000 +0000
***************
*** 23,28 ****
--- 23,32 ----
# I live at /uri . There are several operations defined on /uri itself,
# mostly involved with creation of unlinked files and directories.
+
+ def setAmbientAuthority(self, ambientAuthority):
+ self.ambientAuthority = ambientAuthority
+
def render_GET(self, ctx):
req = IRequest(ctx)
uri = get_arg(req, "uri", None)
***************
*** 36,41 ****
--- 40,49 ----
return there
def render_PUT(self, ctx):
+ if not self.ambientAuthority:
+ errmsg = ("/uri handling of PUT not enabled on this node",)
+ raise WebError(errmsg, http.BAD_REQUEST)
+
req = IRequest(ctx)
# either "PUT /uri" to create an unlinked file, or
# "PUT /uri?t=mkdir" to create an unlinked directory
***************
*** 53,58 ****
--- 61,70 ----
raise WebError(errmsg, http.BAD_REQUEST)
def render_POST(self, ctx):
+ if not self.ambientAuthority:
+ errmsg = ("/uri handling of PUT not enabled on this node",)
+ raise WebError(errmsg, http.BAD_REQUEST)
+
# "POST /uri?t=upload&file=newfile" to upload an
# unlinked file or "POST /uri?t=mkdir" to create a
# new directory
***************
*** 122,127 ****
--- 134,143 ----
rend.Page.__init__(self, original)
self.child_operations = operations.OphandleTable()
+ def setAmbientAuthority(self, ambientAuthority):
+ self.child_uri.setAmbientAuthority(ambientAuthority)
+
+
child_uri = URIHandler()
child_cap = URIHandler()
child_file = FileHandler()
diff -cr allmydata/webish.py allmydata.patched/webish.py
*** allmydata/webish.py 2008-10-29 22:36:20.000000000 +0000
--- allmydata.patched/webish.py 2009-01-15 00:36:08.000000000 +0000
***************
*** 123,132 ****
name = "webish"
root_class = root.Root
! def __init__(self, webport, nodeurl_path=None, staticdir=None):
service.MultiService.__init__(self)
self.webport = webport
self.root = self.root_class()
self.site = site = appserver.NevowSite(self.root)
self.site.requestFactory = MyRequest
if self.root.child_operations:
--- 123,135 ----
name = "webish"
root_class = root.Root
! def __init__(self, webport, nodeurl_path=None, staticdir=None, ambientAuthority=False):
service.MultiService.__init__(self)
self.webport = webport
self.root = self.root_class()
+ if self.root_class == root.Root:
+ self.root.setAmbientAuthority(ambientAuthority)
+
self.site = site = appserver.NevowSite(self.root)
self.site.requestFactory = MyRequest
if self.root.child_operations:
More information about the tahoe-dev
mailing list