Feedback on Capability URLs

Thanks for writing this doc! (http://www.w3.org/TR/capability-urls/).

> When capability URLs are used, they should be used within an 
> appropriate HTTP verb to enable a relevant action. For example, an 
> HTTP GET on a capability URL should not result in side effects such as 
> the deletion of a resource. Capability URLs should encode access 
> permissions for a resource, not actions on that resource.

Some common uses of capability URLs break this pattern, in favor of 
providing easy actions, especially from email. For instance, 'confirm 
email' and 'unsubscribe' actions are typically executed as GETs on a 
capability URL, but they perform an action.

> Capability URLs must be unique, but they should also avoid being 
> guessable. For example, if capability URLs are generating using a URL 
> like https://example.org/access/{number} and number is merely a 
> sequentially increasing integer, it would be incredibly easy to scan 
> through possible numbers to locate new information.

It would be great to provide more detail here. For instance: capability 
URLs should be generated using a secure random number generator, and 
contain at least N bits of entropy. (N may depend on the sparseness or 
density of the URL space). Ideally there should be a rate limit on 
accesses to capability URLs to prevent enumeration, even if the rate 
limit is very generous. And capability URLs should not be passed through 
a URL shortener that has lower protections against enumeration than the 
original capability URL.

If using a hash function to generate capability URLs (common for 
password reset), use an HMAC, not hash(secret + data), otherwise you 
will be vulnerable to length extension attacks.

> One possible application pattern is for capability URLs to redirect 
> (with a 302 Found) to the canonical URL and for the server to use the 
> Referer header, set through the redirect, to determine the level of 
> access granted to the user.

I don't think this works. By default (without special security 
settings), on 302, browsers will not
pass a Referer header matching the URL that 302'ed. Instead they will 
pass the same Referer header
that they sent to the URL that 302'ed.

Also, it's common for users who are given a capability URL to click on 
it, double-checking that it
works as expected. If the capability URL 302'ed to a canonical URL, and 
those users then copy the
result from the location bar, they would send out an incorrect URL that 
does not grant the
capability they intended.

> Future Work ... separate HTTP header that indicates that the requested 
> URL is a capability URL

It might be interesting instead to specify this as a well-known string 
within the URL, e.g. /capability/. This would allow webmail providers to 
apply special logic to emails containing capability URLs. For instance, 
when an attacker gets access to an email account, they often request 
password reset URLs to be sent from various services to that email 
address, so they can take over the matching accounts on those services. 
A webmail provider could choose that, if an email account has recent 
signs of a takeover, all capability URLs sent to that account are 
sequestered for a week to give the real user a chance to re-secure their 
email before other accounts are compromised.

A similar effect could be achieved by specifying this as an attribute on 
anchor tags within emails.

> 3.1.1 Forgotten Passwords

It would be great to add more specific guidelines for the forgotten 
passwords case in particular. E.g.: Password reset links should expire 
after a certain amount of time. All extant password reset links should 
expire after a password is successfully changed (either via a capability 
URL or via a logged-in account). All extant password reset links should 
expire after the email address on the account changes.

This doc should probably also discuss <meta name="referrer" 
value="origin"> as a best practice for pages rendered at a capability url.

Received on Monday, 23 June 2014 09:49:33 UTC