├── .github
└── workflows
│ └── auto-publish.yml
├── .gitignore
├── .pr-preview.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── Makefile
├── README.md
├── index.bs
├── published
├── 2015-02-FPWD.html
├── 2015-10-CR.html
├── ECHIDNA
├── WD.html
└── default.css
└── w3c.json
/.github/workflows/auto-publish.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | pull_request: {}
4 | push:
5 | branches: [main]
6 |
7 | jobs:
8 | main:
9 | name: Build, Validate, and Publish
10 | runs-on: ubuntu-20.04
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: w3c/spec-prod@v2
14 | with:
15 | GH_PAGES_BRANCH: gh-pages
16 | BUILD_FAIL_ON: warning
17 | VALIDATE_LINKS: false
18 | VALIDATE_MARKUP: true
19 | W3C_ECHIDNA_TOKEN: ${{ secrets.ECHIDNA_TOKEN }}
20 | W3C_WG_DECISION_URL: https://lists.w3.org/Archives/Public/public-webappsec/2015Mar/0170.html
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | index.html
2 |
--------------------------------------------------------------------------------
/.pr-preview.json:
--------------------------------------------------------------------------------
1 | {
2 | "src_file": "index.bs",
3 | "type": "bikeshed",
4 | "params": {
5 | "force": 1
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/).
4 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Web Application Security Working Group
2 |
3 | Contributions to this repository are intended to become part of Recommendation-track documents
4 | governed by the [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and
5 | [Document License](https://www.w3.org/Consortium/Legal/copyright-documents). To contribute, you must
6 | either participate in the relevant W3C Working Group or make a non-member patent licensing
7 | commitment.
8 |
9 | If you are not the sole contributor to a contribution (pull request), please identify all
10 | contributors in the pull request's body or in subsequent comments.
11 |
12 | To add a contributor (other than yourself, that's automatic), mark them one per line as follows:
13 |
14 | ```
15 | +@github_username
16 | ```
17 |
18 | If you added a contributor by mistake, you can remove them in a comment with:
19 |
20 | ```
21 | -@github_username
22 | ```
23 |
24 | If you are making a pull request on behalf of someone else but you had no part in designing the
25 | feature, you can remove yourself with the above syntax.
26 |
27 | # Tests
28 |
29 | See [CONTRIBUTING.md](https://github.com/w3c/webappsec/blob/master/CONTRIBUTING.md).
30 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | All documents in this Repository are licensed by contributors under the [W3C Document
2 | License](http://www.w3.org/Consortium/Legal/copyright-documents).
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: index.html
2 |
3 | force:
4 | bikeshed -f spec ./index.bs
5 |
6 | index.html: index.bs
7 | bikeshed -f spec ./index.bs
8 |
9 | CR: index.bs
10 | bikeshed -f spec --md-status=CR --md-date=2015-10-08 --md-deadline=2015-11-08 ./index.bs ./published/2015-10-CR.html
11 |
12 | clean:
13 | $(RM) index.html
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Specification 'webappsec-upgrade-insecure-requests'
3 |
4 | This is the repository for webappsec-upgrade-insecure-requests. You're welcome to contribute! Let's make the Web rock our socks
5 | off!
6 |
--------------------------------------------------------------------------------
/index.bs:
--------------------------------------------------------------------------------
1 |
Upgrade Insecure Requests
2 |
3 | Status: ED
4 | Group: WebAppSec
5 | ED: https://w3c.github.io/webappsec-upgrade-insecure-requests/
6 | TR: http://www.w3.org/TR/upgrade-insecure-requests/
7 | Previous Version: from biblio
8 | Shortname: upgrade-insecure-requests
9 | Editor: Carlos Joan Rafael Ibarra Lopez 117196, Google Inc., carlosil@google.com
10 | Former Editor: Mike West 56384, Google Inc., mkwst@google.com
11 | Abstract:
12 | This document defines a mechanism which allows authors to instruct a user
13 | agent to upgrade insecure resource requests to secure transport before
14 | fetching them.
15 | Indent: 2
16 | Level: None
17 | Version History: https://github.com/w3c/webappsec-upgrade-insecure-requests/commits/main/index.bs
18 | Boilerplate: omit conformance, omit feedback-header
19 | !Participate: File an issue (open issues)
20 |
147 |
148 | This section is not normative.
149 |
150 | Increasingly, we encourage authors to transition their sites and applications
151 | away from insecure transport, and onto encrypted and authenticated connections
152 | [[WEB-HTTPS]]. While this migration has significant advantages for both
153 | authors and users, it isn't without negative side-effects.
154 |
155 | Most notably, mixed content checking [[MIX]] has the potential to cause real
156 | headache for administrators tasked with moving substantial amounts of legacy
157 | content onto HTTPS. In particular, going through old content and rewriting
158 | resource URLs manually is a huge undertaking. Moreover, it's often the case
159 | that truly legacy content is difficult or impossible to update. Consider the
160 | BBC's archived websites [[BBC-ARCHIVE]], or the New York Times' hard-coded
161 | URLs [[NYT-HTTPS]].
162 |
163 | We should remove this burden from site authors by allowing them to assert to a
164 | user agent that they intend a site to load only secure resources, and that
165 | insecure URLs ought to be treated as though they had been replaced with equivalent secure
166 | URLs.
167 |
168 | This document defines a new Content Security Policy directive,
169 | upgrade-insecure-requests, through which authors can make
170 | this assertion.
171 | Note: Delivering the policy as a header allows an administrator to easily
172 | opt a set of pages into the upgrade mechanism without touching their source
173 | code individually. The legacy content examples above would not be feasible
174 | with an approach that inlined the policy into HTML, for example.
175 |
176 |
Goals
177 |
178 | The overarching goal is to reduce the burden of migrating websites from
179 | insecure origins by reducing the negative side effects of mixed content
180 | blocking [[MIX]].
181 |
182 | If we assume that authors do the server-side legwork (obtaining a certificate,
183 | configuring the server, setting up redirects), and that authors also ensure
184 | that both first- and third-party content is accessible at the same
185 | [=url/host=] and [=url/path=] on a secure [=url/scheme=], then the
186 | following statements ought to hold after implementing this feature:
187 |
188 |
189 |
190 | Authors should be able to ensure that all content requested by a given
191 | page loads successfully, and securely. Mixed content blocking should not
192 | break pages as a result of migrating to a secure origin.
193 |
194 | Note: This requirement is not met by Mixed Content's strict
195 | mode, which makes something like the opposite assertion.
196 |
197 |
198 | As a result of #1, the user agent should not degrade any security
199 | indicators related to requesting mixed content, as no insecure content
200 | should be requested.
201 |
202 |
203 | Authors should be able to ensure that all internal links correctly send
204 | users to the site's secure address, and not to its pre-migration insecure
205 | address.
206 |
207 |
208 | Authors should be able to achieve all these goals without editing a site's
209 | content. This is particularly important for archived content and legacy
210 | systems for which maintenance is difficult enough, never mind upgrades.
211 |
212 |
213 | Authors should be able to pursue a gradual transition from insecure to
214 | secure, serving secure resources to clients that support upgrades, while
215 | retaining insecure resources for clients that don't.
216 |
217 |
218 |
219 | Note: The mechanism defined here does not intend to supplant Strict
220 | Transport Security [[RFC6797]]. See [[#relation-to-hsts]] for details.
221 |
222 |
Examples
223 |
224 |
Non-navigational Upgrades
225 |
226 |
227 | Megacorp, Inc. wishes to migrate http://example.com/ to
228 | https://example.com. They set up their servers
229 | to make their own resources available over HTTPS, and work with partners in
230 | order to make third-party widgets available securely as well.
231 |
232 | They quickly realize, however, that the majority of their content is locked
233 | up in a database tied to an old content management system, and it contains
234 | hardcoded links to insecure resources (e.g., http:// URLs to images and
235 | other content). Unfortunately, it's a substantial amount of work to update
236 | it.
237 |
238 | As a stopgap measure, Megacorp injects the following header field into every
239 | HTML response that goes out from their servers:
240 |
241 |
244 |
245 | This automatically upgrades all insecure resource requests from their pages
246 | to secure variants, allowing a user agent to treat the following HTML code:
247 |
248 |
259 |
260 | The URL will be rewritten before the request is made, meaning that no
261 | insecure requests will hit the network. Users will be safer, and Megacorp's
262 | administrators will be happier, as all resource requests will be
263 | transparently upgraded with no effort on their part.
264 |
265 |
266 |
Navigational Upgrades
267 |
268 |
269 | Megacorp, Inc. isn't quite ready to deliver Strict Transport Security
270 | headers [[RFC6797]], but does want to keep users on secure pages when
271 | possible. Happily, this comes for free with
272 | upgrade-insecure-requests. That is, they're already
273 | delivering pages with the following header:
274 |
275 |
304 | Tinycorp, Inc. enabled upgrade-insecure-requests a bit
305 | earlier than they should have, as they don't actually support HTTPS on
306 | http://cdn.example.com/. Given the following code:
307 |
308 |
311 |
312 | User agents will upgrade requests, as described in [[#example-nonnavigational]],
313 | rewriting the URL as https://cdn.example.com/image.png. As the
314 | server doesn't respond to secure requests, this results in a network error.
315 |
316 | There is no fallback in this scenario: the user agent acts just as though
317 | the request had been intentionally made, and the request fails.
318 |
319 |
320 |
Recommendations
321 |
322 | We recommend that authors who wish to ensure that user agents which support
323 | upgrade-insecure-requests are as secure as possible do the following:
324 |
325 |
326 |
327 | Redirect insecure, safely upgradable requests from HTTP to HTTPS by
328 | responding with a Location header and a 307
329 | status code.
330 |
331 |
332 | In Nginx, this kind of redirection might look like this:
333 |
334 |
364 |
365 | This is, of course, greatly simplified; your configuration will likely
366 | be significantly more complex.
367 |
368 |
369 |
370 | If the origin is HSTS-safe, then protect
371 | against SSL-stripping man-in-the-middle attacks by sending a
372 | Strict-Transport-Security header with the
373 | preload directive, and ensure that insecure content is
374 | never loaded by enabling Mixed Content's strict mode.
375 |
376 |
377 | In Nginx, adding this header might look like this (note the use of
378 | the preloaded directive, which signifies that this
379 | origin's HSTS state can be safely imported into user agents' HSTS
380 | preload lists):
381 |
382 |
392 |
393 | This is, of course, greatly simplified; your configuration will likely
394 | be significantly more complex.
395 |
396 |
397 | Additionally, work with user agent vendors to add the origin to
398 | HSTS Preload Lists (for example, by submitting the origin to
399 | hstspreload.appspot.com).
400 |
406 | In Nginx, adding this header conditionally might look like this (note
407 | the use of map, as setting headers inside if
408 | without returning immediately is, well, iffy):
409 |
410 |
423 |
424 | This is, of course, greatly simplified; your configuration will likely
425 | be significantly more complex.
426 |
427 |
428 |
429 |
430 |
431 |
440 |
441 |
Key Concepts and Terminology
442 |
443 | : upgrade
444 | :: A [=/request=] is said to be upgraded if it is rewritten
445 | to contain a URL with a [=url/scheme=] of https or
446 | wss.
447 |
448 | : safely upgradable requests
449 | :: A [=/request=] is said to be safely upgradable if the
450 | resource representation which will be returned does not require the
451 | upgrade-insecure-requests mechanism described in this
452 | document to avoid breakage, or if the [=/request=]'s
453 | [=request/header list=] contains an
454 | Upgrade-Insecure-Requests header field with a value of
455 | 1.
456 |
457 | : HSTS-safe origin
458 | :: An origin is said to be HSTS-safe if no
459 | resource representations it returns requires the the
460 | upgrade-insecure-requests mechanism described in
461 | this document to avoid breakage, and if all resource representations
462 | it returns can be served over HTTPS.
463 |
464 | HSTS-safe origins can safely opt-into
465 | Strict-Transport-Security for all user agents,
466 | without risking broken pages for user agents which do not support
467 | upgrade-insecure-requests.
468 |
469 | : conditionally HSTS-safe origin
470 | :: An origin is said to be conditionally HSTS-safe
471 | if one or more resource representations it returns requires the
472 | upgrade-insecure-requests mechanism described in
473 | this document to avoid breakage, and if all resource representations it
474 | returns can be served over HTTPS.
475 |
476 | Conditionally HSTS-safe origins can safely opt-into
477 | Strict-Transport-Security only for user agents which
478 | support upgrade-insecure-requests.
479 |
480 | : preloadable HSTS host
481 | :: A [=url/host=] host is a preloadable HSTS
482 | host if, when performing Known HSTS Host Domain Name
483 | Matching, host is a superdomain match for a
484 | Known HSTS Host which asserts both the includeSubDomains
485 | directive and the preload directive, or host
486 | is a congruent matchfor a Known HSTS Host which asserts
487 | the preload directive.
488 |
489 | Note: This is a long way of saying "any host the user agent has pinned
490 | with a Strict-Transport-Security header that contained
491 | a preload directive".
492 |
493 | The Augmented Backus-Naur Form (ABNF) notation used in [[#delivery]] is
494 | specified in RFC5234. [[!ABNF]]
495 |
496 |
497 |
498 |
499 |
Upgrading Insecure Resource Requests
500 |
501 | In order to allow authors to mitigate the negative side-effects of migration
502 | away from insecure origins, authors may instruct the user agent to
503 | transparently upgrade resource requests to potentially trustworthy URL
504 | variants of the original request's URL.
505 |
506 | To support this instruction:
507 |
508 |
509 |
510 | Environment settings objects and browsing contexts are
511 | given an insecure requests policy which has two
512 | potential values Do Not
513 | Upgrade and
514 | Upgrade. It is
515 | set to Do Not Upgrade unless otherwise specified. This policy
516 | is checked in [[#upgrade-request]] in order to determine whether or not
517 | non-navigation requests and form submissions should be upgraded during
518 | [=/fetching=].
519 |
520 |
521 | Environment settings objects and browsing contexts are
522 | given an upgrade insecure navigations set which
523 | contains a set of ([=url/host=], [=url/port=]) tuples to which navigations
524 | ought to be upgraded. Its value is the empty set unless otherwise
525 | specified. This set is checked in [[#upgrade-request]] in order to
526 | determine whether or not navigation requests should be upgraded.
527 |
528 |
529 |
530 |
531 | The upgrade-insecure-requests Content Security Policy directive
532 |
533 |
534 | A server MAY instruct a user agent to upgrade insecure requests for a
535 | particular protected resource by sending a
536 | Content-Security-Policy header [[!CSP]] that contains a
537 | upgrade-insecure-requests directive, defined via the
538 | following ABNF grammar:
539 |
540 |
564 |
565 |
566 | Monitoring the upgrade-insecure-requests directive has
567 | no effect: the directive is ignored when sent via a
568 | Content-Security-Policy-Report-Only header. Authors can
569 | determine whether or not upgraded resources' original URLs
570 | were insecure via Content-Security-Policy-Report-Only. For
571 | example, Content-Security-Policy-Report-Only:
572 | default-src https:; report-uri /endpoint. See [[#reporting-upgrades]]
573 | for additional detail.
574 |
575 |
Relation to "Mixed Content"
576 |
577 | The upgrade-insecure-requests directive results in
578 | requests being rewritten at the top of the [=/Fetching=] algorithm
579 | [[!FETCH]], as specified in [[#upgrade-request]]. It's important to note that
580 | the rewrite happens before either Mixed Content [[MIX]] or Content
581 | Security Policy checks take effect [[CSP]].
582 |
583 | This ordering means that upgraded requests will not be flagged as
584 | mixed content. Moreover, it means that
585 | upgrade-insecure-requests's effect takes place before
586 | the block-all-mixed-content directive would have a chance
587 | to block the request. If the former is set, the latter is effectively a no-op.
588 |
589 | We recommend that authors set one directive or the other, as outlined in
590 | [[#recommendations]].
591 |
592 |
Feature Detecting Clients Capable of Upgrading
593 |
594 | Sites which require the upgrade mechanism laid out in this document in order
595 | to provide users with a reasonable experience over secure transit need some
596 | way to determine whether or not a particular [=/request=] can safely be
597 | redirected from HTTP to HTTPS (and vice-versa). Moreover, conditionally
598 | HSTS-safe origins can only opt-into
599 | Strict-Transport-Security for supported user agents, and
600 | doing otherwise could have negative consequences for the site's users.
601 |
602 | Rather than relying on user-agent sniffing to make this decision, user agents
603 | can advertise their upgrade capability when making navigation requests
604 | by including an Upgrade-Insecure-Requests header field as
605 | described in [[#preference]].
606 |
607 |
608 | The Upgrade-Insecure-Requests HTTP Request Header Field
609 |
610 |
611 | The
612 | Upgrade-Insecure-Requests HTTP request header
613 | field sends a signal to the server expressing the client's preference
614 | for an encrypted and authenticated response, and that it can successfully
615 | handle the upgrade-insecure-requests directive in order
616 | to make that preference as seamless as possible to provide.
617 |
618 | This preference is represented by the following ANBF:
619 |
620 |
623 |
624 | Note: Though the Upgrade-Insecure-Requests header expresses a
625 | preference, sending it via the existing Prefer header is
626 | problematic, as we expect the response from the server to use it as part of
627 | the cache key. Vary: Prefer is too broad, as discussed in
628 | w3/webappsec#216.
629 |
630 | User agent conformance details are described in step #1 of the the
631 | [[#upgrade-request]] algorithm. That step represents the following
632 | requirements:
633 |
634 |
635 |
668 |
669 |
670 | When a server encounters this preference in an HTTP request's headers, it
671 | SHOULD redirect the user to a potentially trustworthy URL variant
672 | of the resource being requested.
673 |
674 | When a server encounters this preference in an HTTPS request's headers,
675 | it SHOULD include a Strict-Transport-Security header in
676 | the response if the request's [=url/host=] is HSTS-safe or
677 | conditionally HSTS-safe [[RFC6797]].
678 |
679 |
680 | A client that supports this document's upgrade mechanism requests
681 | http://example.com/ as follows:
682 |
683 |
688 |
689 | The server parses the preference, notices that the user's client can deal
690 | well with upgrade requests, and therefore responds to the request by
691 | redirecting the user to a secure version of the resource she's requesting:
692 |
693 |
698 |
699 | The Upgrade-Insecure-Requests
700 | header field is listed in the Vary header, as the
701 | redirect response might otherwise be served by caches to clients that
702 | don't support the upgrade mechanism defined here. A similar effect could be
703 | achieved by making this redirect response uncachable via the
704 | Cache-Control header:
705 |
706 |
770 |
771 |
772 | Likewise, when spinning up a worker, the user agent MUST ensure that it
773 | inherits the setting from the context that created it in the following ways:
774 |
775 |
776 |
803 |
804 | Upgrading insecure requests MUST not interfere with an authors' ability to
805 | track down requests that would be insecure in a user agent that does not
806 | support upgrades. To that end, upgrades MUST be performed after
807 | evaluating request against all monitored security policies,
808 | but before evaluating request against all enforced
809 | policies.
810 |
811 |
812 | Within the context of a protected resource which contains the
813 | insecure image <img src="http://example.com/image.png">,
814 | and delivers the following HTTP headers:
815 |
816 |
849 |
850 | Given a [=/request=] request, this algorithm will rewrite its
851 | [=request/URL=] if the [=request/client=] from which the request originates
852 | has opted-in to upgrades. It will also inject an
853 | Upgrade-Insecure-Requests header field header for
854 | insecure navigation requests in order to improve a server's ability to
855 | feature-detect a client's upgrade capabilities.
856 |
857 | We will not upgrade cross-origin navigation requests, with the
858 | exception of form submissions. Form submissions will be upgraded to mitigate
859 | the risk of data leakage via plaintext submissions.
860 |
861 | Note: This algorithm is called at the top of the Main Fetch algorithm.
862 |
863 |
864 |
865 | If request is a navigation request, [=header list/append=] a
866 | header named Upgrade-Insecure-Requests with a value of
867 | 1 to request's
868 | [=request/header list=] if any of the following
869 | criteria are met:
870 |
871 |
872 |
877 | request's [=request/URL=]'s [=url/host=]
878 | is not a preloadable HSTS host
879 |
880 |
881 |
882 | Note: User agents can choose to append the
883 | Upgrade-Insecure-Requests header field for other
884 | requests, as discussed in [[#preference]].
885 |
891 | If request is a form submission, skip the remaining
892 | substeps, and continue upgrading request.
893 |
894 |
895 | If request's [=request/client=]'s
896 | [=environment/target browsing context=]
897 | is a nested browsing context, skip the remaining substeps
898 | and continue upgrading request.
899 |
900 |
901 | Let tuple be a tuple of request's
902 | [=request/URL=]'s [=url/host=] and [=url/port=].
903 |
904 |
905 | If tuple is contained in [=request/client=]'s
906 | upgrade insecure navigations set, then skip the remaining
907 | substeps, and continue upgrading request.
908 |
909 |
910 |
911 | Return without further modifying request.
912 |
913 |
914 |
915 | Note: We only upgrade top-level navigation requests for hosts
916 | that have explicitly opted-into the behavior for a particular
917 | protected resource, as described in [[#examples]]. Performing
918 | upgrades for top-level navigations to third-party resources brings a
919 | significantly higher potential for breakage, so we're avoiding it for
920 | the moment. Nested navigations (via <{iframe}>, for example) affect
921 | the security status of their embedder, so we ensure that they are
922 | upgraded if necessary.
923 |
924 |
925 | Let upgrade state be the result of executing
926 | [[#should-upgrade-for-client]] upon request's
927 | [=request/client=].
928 |
929 |
930 | If upgrade state is Do Not Upgrade, return without
931 | modifying request.
932 |
933 |
934 | If request's [=request/URL=]'s [=url/scheme=] is
935 | "http", set request's [=request/URL=]'s
936 | [=url/scheme=] to "https", and return.
937 |
938 |
939 |
940 | Note: Due to [[FETCH]]'s recursive nature, this algorithm will upgrade
941 | insecurely-redirected requests as well as insecure initial requests.
942 |
943 |
944 | Should insecure [=/request=]s be upgraded for client?
945 |
946 |
947 | Given an [=/request=]'s [=request/client=]
948 | client (an environment settings object), this algorithm
949 | returns Enforced Upgrade if insecure requests associated with
950 | that client should be upgraded, or Do Not Upgrade otherwise. In
951 | short, this will check the client and return the appropriate insecure
952 | requests policy set on it or its browsing context.
953 |
954 |
955 |
964 | If client has a responsible browsing context, return the
965 | value of its insecure requests policy.
966 |
967 | Note: This catches requests triggered from detached
968 | [=request/client=]s. Not sure this is necessary, really,
969 | given the inheritance structure defined in [[#nesting]].
970 |
981 |
982 | The upgrade-insecure-requests directive does not replace
983 | the Strict-Transport-Security HTTP response header
984 | [[RFC6797]]. Authors who serve their site over secure transport SHOULD send
985 | that header with an appropriate max-age in order to ensure that
986 | users are not subject to SSL stripping attacks by maliciously active network
987 | attackers, or monitoring by maliciously passive network attackers.
988 |
989 |
CSP Violation Reports
990 |
991 | When sending a violation report for an upgraded resource, user agents MUST
992 | target the {{Document}} or {{Worker}} that triggered the request, rather
993 | than the {{Document}} or {{Worker}} on which the
994 | upgrade-insecure-requests directive was set. Due to
995 | [[#nesting]], the latter might be a cross-origin ancestor of the former, and
996 | sending violation reports to that set of reporting endpoints could leak data
997 | in unexpected ways.
998 |
999 | Likewise, the SecurityPolicyViolationEvent MUST NOT target any
1000 | {{Document}} other than the one which triggered the request, for the same
1001 | reasons.
1002 |
1003 |
1004 |
1005 |
Performance Considerations
1006 |
1007 | The upgrade mechanism specified here adds Upgrade-Insecure-Requests:
1008 | 1\r\n to every outgoing navigation request to non-preloadable
1009 | HSTS hosts (as discussed at length on public-webappsec@, and
1010 | w3c/webappsec#216).
1011 | The advantages and intent of the header are laid out in [[#preference]], and
1012 | though we've taken some steps to ensure that it won't be a permanent fixture
1013 | of the platform (by carving out preloadable HSTS hosts), it's going
1014 | to be a long, long time before the header vanishes.
1015 |
1016 | User agents are encouraged to find additional carveouts, and implement them.
1017 |
1018 |
1019 |
1020 |
Authoring Considerations
1021 |
1022 |
Legacy Clients
1023 |
1024 | Legacy clients which do support mixed content blocking [[MIX]], but do not
1025 | support the upgrade-insecure-requests directive will
1026 | continue to have a suboptimal experience on pages containing insecure URLs.
1027 | Authors SHOULD ensure that they collect
1028 | violation reports in order to determine
1029 | which resources are most problematic for their users, and SHOULD use that
1030 | information to prioritize fixes for URLs in legacy content that users will
1031 | most likely request.
1032 |
1033 |
Relation to HSTS
1034 |
1035 | The mechanism specified here deals only with the security policy for a
1036 | specific protected resource. It does not deprecate, replace, or in any
1037 | way reduce the value of the Strict-Transport-Security HTTP
1038 | response header [[RFC6797]]. Authors can and should continue to use that
1039 | header to ensure that their users are not subject to SSL stripping downgrade
1040 | attacks, as the upgrade-insecure-requests directive will
1041 | not ensure that users visiting your site via links on third-party sites will
1042 | be upgraded to HTTPS for the top-level navigation.
1043 |
1044 | Likewise, the Strict-Transport-Security header does not imply
1045 | the behavior that upgrade-insecure-requests activates.
1046 | It only ensures that resources requested from an origin will never hit the
1047 | network insecurely.
1048 |
1049 | We are intentionally keeping these concepts distinct, as authors may choose
1050 | to activate one or the other behavior, but ought not be forced to bind them
1051 | together.
1052 |
1053 |
1054 |
1055 |
1056 |
IANA Considerations
1057 |
1058 |
1059 | Upgrade-Insecure-Requests Header
1060 |
1061 |
1062 | The permanent message header field registry should be updated
1063 | with the following registration: [[!RFC3864]]
1064 |
1065 |
1066 |
Header field name
1067 |
Upgrade-Insecure-Requests
1068 |
1069 |
Applicable protocol
1070 |
http
1071 |
1072 |
Status
1073 |
standard
1074 |
1075 |
Author/Change controller
1076 |
W3C
1077 |
1078 |
Specification document
1079 |
This specification (See [[#preference]])
1080 |
1081 |
1082 |
1083 | Upgrade-Insecure-Requests Directive
1084 |
1085 |
1086 | The Content Security Policy Directive registry should be updated with the
1087 | following registration: [[!RFC7762]]
1088 |
1089 |
1090 |
Directive name
1091 |
Upgrade-Insecure-Requests
1092 |
1093 |
Reference
1094 |
This specification (See [[#delivery]])
1095 |
1096 |
1097 |
1098 |
1099 |
Acknowledgements
1100 |
1101 | Anne van Kesteren helped ensure that the initial draft of this document was
1102 | sane. Peter Eckersley and Daniel Kahn Gillmor clarified the problem space, and
1103 | helped point out the impact.
1104 |
1105 |
--------------------------------------------------------------------------------
/published/2015-02-FPWD.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Upgrade Insecure Requests
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
This document defines a mechanism which allows authors to instruct a user
65 |
66 | agent to upgrade a priori insecure resource requests to
67 | secure transport before Fetching them.
68 |
69 |
70 |
71 |
72 |
Status of this document
73 |
74 |
75 |
76 | This section describes the status of this document at the time of
77 | its publication. Other documents may supersede this document. A list of
78 | current W3C publications and the latest revision of this technical report
79 | can be found in the W3C technical reports
80 | index at http://www.w3.org/TR/.
81 |
82 |
83 |
84 | This document was published by the
85 | Web Application Security Working Group
86 | as a Working Draft. This document is intended to become a W3C Recommendation.
87 |
88 |
89 |
90 | The (archived) public mailing list
91 | public-webappsec@w3.org
92 | (see instructions)
93 | is preferred for discussion of this specification.
94 | When sending e-mail,
95 | please put the text “upgrade-insecure-requests” in the subject,
96 | preferably like this:
97 | “[upgrade-insecure-requests] …summary of comment…”
98 |
99 |
100 |
101 | This document is a First Public Working Draft.
102 |
103 |
104 |
105 | Publication as a First Public Working Draft does not imply endorsement by the W3C
106 | Membership. This is a draft document and may be updated, replaced or
107 | obsoleted by other documents at any time. It is inappropriate to cite this
108 | document as other than work in progress.
109 |
110 |
117 | This document was produced by a group operating under
118 | the 5 February 2004 W3C Patent Policy.
119 | W3C maintains a public list of any patent disclosures
120 | made in connection with the deliverables of the group;
121 | that page also includes instructions for disclosing a patent.
122 | An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s)
123 | must disclose the information in accordance with section 6 of the W3C Patent Policy.
124 |
125 |
Increasingly, we encourage authors to transition their sites and applications
217 | away from insecure transport, and onto encrypted and authenticated connections
218 | [WEB-HTTPS]. While this migration has significant advantages for both
219 | authors and users, it isn’t without negative side-effects.
220 |
221 |
222 |
Most notably, mixed content checking [MIX] has the potential to cause real
223 | headache for administrators tasked with moving substantial amounts of legacy
224 | content onto HTTPS. In particular, going through old content and rewriting
225 | subresource URLs manually is a huge undertaking. Moreover, it’s often the case
226 | that truly legacy content is difficult or impossible to update. Consider the
227 | BBC’s archived websites [BBC-ARCHIVE], or the New York Times' hard-coded
228 | URLs [NYT-HTTPS].
229 |
230 |
231 |
We should remove this burden from site authors by allowing them to assert to a
232 | user agent that they intend a site to load only secure resources, and that
233 | insecure URLs ought to be treated as though they had been replaced with equivalent secure
234 | URLs.
235 |
236 |
237 |
This document defines a new Content Security Policy directive,
238 | upgrade-insecure-requests, through which authors can make
239 | this assertion.
240 | Note: Delivering the policy as a header allows an administrator to easily
241 | opt a set of pages into the upgrade mechanism without touching their source
242 | code individually. The legacy content examples above would not be feasible
243 | with an approach that inlined the policy into HTML, for example.
244 |
245 |
246 |
1.1. Goals
247 |
248 |
249 |
The overarching goal is to reduce the burden of migrating websites from
250 | a priori insecure origins by reducing the negative
251 | side effects of mixed content blocking [MIX].
252 |
253 |
254 |
If we assume that authors do the server-side legwork (obtaining a certificate,
255 | configuring the server, setting up redirects), and that authors also ensure
256 | that content is accessible at the same host and path
257 | on a secure scheme, then the following statements ought to hold after
258 | implementing this feature:
259 |
260 |
261 |
262 |
263 |
264 | Authors should be able to ensure that all content requested by a given
265 | page loads successfully, and securely. Mixed content blocking should not
266 | break pages as a result of migrating to a secure origin.
267 |
268 |
269 |
Note: This requirement is not met by Mixed Content’s strict
270 | mode, which makes something like the opposite assertion.
271 |
272 |
273 |
274 |
275 |
276 | As a result of #1, the user agent should not degrade any security
277 | indicators related to requesting mixed content, as no insecure content
278 | should be requested.
279 |
280 |
281 |
282 |
283 | Authors should be able to ensure that all internal links correctly send
284 | users to the site’s secure address, and not to its pre-migration insecure
285 | address.
286 |
287 |
288 |
289 |
290 | Authors should be able to achieve all these goals without editing a site’s
291 | content. This is particularly important for archived content and legacy
292 | systems for which maintenance is difficult enough, never mind upgrades.
293 |
294 |
295 |
296 |
297 | Authors should be able to pursue a gradual transition from insecure to
298 | secure, serving secure resources to clients that support upgrades, while
299 | retaining insecure resources for clients that don’t.
300 |
301 |
302 |
303 |
304 |
305 |
306 |
Note: The mechanism defined here does not intend to supplant Strict
307 | Transport Security [RFC6797]. See §7.2 Relation to HSTS for details.
308 |
309 |
310 |
1.2. Examples
311 |
312 |
313 |
314 | Megacorp, Inc. wishes to migrate http://example.com/ to
315 | https://example.com. They set up the server-side requirements
316 | to make their own resources available over HTTPS, and work with partners in
317 | order to make third-party widgets available as well.
318 |
319 |
320 |
They quickly realize, however, that the majority of their long-tail content
321 | is locked up in a database tied to an old content management system that
322 | they’ve been avoiding for years ("If it ain’t broke..."). They’ll need to
323 | spend quite a bit of time either migrating the content to their new system,
324 | or modifying it in-place in the old system. Either way, it ends up being a
325 | substantial amount of work, and though they put top programmers on the task,
326 | it clearly won’t be done any time soon.
327 |
328 |
329 |
330 |
As a stopgap measure, Megacorp injects the following header into every
331 | response that goes out through their servers:
This automatically upgrades all insecure resource requests for their pages
341 | to secure variants, allowing a user agent to treat the following HTML code:
342 |
343 |
344 |
345 |
<img src="http://example.com/image.png">
346 |
347 |
348 |
349 |
350 |
as though it had been delivered as:
351 |
352 |
353 |
354 |
<img src="https://example.com/image.png">
355 |
356 |
357 |
358 |
359 |
The URL will be rewritten before the request is made, meaning that no
360 | insecure requests will hit the network. Users will be safer, and Megacorp’s
361 | administrators will be happier.
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
2. Key Concepts and Terminology
372 |
373 |
374 |
375 |
376 |
upgrade
377 |
378 |
379 |
380 |
A Request is said to be upgraded if it is rewritten
381 | to contain a URL with a scheme of https or
382 | wss.
In order to allow authors to mitigate the negative side-effects of migration
398 | away from a priori insecure origins, authors may
399 | instruct the user agent to transparently upgrade resource requests to
400 | potentially secure variants of the original request’s URL.
A server MAY instruct a user agent to upgrade insecure resource requests for
416 | a particular protected resource by sending a
417 | Content-Security-Policy header [CSP] that contains a
418 | upgrade-insecure-requests directive, defined via the following ABNF
419 | grammar:
In a thread on public-webappsec@,
440 | Peter Eckersley suggested modifying this to allow whitelisting specific hosts,
441 | rather than upgrading everything: "That way, if you have N third parties
442 | on a site, and (say) two of them provide images only, and don’t support
443 | HTTPS at all, you can use the upgrade mechanism for scripts on the other
444 | N - 2 origins."
445 |
446 |
447 |
448 | For example, sending the following header with a document will ensure that
449 | subresource requests are upgraded, and that reports are sent out for each
450 | upgrade:
451 |
452 |
453 |
3.2. Feature Detecting Clients Capable of Upgrading
473 |
474 |
475 |
If a site requires the upgrade mechanism described in this document in order
476 | to provide users with a reasonable experience over secure transit, then
477 | authors need to determine whether or not it is safe to redirect a client to
478 | the secure version of a site. Rather than relying on user-agent sniffing to
479 | make this decision, user agents MUST advertise their capabilities when
480 | making insecure navigational requests by sending a Prefer HTTP
481 | request header expressing the desire for a secure representation [RFC7240]
482 | as described in §3.2.1
483 | The return=secure-representation Preference
484 | .
485 |
486 |
487 |
3.2.1.
488 | The return=secure-representation Preference
489 |
490 |
491 |
492 |
The "return=secure-representation" preference
493 | indicates that the client prefers that the server redirect from an insecure
494 | resource representation to a secure one, and that it can successfully handle
495 | the upgrade-insecure-requests directive in order to make
496 | that redirection as seamless as possible.
When a server encounters this preference in an HTTP request’s headers, it
508 | SHOULD redirect the user to a secure version of the resource being requested.
The server parses the preference, notices that the user’s client can deal
535 | well with upgrade requests, and therefore responds to the request by
536 | redirecting the user to a secure version of the resource she’s requesting:
537 |
538 |
539 |
540 |
HTTP/1.1 302 Moved Temporarily
541 | Location: https://example.com/
542 |
4.1.
586 | Upgrade request to a potentially secure URL, if appropriate
587 |
588 |
589 |
590 |
Given a Requestrequest, this algorithm will rewrite its
591 | url if the client from which the request originates
592 | has opted-in to upgrades. It will also inject a
593 | return=secure-representation preference for insecure
594 | navigational requests in order to improve a server’s ability to feature-detect
595 | a client’s upgrade capabilities.
596 |
597 |
598 |
We will not upgrade cross-origin navigational requests, with the exception of
599 | form submissions. Form submissions will be upgraded to mitigate the risk of
600 | data leakage via plaintext submissions.
601 |
602 |
603 |
This should be called from Fetch, probably after the existing step #3.
604 |
605 |
606 |
607 |
608 |
609 | If request’s url is potentially secure:
610 | return without modifying request.
611 |
612 |
613 |
614 |
624 | If request’s context-frame-type is
625 | top-level or auxiliary, then:
626 |
627 |
628 |
629 |
630 |
631 | If request’s context is form,
632 | skip the remaining substeps, and continue upgrading
633 | request.
634 |
635 |
636 |
637 |
638 | If request’s url's host is the same
639 | as request’s client's origin’s host,
640 | skip the remaining substeps, and continue upgrading
641 | request.
642 |
643 |
644 |
Note: We allow only same-origin upgrades in order to ensure that
645 | navigations between pages of a single site that has opted-into
646 | the upgrade behavior remain on HTTPS, regardless of the hard-coded
647 | values in <a> tags. Performing upgrades for navigations to
648 | third-party resources brings a significantly higher potential for
649 | breakage, so we’re avoiding it for the moment.
650 |
651 |
652 |
653 |
This isn’t correct for nested documents. We need to pass the
654 | policy-setting document’s host down to ensure that we’re only
655 | attempting "first-party" upgrades.
656 |
657 |
658 |
659 |
660 |
661 | Return without further modifying request.
662 |
663 |
664 |
665 |
692 | If upgrade state is Monitored Upgrade, return
693 | without modifying request.
694 |
695 |
696 |
697 |
698 | If request’s url's scheme is
699 | http, set request’s url's
700 | scheme to https, and return.
701 |
702 |
703 |
704 |
705 | If request’s urls port is
706 | 80, set request’s urls port
707 | to 443.
708 |
709 |
710 |
Note: This will only change the URL’s port if the port is
711 | explicitly set to 80. If the port is not set, or if
712 | it is set to some non-standard value, the user agent will not
713 | modify that value. This implementation makes the same tradeoffs as
714 | HSTS (see [RFC6797], and specifically step #5 of
715 | Section
716 | 8.3, and item #6 in
717 | Appendix
718 | A).
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
Note: Due to Fetch’s recursive nature, this algorithm will upgrade
727 | insecurely-redirected requests as well as insecure initial requests.
728 |
729 |
730 |
4.2.
731 | Should insecure Requests be upgraded for client?
732 |
Note: This catches requests triggered from detached clients.
767 | Not sure this is necessary, really, given the inheritance structure
768 | defined in §3.3 Policy Inheritance.
769 |
770 |
771 |
772 |
773 |
774 | Return No Upgrade.
775 |
776 |
777 |
778 |
779 |
780 |
781 |
4.3.
782 | Report an upgrade for request
783 |
784 |
785 |
786 |
When a Request is upgraded, a CSP violation is triggered with the intent
787 | of informing authors that resources on their sites will fail to load in
788 | user agents that do not support this upgrade mechanism.
866 | If upgrade state is Monitored Upgrade,
867 | skip the remaining substeps.
868 |
869 |
870 |
871 |
872 | Set secure to true.
873 |
874 |
875 |
876 |
877 | If port is 80, set port to
878 | 443.
879 |
880 |
881 |
Note: This will only change the URL’s port if the port is
882 | explicitly set to 80. If the port is not set, or if
883 | it is set to some non-standard value, the user agent will not
884 | modify that value. This implementation makes the same tradeoffs as
885 | HSTS (see [RFC6797], and specifically step #5 of
886 | Section
887 | 8.3, and item #6 in
888 | Appendix
889 | A).
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
6. Security Considerations
911 |
912 |
913 |
6.1. Interaction with HSTS
914 |
915 |
916 |
The upgrade-insecure-requests directive does not replace
917 | the Strict-Transport-Security HTTP response header [RFC6797].
918 | Authors who serve their site over secure transport SHOULD send that header
919 | with an appropriate max-age in order to ensure that users are
920 | not subject to SSL stripping attacks by maliciously active network attackers.
921 |
922 |
923 |
6.2. CSP Violation Reports
924 |
925 |
926 |
When sending a violation report for an upgraded resource, user agents MUST
927 | target the Document or Worker that triggered the request, rather
928 | than the Document or Worker on which the
929 | upgrade-insecure-requests directive was set. Due to
930 | §3.3 Policy Inheritance, the latter might be a cross-origin ancestor of the former, and
931 | sending violation reports to that set of reporting endpoints could leak data
932 | in unexpected ways.
933 |
934 |
935 |
Likewise, the SecurityPolicyViolationEvent MUST NOT target any
936 | Document other than the one which triggered the request, for the same
937 | reasons.
938 |
939 |
940 |
941 |
942 |
943 |
7. Authoring Considerations
944 |
945 |
946 |
7.1. Legacy Clients
947 |
948 |
949 |
Legacy clients which do support mixed content blocking [MIX], but do not
950 | support the upgrade-insecure-requests directive will
951 | continue to have a suboptimal experience on pages containing
952 | a priori insecure URLs. Authors SHOULD ensure that
953 | they collect violation reports in order
954 | to determine which resources are most problematic for their users, and SHOULD
955 | use that information to prioritize fixes for URLs in legacy content that
956 | users will most likely request.
957 |
958 |
959 |
7.2. Relation to HSTS
960 |
961 |
962 |
The mechanism specified here deals only with the security policy for a
963 | specific protected resource. It does not deprecate, replace, or in any
964 | way reduce the value of the Strict-Transport-Security HTTP
965 | response header [RFC6797]. Authors can and should continue to use that
966 | header to ensure that their users are not subject to SSL stripping downgrade
967 | attacks, as the upgrade-insecure-requests directive will
968 | not ensure that users visiting your site via links on third-party sites will
969 | be upgraded to HTTPS for the top-level navigation.
970 |
971 |
972 |
Likewise, the Strict-Transport-Security header does not imply
973 | the behavior that upgrade-insecure-requests activates.
974 | It only ensures that resources requested from an origin will never hit the
975 | network insecurely.
976 |
977 |
978 |
Therefore, we recommend that authors who wish to ensure that their users have
979 | a secure experience do the following:
980 |
981 |
982 |
983 |
984 |
985 | Redirect incoming traffic from HTTP to HTTPS by serving a
986 | Location header along with a 302 status code.
987 |
988 |
989 |
990 |
991 | Respond to HTTPS requests with a Strict-Transport-Security
992 | header with a reasonable max-age.
993 |
994 |
995 |
996 |
997 | Work with user agent vendors to add their sites to those user agent’s
998 | HSTS Preload Lists (for example, by visiting
999 | hstspreload.appspot.com).
1000 |
1001 |
1002 |
1003 |
1004 | Opt-into either this document’s
1005 | upgrade-insecure-requests mechanism, or into Mixed
1006 | Content’s strict mode in order to ensure that insecure content is
1007 | never loaded.
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
8. IANA Considerations
1018 |
1019 |
1020 |
The "HTTP Preferences" registry should be updated with the following
1021 | alteration to the existing registration for the return
1022 | preference [RFC7240]:
When the value is "minimal", it indicates that the client
1051 | prefers that the server return a minimal response to a request. When the
1052 | value is "representation", it indicates that the client
1053 | prefers that the server include a representation of the current state of
1054 | the resource in response to a request. When the value is
1055 | "secure-representation" it indicates that the client prefers
1056 | to be redirected to a secure version of the resource (and that the client
1057 | supports the upgrade-insecure-requests mechanism).
Anne van Kesteren helped ensure that the initial draft of this document was
1083 | sane. Peter Eckersley and Daniel Kahn Gillmor clarified the problem space, and
1084 | helped point out the impact.
1085 |
1086 |
1087 |
1088 |
1089 |
Conformance
1090 |
1091 |
1092 |
Document conventions
1093 |
1094 |
1095 |
Conformance requirements are expressed with a combination of
1096 | descriptive assertions and RFC 2119 terminology. The key words "MUST",
1097 | "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT",
1098 | "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this
1099 | document are to be interpreted as described in RFC 2119.
1100 | However, for readability, these words do not appear in all uppercase
1101 | letters in this specification.
1102 |
1103 |
1104 |
All of the text of this specification is normative except sections
1105 | explicitly marked as non-normative, examples, and notes. [RFC2119]
1106 |
1107 |
1108 |
Examples in this specification are introduced with the words "for example"
1109 | or are set apart from the normative text with class="example",
1110 | like this:
1111 |
1112 |
1113 |
1114 |
1115 |
This is an example of an informative example.
1116 |
1117 |
1118 |
1119 |
1120 |
1121 |
Informative notes begin with the word "Note" and are set apart from the
1122 | normative text with class="note", like this:
1123 |
1124 |
1125 |
Note, this is an informative note.
1126 |
1127 |
1128 |
Conformant Algorithms
1129 |
1130 |
1131 |
Requirements phrased in the imperative as part of algorithms (such as
1132 | "strip any leading space characters" or "return false and abort these
1133 | steps") are to be interpreted with the meaning of the key word ("must",
1134 | "should", "may", etc) used in introducing the algorithm.
1135 |
1136 |
1137 |
Conformance requirements phrased as algorithms or specific steps can be
1138 | implemented in any manner, so long as the end result is equivalent. In
1139 | particular, the algorithms defined in this specification are intended to
1140 | be easy to understand and are not intended to be performant. Implementers
1141 | are encouraged to optimize.
1142 |
1143 |
1144 |
Conformance Classes
1145 |
1146 |
1147 |
A conformant user agent must implement all the requirements
1148 | listed in this specification that are applicable to user agents.
1149 |
1150 |
1151 |
A conformant server must implement all the requirements listed
1152 | in this specification that are applicable to servers.
In a thread on public-webappsec@,
1274 | Peter Eckersley suggested modifying this to allow whitelisting specific hosts,
1275 | rather than upgrading everything: "That way, if you have N third parties
1276 | on a site, and (say) two of them provide images only, and don’t support
1277 | HTTPS at all, you can use the upgrade mechanism for scripts on the other
1278 | N - 2 origins." ↵
1279 |
This should be called from Fetch, probably after the existing step #3. ↵
1280 |
This isn’t correct for nested documents. We need to pass the
1281 | policy-setting document’s host down to ensure that we’re only
1282 | attempting "first-party" upgrades. ↵