W3C home > Mailing lists > Public > public-appformats@w3.org > April 2007

Re: [AC] Access Control Algorithm

From: Jonas Sicking <jonas@sicking.cc>
Date: Tue, 24 Apr 2007 12:12:35 -0700
Message-ID: <462E56A3.20502@sicking.cc>
To: Anne van Kesteren <annevk@opera.com>
CC: "WAF WG (public)" <public-appformats@w3.org>

Hi All,

I've started implementing the Access control spec as part of work to
implement cross site XMLHttpRequest. However I'm not really happy with
the current algorithm.

One thing that is very important IMHO is that it is possible using
headers to turn off access to a whole server. One usecase for this would
be if a site notices some files are missconfigured and as immediate
security precaution disables access to all files while figuring out what
is wrong.
Another scenario would be a hosting server such as livejournal or
geocities wanting to disable access to all their hosted files even
though other users manage the contents of those files.

So this puts two requirements on the algorithm. First of all we can't
simply merge whatever lists are in the headers with the lists produced
by the PIs in the page. Second, we need an explicit way to deny access,
not just exclude from the accept list.

I would suggest the following algorithm:

For headers the following syntax is used

Content-Access-Control ::= "Content-Access-Control" ":" ruleset
ruleset        ::= rule ("," rule)*
rule           ::= access pattern+
access         ::= "allow" | "deny"
pattern        ::= "<" access-item ">"

(I've removed the explicit whitespace markers for clarity in the above, 
they should of course be in the spec)

For each rule in the ruleset, apply the following algorithm in order.
   1. If the requesting site matches any of the patterns in the rule set
      and access is "deny" set result to deny and stop.
   2. If the requesting site matches any of the patterns in the rule set
      and access is "allow" set result to allow and stop.
   3. Skip the rule and move on to the next, if there are no more rules
      set the result to "none"

If the result was "deny" abort processing and deny user access. If the 
result was "allow" or "none" search for access control PIs using the 
following steps:

For each child node of the document:
   1. If the node is an element, stop.
   2. If the node is not a processing instruction with the target
      "access-control", skip to next node.
   3. If any of the patterns in the deny pseudo-attribute matches
      the requesting uri set result to "deny" and stop
   4. If any of the patterns in the allow pseudo-attribute matches
      the requesting uri set result to "allow" and stop

If the result is "allow" give user access to the document, note that 
this can happen if no pattern matched in step 3 or 4, but the result was 
"allow" from when processing the headers.
Otherwise, i.e. if the result is "deny" or "none", deny user access to 
the document.

This should be pretty intuitive. For both headers and PIs the first 
matching rule is used. In PIs where allow and deny appear in the same 
rule deny takes precedence for extra security.
If the headers say deny access is denied. If the headers say allow we 
also check with the document.
This also allows both the document author and the server admin to deny 
access to the document.

What do people think?

Best Regards
/ Jonas

Anne van Kesteren wrote:
> Hi,
> The current algorithm for access control is that a resource has an 
> associated
> list two-tuples. Each two-tuple consits of one list with at least one item,
> the allow list. And another list which may be empty, the exception list. 
> When
> a request is made to a resource to which the access control read policy
> applies you go through each of the two-tuples and as soon as you reach one
> where one of the items in the allow list matches with the request URL 
> and the
> exception list (in the same two-tuple) does not access is granted and the
> access algorithm aborted. Otherwise access is denied.
> This means for instance that a request from foo.bar.com would get access in
> this case:
>   [([*.bar.com], [foo.bar.com])
>   ,([*.bar.com], [])]
> The two-tuples are formed by HTTP Content-Access-Control header rules and
> <?access-control?> processing instructions. Each of them creates one
> two-tuple.
> The advantages of this proposal are that each header rule and each 
> processing
> instruction contributes one item which is individually analyzed. It's not
> really clear why this is needed or desirable though especially as it also
> allows scenarios as pointed out above. The main problem with this 
> approach is
> that it's quite complex to grasp and so far nobody really got it I believe.
> The other idea which was specified initially is that all rules specified by
> HTTP headers and processing instructions are combined into two global 
> lists.
> One list of allow rules and one list of exceptions to those allow rules. 
> (The
> latter could probably be called "deny" as it would be effectively the 
> same.)
> The algorithm for this would be that once both lists are constructed you 
> first
> match the request URL against the items in the allow list and if there's 
> match
> and there's no match in the exception / deny list you grant access. 
> Otherwise
> access is denied. (Assuming that the access control read policy is 
> applicable
> to the requested resource.
> Personally I'm in favor of the second proposal as I think it addresses the
> same usecases and has less surprises and complexity. It would be good if
> authors and implementors commented on this approach.
> If needed I'm willing to discuss this during the groups telcon if 
> anybody sees
> some advantage in doing that.
> Cheers,
Received on Tuesday, 24 April 2007 19:14:33 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 20:50:07 UTC