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,






Reply via email to