From d82d154c79bffed56e4835b2a0154bc025394587 Mon Sep 17 00:00:00 2001 From: Dmitri Zagidulin Date: Fri, 15 Jul 2016 16:45:19 -0400 Subject: [PATCH 1/3] Add discussion of Group ACL infinite loops Implements issue #5. --- CHANGELOG.md | 4 ++++ README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64c3afb..9cd61ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +##### v.0.3.1 + +- Add a discussion of infinite loops in Group ACL resolution + ##### v.0.3.0 - Expand the agentClass / Group acl definition, clarifying usage of diff --git a/README.md b/README.md index a61fde5..3104fb4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ subsequently evolved by the community, at [Web Access Control Wiki](https://www.w3.org/wiki/WebAccessControl). This spec is a particular subset of the options and extensions described in the wiki. -**Current Spec version:** `v.0.3.0` (see [CHANGELOG.md](CHANGELOG.md)) +**Current Spec version:** `v.0.3.1` (see [CHANGELOG.md](CHANGELOG.md)) ## Table of Contents @@ -267,14 +267,61 @@ Corresponding `work-groups` Group Listing document: a <#Employee>, <#Management>. ``` -##### Securing Group Listings +#### Group Listings - Implementation Notes -Since Group Listing documents (which are linked to from ACL resources using -the `acl:agentClass` predicate) are regular documents, care must be taken to -secure them, by providing them with `.acl` resources of their own. For example, -the `work-groups` document from the example above should have its own -`work-groups.acl` resource, which restricts which users have Read/Write/etc -access to it. +When implementing support for `acl:agentClass` and Group Listings, it is +important to keep in mind the following issues: + +1. Group Listings are regular documents (and so can have their own `.acl`s) +2. Infinite request loops during ACL resolution become possible, if an `.acl` + points to a group listing on a different server. + +Since Group Listings (which are linked to from ACL resources using +the `acl:agentClass` predicate) are regular documents, they can have their very +own `.acl` resources that restrict which users (or groups) are allowed to access +or change them. This fact, that `.acl`s point to Group Listings, which can have +`.acl`s of their own, which can potentially also point to Group Listings, and so +on, introduces the potential for infinite loops during ACL resolution. + +For example, imagine the following situation with two different servers: + +``` +https://a.com https://b.com +------------- GET --------------- +group-listA <------ group-listB.acl + | ^ contains: + | | agentClass + v GET | +group-listA.acl ------> group-listB + contains: + agentClass +``` + +The access to `group-listA` is controlled by `group-listA.acl`. So far so good. +But if `group-listA.acl` contains any `acl:agentClass` references to *another* +group listing (say, points to `group-listB`), one runs into potential danger. +In order to retrieve that other group listing, the ACL-checking engine on +`https://b.com` will need to check the rules in `group-listB.acl`. And if +`group-listB.acl` (by accident or malice) points back to `group-listA` a request +will be made to access `group-listA` on the original server `https://a.com`, +which would start an infinite cycle. + +To guard against these loops, implementers have two basic options: + + A. Treat the ACL resources for Group Listings as special cases. This + assumes that the server has the ability to parse or query the contents of a + Group Listing document *before* resolving ACL checks -- a design decision + that some implementations may find unworkable. If the ACL checking engine + can inspect the contents of a document and know that it's a Group Listing, + it can put in various safeguards against loops, for example by not allowing + `agentClass` links to different servers (only for `.acl`s of Group Listings, + though). Note that even if you wanted to ensure that no `.acl`s are allowed + for Group Listings, and that all such documents would be public-readable, + you would still have to be able to tell Group Listings apart from other + documents, which would imply special-case treatment. + B. Keep track of request state and break request loops when they occur (see + issue [solid/solid#8](https://github.com/solid/solid/issues/8) for more + discussion). ### Public Access (All Agents) From 874b28924b24b55cc5e9ebbce447f3cdc74a7dc7 Mon Sep 17 00:00:00 2001 From: Dmitri Zagidulin Date: Fri, 15 Jul 2016 16:50:51 -0400 Subject: [PATCH 2/3] Fix typos, tweak language --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3104fb4..7ba7df7 100644 --- a/README.md +++ b/README.md @@ -269,8 +269,8 @@ Corresponding `work-groups` Group Listing document: #### Group Listings - Implementation Notes -When implementing support for `acl:agentClass` and Group Listings, it is -important to keep in mind the following issues: +When implementing support for `acl:agentClass` and Group Listings, keep in mind +the following issues: 1. Group Listings are regular documents (and so can have their own `.acl`s) 2. Infinite request loops during ACL resolution become possible, if an `.acl` @@ -283,14 +283,14 @@ or change them. This fact, that `.acl`s point to Group Listings, which can have `.acl`s of their own, which can potentially also point to Group Listings, and so on, introduces the potential for infinite loops during ACL resolution. -For example, imagine the following situation with two different servers: +Take the following situation with two different servers: ``` https://a.com https://b.com ------------- GET --------------- group-listA <------ group-listB.acl | ^ contains: - | | agentClass + | | agentClass v GET | group-listA.acl ------> group-listB contains: From 578de961fa0df2b729da2843ee560fae9a9580e8 Mon Sep 17 00:00:00 2001 From: Dmitri Zagidulin Date: Mon, 18 Jul 2016 16:37:44 -0400 Subject: [PATCH 3/3] Expand Group Listing authentication and loops sections --- README.md | 102 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 7ba7df7..fd010bc 100644 --- a/README.md +++ b/README.md @@ -272,10 +272,55 @@ Corresponding `work-groups` Group Listing document: When implementing support for `acl:agentClass` and Group Listings, keep in mind the following issues: -1. Group Listings are regular documents (and so can have their own `.acl`s) -2. Infinite request loops during ACL resolution become possible, if an `.acl` +1. Group Listings are regular documents (potentially with their own `.acl`s). +2. What authentication mechanism should the ACL checking engine use, when making + requests for Group Listing documents on other servers? +3. Infinite request loops during ACL resolution become possible, if an `.acl` points to a group listing on a different server. +##### Group Listings - Authentication of External Requests + +Group Listings via `acl:agentClass` links introduce the possibility of an ACL +checking engine having to make requests to other servers. Given that access to +those external group listings can be protected, the question immediately arises: +By what mechanism should the ACL checking engine authenticate its request to +external servers? + +For example: Alice sends a GET request to a resource on the server +`https://a.com`. The ACL for that resource links to a group listing on an +external server, `https://b.com`. In the process of resolving the ACL, `a.com` +must send a request to `b.com`, to get that group listing. Note that it's not +Alice herself (or her application) that is sending that request, it's actually +`a.com` sending it (as part of trying to resolve its own ACL). How should +`a.com` authenticate itself? Does it have its own credentials, or does it have +a way to say that it's acting on behalf of Alice? Or both? + +There are several implementation possibilities: + +**No authentication**. The ACL checking engine sends *un-authenticated* requests +to external servers (to fetch group listings). This is the simplest method to +implement, but suffers from the limitation that those external group listings +need to be public-readable. + +**WebID-TLS Delegation**. If your implementation uses the WebID-TLS +authentication method, it also needs to implement the ability to delegate its +requests on behalf of the original user. For a discussion of such a capability, +see the [Extending the WebID Protocol with Access +Delegation](http://bblfish.net/tmp/2012/08/05/WebID_Delegation.pdf) paper. +One thing to keep in mind is - if there are several hops (an ACL request chain +across more than one other domain), how does this change the delegation +confirmation algorithm? If the original server is explicitly authorized for +delegation by the user, what about the subsequent ones? + +**ID Tokens/Bearer Tokens**. If you're using a token-based authentication system +such as OpenID Connect or OAuth2 Bearer Tokens, it will also need to implement +the ability to delegate its ACL requests on behalf of the original user. See +[PoP/RFC7800](https://tools.ietf.org/html/rfc7800) and [Authorization Cross +Domain Code](http://openid.bitbucket.org/draft-acdc-01.html) specs for relevant +examples. + +##### Infinite Request Loops in Group Listings + Since Group Listings (which are linked to from ACL resources using the `acl:agentClass` predicate) are regular documents, they can have their very own `.acl` resources that restrict which users (or groups) are allowed to access @@ -306,22 +351,43 @@ In order to retrieve that other group listing, the ACL-checking engine on will be made to access `group-listA` on the original server `https://a.com`, which would start an infinite cycle. -To guard against these loops, implementers have two basic options: - - A. Treat the ACL resources for Group Listings as special cases. This - assumes that the server has the ability to parse or query the contents of a - Group Listing document *before* resolving ACL checks -- a design decision - that some implementations may find unworkable. If the ACL checking engine - can inspect the contents of a document and know that it's a Group Listing, - it can put in various safeguards against loops, for example by not allowing - `agentClass` links to different servers (only for `.acl`s of Group Listings, - though). Note that even if you wanted to ensure that no `.acl`s are allowed - for Group Listings, and that all such documents would be public-readable, - you would still have to be able to tell Group Listings apart from other - documents, which would imply special-case treatment. - B. Keep track of request state and break request loops when they occur (see - issue [solid/solid#8](https://github.com/solid/solid/issues/8) for more - discussion). +To guard against these loops, implementers have several options: + +**A) Do not allow cross-domain Group Listing resolutions**. +The simplest to implement (but also the most limited) option is to disallow +cross-domain Group Listings resolution requests. That is, the ACL-checking code +could detect `agentClass` links pointing to external servers during ACL +resolution time, and treat those uniformly (as errors, or as automatic "access +denied"). + +**B) Treat Group Listings as special cases**. +This assumes that the server has the ability to parse or query the contents of a +Group Listing document *before* resolving ACL checks -- a design decision that +some implementations may find unworkable. If the ACL checking engine can inspect +the contents of a document and know that it's a Group Listing, it can put in +various safeguards against loops. For example, it could validate ACLs when they +are created, and disallow external Group Listing links, similar to option A +above. Note that even if you wanted to ensure that no `.acl`s are allowed for +Group Listings, and that all such documents would be public-readable, you would +still have to be able to tell Group Listings apart from other documents, which +would imply special-case treatment. + +**C) Create and pass along a tracking/state parameter**. +For each ACL check request beyond the original server, it would be possible to +create a nonce-type tracking parameter and pass it along with each subsequent +request. Servers would then be able to use this parameter to detect loops on +each particular request chain. However, this is a spec-level solution (instead +of an individual implementation level), since all implementations have to play +along for this to work. See issue +[solid/solid#8](https://github.com/solid/solid/issues/8) for further +discussion). + +**D) Ignore this issue and rely on timeouts.** +It's worth noting that if an infinite group ACL loop was created by mistake, +this will soon become apparent since requests for that resource will time out. +If the loop was created by malicious actors, this is comparable to a very +small, low volume DDOS attack, which experienced server operators know how to +guard against. In either case, the consequences are not disastrous. ### Public Access (All Agents)