[tahoe-dev] [tahoe-lafs] #833: reject mutable children when *reading* an immutable dirnode

tahoe-lafs trac at allmydata.org
Mon Jan 18 19:31:49 UTC 2010

#833: reject mutable children when *reading* an immutable dirnode
 Reporter:  warner                                           |           Owner:  davidsarah
     Type:  defect                                           |          Status:  assigned  
 Priority:  critical                                         |       Milestone:  1.6.0     
Component:  code-dirnodes                                    |         Version:  1.5.0     
 Keywords:  integrity forward-compatibility confidentiality  |   Launchpad_bug:            

Comment(by davidsarah):

 Replying to [comment:29 zooko]:
 > I'm not sure I understand everything about your current plan.  However,
 I think I understand that the Tahoe-LAFS storage client has to enforce
 constraints on the semantics of a directory's child links when ''reading''
 the directory, whether it is doing so in order to display the directory in
 the WUI, send a copy of the directory (in JSON form) back through the
 WAPI, or (???) to write a copy of the directory into a new directory in

 The constraints are only on ''decoding'' future cap URIs. When a future
 version decodes an URI that starts with "{{{ro.}}}" and is followed by the
 encoding of a future cap, it must check that the cap is read-only. When it
 decodes an URI that starts with "{{{imm.}}}" and is followed by the
 encoding of a future cap, it must check that the cap is immutable. If
 those constraints are not met then decoding must fail (but it is still
 safe to handle the URI in undecoded form).

 There are no constraints on current clients, or on handling URIs as opaque
 (If an entity were to strip off a "{{{ro.}}}" or "{{{imm.}}}" prefix
 without checking the constraint, it could confuse itself, so it shouldn't
 do that.)

 > (I guess it doesn't ''have'' to enforce security properties on read when
 the purpose of the read is to make a shallow copy of (a subset of) the
 child links into a different Tahoe-LAFS directory,

 Correct, because it's not decoding those child URIs.

 > but I feel like it "should" do so in order to be consistent and parallel
 with the other two targets that the information could be headed toward:
 the WUI and the WAPI.)

 That would mean that a directory operation could have side-effects on
 child links that it isn't defined to alter. No component needs to check
 URIs that it isn't decoding, so this would be consistent between

 > But the Tahoe-LAFS storage client doesn't need to enforce any security
 constraints when writing directories -- a malicious client could always
 write arbitrarily bad things into Tahoe-LAFS directories and no-one should
 rely on the assumption that the Tahoe-LAFS directory that they are using
 was written by a client that enforces some security constraints.


 > But the storage client ''should'' enforce constraints to help the
 programmer realize that they're trying to do something wrong, when it can
 tell that they are.  That's why it will refuse to put a child link of a
 known type which is mutable into an immutable directory, but it will not
 refuse to put a child link of an unknown type into an immutable directory.

 Yes. (Currently it does refuse to put child links of unknown types into
 any directory, but this patch would change that.)

 > Okay, so the practice of prepending an {{{imm.}}} to a cap which it
 extracts from an immutable directory is best understood as a security
 constraint that the Tahoe-LAFS storage client enforces on child links of
 immutable directories when it reads them.

 As I said, the constraint is only ''necessary'' on decoding. A future
 version of the storage client ''could'' redundantly check the constraint
 when it passes on an URI to a webapi client, and it should probably do so
 even if only to reduce the length of the URI (since it can then strip off
 the 3 or 4 character prefix).

 > It needs to inform any other (correct) Tahoe-LAFS clients that
 eventually receive that cap that the cap came from an immutable context.
 The prepending of {{{imm.}}} is a way to mark the context from which that
 cap came. The reason we can't prepend {{{imm.}}} to every child link from
 an immutable directory and {{{ro.}}} to every link from a {{{ro_uri}}}
 slot is backwards-compatibility -- existing Tahoe-LAFS storage clients
 need to read directories and find caps of known types there and they won't
 recognize {{{ro.}}} or {{{imm.}}}.


 > This suggests a forward-compatibility improvement: if you are a Tahoe-
 LAFS storage client ("gateway", "node") and I give you a cap and it has
 {{{imm.}}} on the front of it then you should ''check'' whether it is of a
 type that you recognize and you can tell that the type is immutable.  If
 so, you can pop off the {{{imm.}}} and use the cap.  Likewise with
 {{{ro.}}}.  If Tahoe-LAFS v1.6 storage clients always perform that check,
 then this may free up future versions of the Tahoe-LAFS storage client to
 prepend {{{imm.}}} even to old-type child links (from the Tahoe-LAFS
 v1.6-era), which would be simpler and more consistent than prepending
 {{{imm.}}} only to child links whose type you don't recognize.

 OK, I've made this improvement in my patch.

Ticket URL: <http://allmydata.org/trac/tahoe/ticket/833#comment:31>
tahoe-lafs <http://allmydata.org>
secure decentralized file storage grid

More information about the tahoe-dev mailing list