-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy path2014-02-06.html
761 lines (635 loc) · 46.7 KB
/
2014-02-06.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
<!DOCTYPE html>
<html lang="en" dir="ltr" typeof="bibo:Document " about="" property="dcterms:language" content="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
<title>
Good Practices for Capability URLs
</title>
<style>/* --- EXAMPLES --- */
div.example-title {
min-width: 7.5em;
color: #b9ab2d;
}
div.example-title span {
text-transform: uppercase;
}
aside.example, div.example, div.illegal-example {
padding: 0.5em;
margin: 1em 0;
position: relative;
clear: both;
}
div.illegal-example { color: red }
div.illegal-example p { color: black }
aside.example, div.example {
padding: .5em;
border-left-width: .5em;
border-left-style: solid;
border-color: #e0cb52;
background: #fcfaee;
}
aside.example div.example {
border-left-width: .1em;
border-color: #999;
background: #fff;
}
aside.example div.example div.example-title {
color: #999;
}
</style><style>/* --- ISSUES/NOTES --- */
div.issue-title, div.note-title {
padding-right: 1em;
min-width: 7.5em;
color: #b9ab2d;
}
div.issue-title { color: #e05252; }
div.note-title { color: #2b2; }
div.issue-title span, div.note-title span {
text-transform: uppercase;
}
div.note, div.issue {
margin-top: 1em;
margin-bottom: 1em;
}
.note > p:first-child, .issue > p:first-child { margin-top: 0 }
.issue, .note {
padding: .5em;
border-left-width: .5em;
border-left-style: solid;
}
div.issue, div.note {
padding: 1em 1.2em 0.5em;
margin: 1em 0;
position: relative;
clear: both;
}
span.note, span.issue { padding: .1em .5em .15em; }
.issue {
border-color: #e05252;
background: #fbe9e9;
}
.note {
border-color: #52e052;
background: #e9fbe9;
}
</style><link href="editorial.css" rel="stylesheet" type="text/css">
<style>/*****************************************************************
* ReSpec 3 CSS
* Robin Berjon - http://berjon.com/
*****************************************************************/
/* --- INLINES --- */
em.rfc2119 {
text-transform: lowercase;
font-variant: small-caps;
font-style: normal;
color: #900;
}
h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym,
h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr {
border: none;
}
dfn {
font-weight: bold;
}
a.internalDFN {
color: inherit;
border-bottom: 1px solid #99c;
text-decoration: none;
}
a.externalDFN {
color: inherit;
border-bottom: 1px dotted #ccc;
text-decoration: none;
}
a.bibref {
text-decoration: none;
}
cite .bibref {
font-style: normal;
}
code {
color: #ff4500;
}
/* --- TOC --- */
.toc a, .tof a {
text-decoration: none;
}
a .secno, a .figno {
color: #000;
}
ul.tof, ol.tof {
list-style: none outside none;
}
.caption {
margin-top: 0.5em;
font-style: italic;
}
/* --- TABLE --- */
table.simple {
border-spacing: 0;
border-collapse: collapse;
border-bottom: 3px solid #005a9c;
}
.simple th {
background: #005a9c;
color: #fff;
padding: 3px 5px;
text-align: left;
}
.simple th[scope="row"] {
background: inherit;
color: inherit;
border-top: 1px solid #ddd;
}
.simple td {
padding: 3px 10px;
border-top: 1px solid #ddd;
}
.simple tr:nth-child(even) {
background: #f0f6ff;
}
/* --- DL --- */
.section dd > p:first-child {
margin-top: 0;
}
.section dd > p:last-child {
margin-bottom: 0;
}
.section dd {
margin-bottom: 1em;
}
.section dl.attrs dd, .section dl.eldef dd {
margin-bottom: 0;
}
@media print {
.removeOnSave {
display: none;
}
}
</style><link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/W3C-ED"><!--[if lt IE 9]><script src='https://www.w3.org/2008/site/js/html5shiv.js'></script><![endif]--></head>
<body class="h-entry" style="" role="document" id="respecDocument"><div class="head" role="contentinfo" id="respecHeader">
<p>
<a href="http://www.w3.org/"><img width="72" height="48" src="https://www.w3.org/Icons/w3c_home" alt="W3C"></a>
</p>
<h1 class="title p-name" id="title" property="dcterms:title">Good Practices for Capability URLs</h1>
<h2 property="dcterms:issued" datatype="xsd:dateTime" content="2014-02-06T12:50:32.000Z" id="w3c-editor-s-draft-06-february-2014"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2014-02-06">06 February 2014</time></h2>
<dl>
<dt>This version:</dt>
<dd><a class="u-url" href="http://w3ctag.github.io/capability-urls/">http://w3ctag.github.io/capability-urls/</a></dd>
<dt>Latest published version:</dt>
<dd><a href="http://www.w3.org/TR/capability-urls/">http://www.w3.org/TR/capability-urls/</a></dd>
<dt>Latest editor's draft:</dt>
<dd><a href="http://w3ctag.github.io/capability-urls/">http://w3ctag.github.io/capability-urls/</a></dd>
<dt>Editor:</dt>
<dd class="p-author h-card vcard" rel="bibo:editor" inlist=""><span typeof="foaf:Person"><span property="foaf:name" class="p-name fn">Jeni Tennison</span>, <a rel="foaf:workplaceHomepage" class="p-org org h-org h-card" href="http://www.theodi.org/">ODI</a></span>
</dd>
<dt>Repository:</dt>
<dd>
<a href="https://github.com/w3ctag/capability-urls">
We are on Github.
</a>
</dd>
<dd>
<a href="https://github.com/w3ctag/capability-urls/issues">
File a bug.
</a>
</dd>
<dd>
<a href="https://github.com/w3ctag/capability-urls/commits/gh-pages">
Commit history.
</a>
</dd>
</dl>
<p class="copyright">
<a href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> ©
2014
<a href="http://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup>
(<a href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>,
<a href="http://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>,
<a href="http://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>),
All Rights Reserved.
<abbr title="World Wide Web Consortium">W3C</abbr> <a href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
<a href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and
<a href="http://www.w3.org/Consortium/Legal/copyright-documents">document use</a>
rules apply.
</p>
<hr>
</div>
<section id="abstract" class="introductory" property="dcterms:abstract" datatype="" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter"><h2 aria-level="1" role="heading" id="h2_abstract">Abstract</h2>
<p>
Capability URLs grant access to a resource to anyone who has the URL. There are times when this is useful, for example one-shot password reset URLs, but overuse can be problematic as URLs cannot generally be kept secret. This document provides some good practices for web developers who wish to incorporate capability URLs into their applications.
</p>
</section><section id="sotd" class="introductory" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter"><h2 aria-level="1" role="heading" id="h2_sotd">Status of This Document</h2>
<p>
<em>This section describes the status of this document at the time of its publication.
Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the
latest revision of this technical report can be found in the <a href="http://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at
http://www.w3.org/TR/.</em>
</p>
<p>
This is a proposed Working Draft, towards a TAG Finding.
</p>
<p>
This document was published by the <a href="http://www.w3.org/2001/tag/">Technical Architecture Group</a> as an Editor's Draft.
If you wish to make comments regarding this document, please send them to
<a href="mailto:www-tag@w3.org">www-tag@w3.org</a>
(<a href="mailto:www-tag-request@w3.org?subject=subscribe">subscribe</a>,
<a href="http://lists.w3.org/Archives/Public/www-tag/">archives</a>).
All comments are welcome.
</p>
<p>
Publication as an Editor's Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr>
Membership. This is a draft document and may be updated, replaced or obsoleted by other
documents at any time. It is inappropriate to cite this document as other than work in
progress.
</p>
<p>
This document was produced by a group operating under the
<a id="sotd_patent" about="" rel="w3p:patentRules" href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title="World Wide Web Consortium">W3C</abbr> Patent
Policy</a>.
<abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="http://www.w3.org/2001/tag/disclosures" rel="disclosure">public list of any patent
disclosures</a>
made in connection with the deliverables of the group; that page also includes
instructions for disclosing a patent. An individual who has actual knowledge of a patent
which the individual believes contains
<a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential
Claim(s)</a> must disclose the information in accordance with
<a href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section
6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>.
</p>
</section><section id="toc"><h2 class="introductory" aria-level="1" role="heading" id="h2_toc">Table of Contents</h2><ul class="toc" role="directory" id="respecContents"><li class="tocline"><a href="#intro" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">2. </span>Example Capability URLs</a><ul class="toc"><li class="tocline"><a href="#password-resets" class="tocxref"><span class="secno">2.1 </span>Password Resets</a></li><li class="tocline"><a href="#second-life" class="tocxref"><span class="secno">2.2 </span>Second Life</a></li><li class="tocline"><a href="#google-calendar" class="tocxref"><span class="secno">2.3 </span>Google Calendar</a></li><li class="tocline"><a href="#github-gists" class="tocxref"><span class="secno">2.4 </span>Github Gists</a></li><li class="tocline"><a href="#doodle-polls" class="tocxref"><span class="secno">2.5 </span>Doodle polls</a></li><li class="tocline"><a href="#flickr-images" class="tocxref"><span class="secno">2.6 </span>Flickr images</a></li></ul></li><li class="tocline"><a href="#advantages" class="tocxref"><span class="secno">3. </span>Reasons to Use Capabilty URLs</a><ul class="toc"><li class="tocline"><a href="#no-login-required" class="tocxref"><span class="secno">3.1 </span>No Login Required</a><ul class="toc"><li class="tocline"><a href="#forgotten-passwords" class="tocxref"><span class="secno">3.1.1 </span>Forgotten Passwords</a></li><li class="tocline"><a href="#low-friction-accounts" class="tocxref"><span class="secno">3.1.2 </span>Low Friction Accounts</a></li><li class="tocline"><a href="#websites-without-accounts" class="tocxref"><span class="secno">3.1.3 </span>Websites without Accounts</a></li></ul></li><li class="tocline"><a href="#easy-onward-sharing" class="tocxref"><span class="secno">3.2 </span>Easy Onward Sharing</a></li><li class="tocline"><a href="#easy-client-api" class="tocxref"><span class="secno">3.3 </span>Easy Client API</a></li></ul></li><li class="tocline"><a href="#disadvantages" class="tocxref"><span class="secno">4. </span>Potential Issues</a><ul class="toc"><li class="tocline"><a href="#risk-of-exposure" class="tocxref"><span class="secno">4.1 </span>Risk of Exposure</a></li><li class="tocline"><a href="#detecting-compromises" class="tocxref"><span class="secno">4.2 </span>Detecting Compromises</a></li><li class="tocline"><a href="#handling-compromises" class="tocxref"><span class="secno">4.3 </span>Handling Compromises</a></li><li class="tocline"><a href="#web-architecture" class="tocxref"><span class="secno">4.4 </span>Web Architecture</a></li><li class="tocline"><a href="#beyond-the-single-page" class="tocxref"><span class="secno">4.5 </span>Beyond the Single Page</a></li></ul></li><li class="tocline"><a href="#recommendations" class="tocxref"><span class="secno">5. </span>Recommendations</a><ul class="toc"><li class="tocline"><a href="#application-design" class="tocxref"><span class="secno">5.1 </span>Application Design</a></li><li class="tocline"><a href="#capability-url-design" class="tocxref"><span class="secno">5.2 </span>Capability URL Design</a></li><li class="tocline"><a href="#ui-design-considerations" class="tocxref"><span class="secno">5.3 </span>UI Design Considerations</a></li><li class="tocline"><a href="#canonical-urls" class="tocxref"><span class="secno">5.4 </span>Canonical URLs</a></li></ul></li><li class="tocline"><a href="#future-work" class="tocxref"><span class="secno">A. </span>Future Work</a></li></ul></section>
<section id="intro" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_intro"><span class="secno">1. </span>Introduction</h2>
<p>There are two broad methods of controlling access to information that is published on the web:</p>
<ol>
<li> the server can have access control measures that require people accessing the content to provide the correct token(s) (such as a password) before the content is accessible</li>
<li> the information can be published at an obscure or unguessable URL, and links to it only provided to people who have permission to access it</li>
</ol>
<p>The URLs used in the second method are known as "capability URLs": an agent who possesses the URL is given the capability to access the information.</p>
<p>This document describes:</p>
<ul>
<li>cases where capability URLs are used on the web today</li>
<li>advantages and disadvantages of using capability URLs to control access to content</li>
<li>design considerations when creating websites that use capability URLs</li>
<li>areas of technical development to support the use of capability URLs</li>
</ul>
</section>
<section id="examples" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_examples"><span class="secno">2. </span>Example Capability URLs</h2>
<p>
Capability URLs are in widespread use. This section contains examples from the web where capability URLs are used.
</p>
<section id="password-resets">
<h3 aria-level="2" role="heading" id="h3_password-resets"><span class="secno">2.1 </span>Password Resets</h3>
<p>
When a user forgets their password to access a site, the site cannot simply tell them what their password is as this would require the site to store and transmit their password as plain text, which is extremely insecure.
</p>
<p>
The pattern that is usually used instead is that the user is sent an email that contains a link that provides the user who has received that link with enough permissions to reset their password. This example is from Dropbox:
</p>
<div class="example"><div class="example-title"><span>Example 1</span></div><pre class="example">Your Dropbox password recently expired. You can reset it <a href="https://www.dropbox.com/l/Q8eJH22ft0ckDJDeff1Do10/password_reset">here</a>.</pre></div>
<p>In this case the capability URL is <code>https://www.dropbox.com/l/Q8eJH22ft0ckDJDeff1Do10/password_reset</code>. Anyone accessing this link is able to change the password for the user with whom the capability URL is associated.</p>
</section>
<section id="second-life">
<h3 aria-level="2" role="heading" id="h3_second-life"><span class="secno">2.2 </span>Second Life</h3>
<figure id="fig-using-capability-urls-linden-lab-official-registration-api">
<blockquote cite="http://wiki.secondlife.com/wiki/Linden_Lab_Official:Registration_API#Using_capability_URLs">Reg API capabilities represent permissions to perform certain actions.</blockquote>
<figcaption>Fig. <span class="figno">1</span> <span class="fig-title"><a href="http://wiki.secondlife.com/wiki/Linden_Lab_Official:Registration_API#Using_capability_URLs">Using capability URLs</a> – Linden Lab Official:Registration API</span></figcaption>
</figure>
<p>
Within the Second Life API, user agents aren't required to provide credentials with each action that they wish to take. Instead, they submit a single form with a username and password and the response contains a set of capability URLs for different capabilities. For example:
</p>
<div class="example"><div class="example-title"><span>Example 2</span></div><pre class="example"><llsd>
<map>
<key>create_user</key>
<string>https://cap.secondlife.com/cap/0/35ff3b8c-a30d-4d18-b29a-e3f7f6c79cb6</string>
<key>check_name</key>
<string>https://cap.secondlife.com/cap/0/6e528ba1-a8b0-4f6b-8b56-362ee6f5cef8</string>
<key>get_last_names</key>
<string>https://cap.secondlife.com/cap/0/be4e4d2e-c00a-46cd-bb8d-d17cb8e92c9b</string>
<key>get_error_codes</key>
<string>https://cap.secondlife.com/cap/0/e75f81a5-b7da-4480-8f95-b1cf9d2d680f</string>
</map>
</llsd></pre></div>
<p>
The documentation provides two guidelines for using these capability URLs:
</p>
<figure id="fig-using-capability-urls-linden-lab-official-registration-api-1">
<blockquote cite="http://wiki.secondlife.com/wiki/Linden_Lab_Official:Registration_API#Using_capability_URLs">
<ul>
<li>Do not hard-code your capabilities URLs. Either code your capabilities URLs as constants, or better yet, obtain them at run-time. Capability URLs will expire eventually, so fresh ones are always better.</li>
<li>Keep your capability URLs secret! The capabilities granted to you are only meant for you. A capability URL is sensitive much like a password. Moreover, Linden Lab tracks the use of each capability.</li>
</ul>
</blockquote>
<figcaption>Fig. <span class="figno">2</span> <span class="fig-title"><a href="http://wiki.secondlife.com/wiki/Linden_Lab_Official:Registration_API#Using_capability_URLs">Using capability URLs</a> – Linden Lab Official:Registration API</span></figcaption>
</figure>
</section>
<section id="google-calendar">
<h3 aria-level="2" role="heading" id="h3_google-calendar"><span class="secno">2.3 </span>Google Calendar</h3>
<p>
Google Calendar provides Private Addresses for XML and iCalendar formats of a calendar. These can be used by anyone within a feed reader or a calendar programme to provide access to the calendar, but users are warned "Your calendar's Private Address was designed for your use only, so be sure not to share this address with others." (from <a href="https://support.google.com/calendar/answer/37106?hl=en&ref_topic=1672529">About the 'Private Address'</a>).
</p>
<p>
The help associated with Private Addresses similarly warns against sharing the URLs with others:
</p>
<figure id="fig-help-associated-with-private-address-in-google-calendar">
<img src="gcal.png" alt="Help box reading 'Your calendar's Private Address is designed for your use only. All of your calendar information is available via your private links, so don't share this address with others. To change your Private Address and disable any previous access, click the Reset Private URLs link.'">
<figcaption>Fig. <span class="figno">3</span> <span class="fig-title">Help associated with Private Address in Google Calendar</span></figcaption>
</figure>
</section>
<section id="github-gists">
<h3 aria-level="2" role="heading" id="h3_github-gists"><span class="secno">2.4 </span>Github Gists</h3>
<p>
GitHub Gists support sharing and discussing versioned code and other files with other people. These can be created anonymously, and can be kept private. Access to private Gists is provided simply through sharing the URL for the Gist.
</p>
<figure id="fig-a-secret-github-gist">
<img src="gist.png" alt="Gist page with a pop-up explaining 'Secret gists are hidden from search engines but visible to anyone you give the URL.'">
<figcaption>Fig. <span class="figno">4</span> <span class="fig-title">A secret GitHub Gist</span></figcaption>
</figure>
</section>
<section id="doodle-polls">
<h3 aria-level="2" role="heading" id="h3_doodle-polls"><span class="secno">2.5 </span>Doodle polls</h3>
<p>
Doodle enables users to create polls that can be accessed through URLs without users logging in. The URLs are provided to the administrator of the poll within the browser and through email. For example:
</p>
<figure id="fig-doodle-page-for-a-new-poll">
<img src="doodle.png" alt="Doodle page providing URLs with a Participation link saying 'Send this link to anyone you wish to invite.' and an Administration link saying 'Access this link to change, close or delete this poll.'">
<figcaption>Fig. <span class="figno">5</span> <span class="fig-title">Doodle page for a new poll</span></figcaption>
</figure>
</section>
<section id="flickr-images">
<h3 aria-level="2" role="heading" id="h3_flickr-images"><span class="secno">2.6 </span>Flickr images</h3>
<p>
Private images on Flickr can be shared through Guest Passes which are generated for a given image on demand.
</p>
<figure id="fig-flickr-dialog-for-a-new-guest-pass">
<img src="flickr-guest-pass.png" alt="Flickr dialog saying 'Grab the link' for a Guest Pass and inviting the user to visit the Guess Pass History.">
<figcaption>Fig. <span class="figno">6</span> <span class="fig-title">Flickr dialog for a new Guest Pass</span></figcaption>
</figure>
<p>
Users can view the Guest Pass History which provides the option of expiring the current Guest Pass for the image.
</p>
<figure id="fig-flickr-guest-pass-history">
<img src="flickr-guest-pass-history.png" alt="Portion of a Guest Pass History on Flickr, showing the option to Expire the Guest Pass.">
<figcaption>Fig. <span class="figno">7</span> <span class="fig-title">Flickr Guest Pass History</span></figcaption>
</figure>
</section>
</section>
<section id="advantages" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_advantages"><span class="secno">3. </span>Reasons to Use Capabilty URLs</h2>
<p>There are three rationales for using capability URLs evident in the examples described above.</p>
<section id="no-login-required">
<h3 aria-level="2" role="heading" id="h3_no-login-required"><span class="secno">3.1 </span>No Login Required</h3>
<p>
A capability URL enables a user to access a service without having a login or password on that service. There are three situations where that is a particular advantage:
</p>
<ul>
<li>users who can't remember login details</li>
<li>users who don't want to create accounts</li>
<li>developers who don't want to support accounts</li>
</ul>
<section id="forgotten-passwords">
<h4 aria-level="3" role="heading" id="h4_forgotten-passwords"><span class="secno">3.1.1 </span>Forgotten Passwords</h4>
<p>
Users frequently forget their passwords, especially when their form is restricted based on length or types of characters that they contain. Sending a URL to users who forget their passwords is preferable to sending a password because:
</p>
<ul>
<li>sending a password would require the website to send (and possibly store) the password in plain text, which is a bad security practice</li>
<li>the capability URL can be disabled after it has been accessed, which means that even if the email or URL is shared later on, it doesn't provide ongoing access to the account</li>
<li>the capability URL can resolve to a page that forces the user to reset their password; if users were simply presented with a password or granted access to the entire system with the URL then they might not remember to reset their password</li>
</ul>
</section>
<section id="low-friction-accounts">
<h4 aria-level="3" role="heading" id="h4_low-friction-accounts"><span class="secno">3.1.2 </span>Low Friction Accounts</h4>
<p>
There are a proliferation of web-based services which provide for user accounts, to help record user preferences and history. Creating another user account can become a high burden for users, particularly when they don't expect to use the account very frequently.
</p>
<p>
Web-based applications that do not require user information in order to function may enable users to access the service without creating an account, or only prompt the user to create an account after they have used the service for a while.
</p>
<p>
Using capability URLs is beneficial to the more regular users of a web-based application because it enables them to collaborate with other people who are not regular users of the service. Regular users can create a resource and share a URL for that resource with their potential collaborators through another route (eg through email).
</p>
<p>
Capability URLs that are used to facilitate collaboration without requiring accounts are generally controlled by a regular user, who might wish to:
</p>
<ul>
<li>create different capability URLs for different people or groups that they wish to collaborate with</li>
<li>create different capability URLs for different types of action that they wish to permit on a resource (eg editing or commenting or viewing)</li>
<li>be able to revoke permissions for given capability URLs if they learn they have been shared outside the intended group</li>
</ul>
</section>
<section id="websites-without-accounts">
<h4 aria-level="3" role="heading" id="h4_websites-without-accounts"><span class="secno">3.1.3 </span>Websites without Accounts</h4>
<p>
Account management is seldom the main goal of a web-based application. Although it can be relatively easy for developers to plug in account management, there is an overhead involved: it can raise security concerns, and has legal implications because it involves storing personal data.
</p>
<p>
In some applications there is no risk of someone else deleting important work belonging to another user. This might be because the web application is not used to do important work. Or it might be that the application does not support destructive acts.
</p>
<p>
In these cases, it may be that the developer of a web application chooses to use capability URLs rather than supporting user accounts, letting them focus development on the main purpose of the application rather than account management.
</p>
</section>
</section>
<section id="easy-onward-sharing">
<h3 aria-level="2" role="heading" id="h3_easy-onward-sharing"><span class="secno">3.2 </span>Easy Onward Sharing</h3>
<p>
A second set of reasons for supporting capability URLs is that it enables those with whom access is originally shared to continue to share that access with their own network.
</p>
<p>
For example, if a user is trying to arrange a meeting between organisations, they might not know all the people who should attend the meeting from other organisations. Under a normal account-based method, the user would typically have to gather the information about who should attend the meeting before granting each of those individuals access to the system. With a capability URL, they only have to share the URL with a representative from each organisation, and trust that representative to pass on the URL to whichever colleagues need to take part.
</p>
<p>
Capability URLs can thus enable permissions to flow through networks more easily than they can with an account-based system.
</p>
</section>
<section id="easy-client-api">
<h3 aria-level="2" role="heading" id="h3_easy-client-api"><span class="secno">3.3 </span>Easy Client API</h3>
<p>
Authentication can be burdensome in HTTP APIs because HTTP is a stateless protocol and requires authentication tokens to be passed and processed on each transaction. This takes up both bandwidth and processing power, which can be a significant overhead for frequent, small, messages.
</p>
<p>
Capability URLs can be used instead. Clients:
</p>
<ol>
<li>perform authentication as normal</li>
<li>request a list of capability URLs to use for the rest of the session</li>
<li>use those URLs without authentication</li>
</ol>
<p>
This removes the authentication cost on each transaction while keeping the exchanges fairly secure.
</p>
<div class="note"><div class="note-title" aria-level="3" role="heading" id="h_note_1"><span>Note</span></div><p class="">
There are larger issues here about using HTTP for frequent, small, messages. Arguably, HTTP isn't an appropriate protocol in these circumstances, or other workarounds such as long polling or pipelined requests would work better.
</p></div>
</section>
</section>
<section id="disadvantages" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_disadvantages"><span class="secno">4. </span>Potential Issues</h2>
<p>
There are disadvantages to using capability URLs arising from the fact that the URLs were not originally designed to be used in this way.
</p>
<section id="risk-of-exposure">
<h3 aria-level="2" role="heading" id="h3_risk-of-exposure"><span class="secno">4.1 </span>Risk of Exposure</h3>
<p>
In general, applications that use URLs are not designed to treat them as sensitive information. URLs appear within URL bars, from which they can be copied easily. They appear within application logs, such as within web servers and in browser history.
</p>
<p>
There are more subtle routes for exposure too. If a link to another site is followed on a page accessed through a capability URL, that site may be notified of the capability URL through the <code>Referer</code> HTTP header. Third party scripts within a page accessed through a capability URL can access that URL and potentially record it elsewhere. Hosted services that synchronise browser histories, and browser plugin toolbars can easily get hold of URLs for pages that someone using them visits.
</p>
<p>
The method by which a user gets the capability URL in the first place may also be compromised, enabling an ISP or web-based email service to become aware of the URL. Capability URLs will also be exposed to URL shortening services such as <code>t.co</code> if they are shared via Twitter direct messages.
</p>
<p>
Any of these sources of URLs can be used by search engines and other crawlers, and may therefore result in pages protected through capability URLs being shown within search results.
</p>
<p>
In short, the risk of exposure of capability URLs is very high, particularly when they are accessed through a browser.
</p>
</section>
<section id="detecting-compromises">
<h3 aria-level="2" role="heading" id="h3_detecting-compromises"><span class="secno">4.2 </span>Detecting Compromises</h3>
<p>
It can be hard to detect when a capability URL has been compromised, because there is nothing to distinguish legitimate access from illegitimate access. Unexpected access might be detectable by examining the IP addresses or User-Agent strings in requests for the resource, but there is little else to go on.
</p>
</section>
<section id="handling-compromises">
<h3 aria-level="2" role="heading" id="h3_handling-compromises"><span class="secno">4.3 </span>Handling Compromises</h3>
<p>
If a capability URL does leak out to unwanted recipients, the person who originally granted access through that URL needs to be able to revoke it. This is exactly the same as needs to happen in normal account-driven access control. However, capability URLs tend to be designed to be the same for everyone who has the given capability, and therefore revoking the capability URL has an impact on all those who had it. Conversely, in account-based access control it tends to be possible to target the withdrawal of rights on a single user.
</p>
<p>
It would be possible to design systems that use capability URLs in a more targetted way: that enable users to generate multiple URLs for the same capability and to pass those on to different people. This would enable targetted revocation of access rights when a particular URL is compromised.
</p>
</section>
<section id="web-architecture">
<h3 aria-level="2" role="heading" id="h3_web-architecture"><span class="secno">4.4 </span>Web Architecture</h3>
<p>
Capability URLs encode a combination of a resource and access privileges for that resource. This leads to separate URLs being used to refer to the same resource (but with different permissions about what can be done with it). For example, Google Calendar provides different URLs for the same iCalendar representation of a calendar for public and private use.
</p>
<p>
Using multiple URLs for the same resource runs contrary to good practice:
</p>
<figure id="fig-architecture-of-the-world-wide-web-volume-one">
<blockquote>
<strong>Good practice: Avoiding URI aliases</strong>
<br>
A URI owner <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> associate arbitrarily different URIs with the same resource.
</blockquote>
<figcaption>Fig. <span class="figno">8</span> <span class="fig-title"><a href="http://www.w3.org/TR/webarch/#avoid-uri-aliases">Architecture of the World Wide Web, Volume One</a></span></figcaption>
</figure>
<p>
However, the main reason for avoiding URI aliases is based on sharing of the URI: it is better for everyone linking to, or talking about, the same resource to refer to it with the same URL, as this creates a more coherent network. Unlike normal URLs, capability URLs are oriented around only limited sharing. In these circumstances, having multiple aliases is not an issue.
</p>
<p>
What may need to be considered, however, is how to transition from providing access to a resource through capability URLs and taking it public, using a normal URL. This is discussed further in <a href="#canonical-urls" class="sectionRef sec-ref">section <span class="secno">5.4</span> <span class="sec-title">Canonical URLs</span></a>.
</p>
</section>
<section id="beyond-the-single-page">
<h3 aria-level="2" role="heading" id="h3_beyond-the-single-page"><span class="secno">4.5 </span>Beyond the Single Page</h3>
<p>
All the examples of capability URLs described in <a class="sectionRef sec-ref" href="#examples">section <span class="secno">2.</span> <span class="sec-title">Example Capability URLs</span></a> are self-contained: once a user has accessed a page through a capability URL, they are able to do all they need to do within that page. Capability URLs are less easy to use in applications that require the user to access multiple pages, because each of those pages must be accessed through a (different) capability URL.
</p>
</section>
</section>
<section id="recommendations" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_recommendations"><span class="secno">5. </span>Recommendations</h2>
<p>
This section outlines recommendations about when and how to use capability URLs within web applications.
</p>
<section id="application-design">
<h3 aria-level="2" role="heading" id="h3_application-design"><span class="secno">5.1 </span>Application Design</h3>
<p>
The use of capability URLs should not be the default choice in the design of a web application because they are only secure in tightly controlled circumstances. However, in <a href="#advantages" class="sectionRef sec-ref">section <span class="secno">3.</span> <span class="sec-title">Reasons to Use Capabilty URLs</span></a> we outlined three situations in which capability URLs are useful:
</p>
<ul>
<li>To avoid the need for users to log in to perform an action.</li>
<li>To make it easy for those with whom you share URLs to share them with others.</li>
<li>To avoid authentication overheads in APIs.</li>
</ul>
<p>
If you are considering using capability URLs, you should consider other options, the costs of implementing them and the risks of using capability URLs instead. For example:
</p>
<ul>
<li>Could access be restricted using an account-based mechanism instead?</li>
<li>Should you use a protocol other than HTTP?</li>
</ul>
<p>
If you have decided to use capability URLs, depending on the level of risk associated to the discovery of a capability URL, you should employ as many of the following security measures as possible:
</p>
<ul>
<li><strong>Capability URLs should be <code>https</code> URLs.</strong> This does not prevent all exposure of the URL but does prevent it from being shown in plain text within the HTTP request for the URL.</li>
<li><strong>Pages that inform users of capability URLs should be encrypted, by being served through HTTPS.</strong></li>
<li><strong>Capability URLs should expire.</strong> For example, it may be suitable to have a capability URL that can only be accessed once, or one that expires after a week.</li>
<li><strong>Pages accessed through a capability URL should not include links to third-party websites, or to untrusted third-party scripts.</strong> They should not include a mechanism for others to insert such links onto the page (eg through comments). If these are allowed, the links should include <code>rel="noreferrer"</code> to prevent the <code>Referer</code> header from being set.</li>
<li>If capability URLs are controlled by an authenticated user, <strong>it should be possible for that user to revoke the capability URLs associated with the resource that they control</strong>. They should be able to create multiple such capability URLs so that they can revoke access through a compromised capability URL without affecting access from other capability URLs.</li>
<li><strong>The path under which capability URLs are found should be listed within <code>robots.txt</code></strong> to prevent them from being listed by those search engines that honour <code>robots.txt</code>. Do not list individual capability URLs within <code>robots.txt</code>.</li>
</ul>
<p>
<strong>When capability URLs are used, they should be used within an appropriate HTTP verb to enable a relevant action.</strong> For example, an HTTP <code>GET</code> 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.
</p>
<p>
<strong>When capability URLs expire, servers should respond to the URL with either a <code>410 Gone</code> or a <code>404 Not Found</code> response.</strong> In practice, there is little difference between these responses: a <code>410 Gone</code> response requires the application to keep track of which capability URLs have been supported in the past; although this is more work for the application, it does prevent the reassignment of that capability URL to a new resource.
</p>
</section>
<section id="capability-url-design">
<h3 aria-level="2" role="heading" id="h3_capability-url-design"><span class="secno">5.2 </span>Capability URL Design</h3>
<p>
<strong>Capability URLs must be unique, but they should also avoid being guessable.</strong> For example, if capability URLs are generating using a URL like <code>https://example.org/access/{<var>number</var>}</code> and <var>number</var> is merely a sequentially increasing integer, it would be incredibly easy to scan through possible numbers to locate new information.
</p>
<p>
Good unique URLs include an unguessable unique identifier such as a <a href="http://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a>.
</p>
</section>
<section id="ui-design-considerations">
<h3 aria-level="2" role="heading" id="h3_ui-design-considerations"><span class="secno">5.3 </span>UI Design Considerations</h3>
<p>
There is currently no way for built-in user interfaces, such as the location bar of a browser, to detect when a page is being accessed through a capability URL as opposed to a normal URL.
</p>
<p>
To prevent the capability URL from being visible in the location bar, you can use the <code>replaceState()</code> method to replace the displayed URL with the canonical URL. However, this prevents the capability URL from being bookmarked by the user. In addition, if you do this, you should make sure the capability URL is replaced back into the history when the page is unloaded, otherwise it will not be possible for the user to navigate back to the page by navigating through their history.
</p>
<p>
<strong>Users who are provided with capability URLs to share with others should be informed of the consequences of those URLs being shared widely.</strong> Pages should describe what people who get the URL can do with it, and explain the ways in which these URLs can be shared safely.
</p>
</section>
<section id="canonical-urls" typeof="bibo:Chapter" resource="#ref" rel="bibo:Chapter">
<h3 aria-level="2" role="heading" id="h3_canonical-urls"><span class="secno">5.4 </span>Canonical URLs</h3>
<p>
As outlined in <a href="#disadvantages" class="sectionRef sec-ref">section <span class="secno">4.</span> <span class="sec-title">Potential Issues</span></a>, <strong>servers should have a single canonical URL for a resource when there are several capability URLs that are used to provide access to that resource</strong>. This URL may be accessible by users who have the correct access privileges (granted through an account).
</p>
<p>
Canonical URLs may be used:
</p>
<ul>
<li>to list and provide control over capability URLs for the resource</li>
<li>as a URL that is transitioned to when a resource becomes public</li>
<li>as a public URL that anyone can access with limited privileges</li>
<li>as a common URL that can be used by anyone in annotations about the resource</li>
</ul>
<p>
One possible application pattern is for capability URLs to redirect (with a <code>302 Found</code>) to the canonical URL and for the server to use the <code>Referer</code> header, set through the redirect, to determine the level of access granted to the user. This has the advantage of not exposing the capability URL within the browser bar or within the server logs of linked to servers. However, browsers may be set to not expose the <code>Referer</code> header (for security reasons) in which case this method will not work.
</p>
<p>
If content is served directly from pages accessed through capability URLs, these pages can link to the canonical URL for the resource through <code>rel="canonical"</code> either in the metadata for the page (a <code><link></code> element) or within a <code>Link</code> header on the resource.
</p>
<p>
<strong>If the capability URLs refer to a resource that is later made public, they should respond with a <code>301 Moved Permanently</code> providing a redirection to the normal, public, canonical URL.</strong>
</p>
</section>
</section>
<section class="appendix" id="future-work">
<!--OddPage--><h2 aria-level="1" role="heading" id="h2_future-work"><span class="secno">A. </span>Future Work</h2>
<p>
Following the above analysis, the TAG thinks that it would be useful to investigate adding a <a href="http://www.w3.org/TR/CSP/">Content Security Policy</a> directive or a separate HTTP header that indicates that the requested URL is a capability URL. A browser could then protect the URL in various ways such as:
</p>
<ul>
<li>obscuring the location bar</li>
<li>ensuring that the <code>Referer</code> header was not set</li>
<li>disallowing access to the page URL from any third-party scripts</li>
<li>hiding it within the history</li>
</ul>
</section>
</body></html>