Skip to content

Commit dbd1370

Browse files
Merge pull request #12 from solid/dz_infinite_loops
Add discussion of Group ACL infinite loops
2 parents e344a57 + 578de96 commit dbd1370

File tree

2 files changed

+125
-8
lines changed

2 files changed

+125
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
##### v.0.3.1
2+
3+
- Add a discussion of infinite loops in Group ACL resolution
4+
15
##### v.0.3.0
26

37
- Expand the agentClass / Group acl definition, clarifying usage of

README.md

Lines changed: 121 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ subsequently evolved by the community, at
77
[Web Access Control Wiki](https://www.w3.org/wiki/WebAccessControl). This spec
88
is a particular subset of the options and extensions described in the wiki.
99

10-
**Current Spec version:** `v.0.3.0` (see [CHANGELOG.md](CHANGELOG.md))
10+
**Current Spec version:** `v.0.3.1` (see [CHANGELOG.md](CHANGELOG.md))
1111

1212
## Table of Contents
1313

@@ -267,14 +267,127 @@ Corresponding `work-groups` Group Listing document:
267267
<https://deb.example.com/profile/card#me> a <#Employee>, <#Management>.
268268
```
269269

270-
##### Securing Group Listings
270+
#### Group Listings - Implementation Notes
271+
272+
When implementing support for `acl:agentClass` and Group Listings, keep in mind
273+
the following issues:
274+
275+
1. Group Listings are regular documents (potentially with their own `.acl`s).
276+
2. What authentication mechanism should the ACL checking engine use, when making
277+
requests for Group Listing documents on other servers?
278+
3. Infinite request loops during ACL resolution become possible, if an `.acl`
279+
points to a group listing on a different server.
280+
281+
##### Group Listings - Authentication of External Requests
282+
283+
Group Listings via `acl:agentClass` links introduce the possibility of an ACL
284+
checking engine having to make requests to other servers. Given that access to
285+
those external group listings can be protected, the question immediately arises:
286+
By what mechanism should the ACL checking engine authenticate its request to
287+
external servers?
288+
289+
For example: Alice sends a GET request to a resource on the server
290+
`https://a.com`. The ACL for that resource links to a group listing on an
291+
external server, `https://b.com`. In the process of resolving the ACL, `a.com`
292+
must send a request to `b.com`, to get that group listing. Note that it's not
293+
Alice herself (or her application) that is sending that request, it's actually
294+
`a.com` sending it (as part of trying to resolve its own ACL). How should
295+
`a.com` authenticate itself? Does it have its own credentials, or does it have
296+
a way to say that it's acting on behalf of Alice? Or both?
297+
298+
There are several implementation possibilities:
299+
300+
**No authentication**. The ACL checking engine sends *un-authenticated* requests
301+
to external servers (to fetch group listings). This is the simplest method to
302+
implement, but suffers from the limitation that those external group listings
303+
need to be public-readable.
304+
305+
**WebID-TLS Delegation**. If your implementation uses the WebID-TLS
306+
authentication method, it also needs to implement the ability to delegate its
307+
requests on behalf of the original user. For a discussion of such a capability,
308+
see the [Extending the WebID Protocol with Access
309+
Delegation](http://bblfish.net/tmp/2012/08/05/WebID_Delegation.pdf) paper.
310+
One thing to keep in mind is - if there are several hops (an ACL request chain
311+
across more than one other domain), how does this change the delegation
312+
confirmation algorithm? If the original server is explicitly authorized for
313+
delegation by the user, what about the subsequent ones?
314+
315+
**ID Tokens/Bearer Tokens**. If you're using a token-based authentication system
316+
such as OpenID Connect or OAuth2 Bearer Tokens, it will also need to implement
317+
the ability to delegate its ACL requests on behalf of the original user. See
318+
[PoP/RFC7800](https://tools.ietf.org/html/rfc7800) and [Authorization Cross
319+
Domain Code](http://openid.bitbucket.org/draft-acdc-01.html) specs for relevant
320+
examples.
321+
322+
##### Infinite Request Loops in Group Listings
323+
324+
Since Group Listings (which are linked to from ACL resources using
325+
the `acl:agentClass` predicate) are regular documents, they can have their very
326+
own `.acl` resources that restrict which users (or groups) are allowed to access
327+
or change them. This fact, that `.acl`s point to Group Listings, which can have
328+
`.acl`s of their own, which can potentially also point to Group Listings, and so
329+
on, introduces the potential for infinite loops during ACL resolution.
330+
331+
Take the following situation with two different servers:
271332

272-
Since Group Listing documents (which are linked to from ACL resources using
273-
the `acl:agentClass` predicate) are regular documents, care must be taken to
274-
secure them, by providing them with `.acl` resources of their own. For example,
275-
the `work-groups` document from the example above should have its own
276-
`work-groups.acl` resource, which restricts which users have Read/Write/etc
277-
access to it.
333+
```
334+
https://a.com https://b.com
335+
------------- GET ---------------
336+
group-listA <------ group-listB.acl
337+
| ^ contains:
338+
| | agentClass <a.com/group-ListA>
339+
v GET |
340+
group-listA.acl ------> group-listB
341+
contains:
342+
agentClass <b.com/group-listB>
343+
```
344+
345+
The access to `group-listA` is controlled by `group-listA.acl`. So far so good.
346+
But if `group-listA.acl` contains any `acl:agentClass` references to *another*
347+
group listing (say, points to `group-listB`), one runs into potential danger.
348+
In order to retrieve that other group listing, the ACL-checking engine on
349+
`https://b.com` will need to check the rules in `group-listB.acl`. And if
350+
`group-listB.acl` (by accident or malice) points back to `group-listA` a request
351+
will be made to access `group-listA` on the original server `https://a.com`,
352+
which would start an infinite cycle.
353+
354+
To guard against these loops, implementers have several options:
355+
356+
**A) Do not allow cross-domain Group Listing resolutions**.
357+
The simplest to implement (but also the most limited) option is to disallow
358+
cross-domain Group Listings resolution requests. That is, the ACL-checking code
359+
could detect `agentClass` links pointing to external servers during ACL
360+
resolution time, and treat those uniformly (as errors, or as automatic "access
361+
denied").
362+
363+
**B) Treat Group Listings as special cases**.
364+
This assumes that the server has the ability to parse or query the contents of a
365+
Group Listing document *before* resolving ACL checks -- a design decision that
366+
some implementations may find unworkable. If the ACL checking engine can inspect
367+
the contents of a document and know that it's a Group Listing, it can put in
368+
various safeguards against loops. For example, it could validate ACLs when they
369+
are created, and disallow external Group Listing links, similar to option A
370+
above. Note that even if you wanted to ensure that no `.acl`s are allowed for
371+
Group Listings, and that all such documents would be public-readable, you would
372+
still have to be able to tell Group Listings apart from other documents, which
373+
would imply special-case treatment.
374+
375+
**C) Create and pass along a tracking/state parameter**.
376+
For each ACL check request beyond the original server, it would be possible to
377+
create a nonce-type tracking parameter and pass it along with each subsequent
378+
request. Servers would then be able to use this parameter to detect loops on
379+
each particular request chain. However, this is a spec-level solution (instead
380+
of an individual implementation level), since all implementations have to play
381+
along for this to work. See issue
382+
[solid/solid#8](https://github.com/solid/solid/issues/8) for further
383+
discussion).
384+
385+
**D) Ignore this issue and rely on timeouts.**
386+
It's worth noting that if an infinite group ACL loop was created by mistake,
387+
this will soon become apparent since requests for that resource will time out.
388+
If the loop was created by malicious actors, this is comparable to a very
389+
small, low volume DDOS attack, which experienced server operators know how to
390+
guard against. In either case, the consequences are not disastrous.
278391

279392
### Public Access (All Agents)
280393

0 commit comments

Comments
 (0)