@@ -37,6 +37,9 @@ urlPrefix:https://w3c.github.io/hr-time/#;spec:hr-time
37
37
urlPrefix:https://tc39.es/ecma262/#;type:dfn;spec:ecma-262
38
38
url:realm;text:realm
39
39
url:sec-list-and-record-specification-type;text:Record
40
+ url:sec-parsetext;text:ParseText
41
+ url:prod-Script;text:Script
42
+ url:script-record;text:Script Record
40
43
</pre>
41
44
42
45
<pre class=biblio>
@@ -1970,6 +1973,17 @@ Unless stated otherwise, it is false.
1970
1973
1971
1974
<p class=note> This flag is for exclusive use by HTML's render-blocking mechanism. [[!HTML]]
1972
1975
1976
+ <p class=XXX> A <a for=/>request</a> has an associated
1977
+ <dfn export for=request>no-cors media request state</dfn> ...
1978
+
1979
+ <p class=note> This is for exclusive use by the <a>opaque-response-safelist check</a> .
1980
+
1981
+ <p> A <a for=/>request</a> has an associated
1982
+ <dfn for=request>no-cors JavaScript fallback encoding</dfn> (an <a for=/>encoding</a> ). Unless
1983
+ stated otherwise, it is <a for=/>UTF-8</a> .
1984
+
1985
+ <p class=note> This is for exclusive use by the <a>opaque-response-safelist check</a> .
1986
+
1973
1987
<hr>
1974
1988
1975
1989
<p> A <a for=/>request</a> has an associated
@@ -3042,6 +3056,285 @@ run these steps:
3042
3056
</ol>
3043
3057
3044
3058
3059
+ <h3 id=orb>Opaque-response blocking</h3>
3060
+
3061
+ <div class=note>
3062
+ <p> Opaque-response blocking, also known as <abbr> ORB</abbr> , is a network filter that blocks access
3063
+ to <a>opaque filtered responses</a> . These responses would likely would not have been useful to the
3064
+ fetching party. Blocking them reduces information leakage to potential attackers.
3065
+
3066
+ <p> Essentially, CSS, JavaScript, images, and media (audio and video) can be requested across
3067
+ origins without the <a>CORS protocol</a> . And unfortunately except for CSS there is no MIME type
3068
+ enforcement. This algorithm aims to block as many responses as possible that are not one of these
3069
+ types (or are newer variants of those types) to avoid leaking their contents through side channels.
3070
+
3071
+ <p> The network filter combines pro-active blocking based on response headers, sniffing a limited
3072
+ set of bytes, and ultimately falls back to a full parse due to unfortunate (lack of) design
3073
+ decisions in the early days of the web platform. As a result there are still quite a few responses
3074
+ whose secrets can end up being revealed to attackers. Web developers are strongly encouraged to use
3075
+ the `<code http-header> Cross-Origin-Resource-Policy</code> ` response header to defend them.
3076
+ </div>
3077
+
3078
+
3079
+ <h4 id=orb-algorithm>The opaque-response-safelist check</h4>
3080
+
3081
+ <p> The <dfn>opaque-response-safelist check</dfn> , given a <a for=/>request</a> <var> request</var>
3082
+ and a <a for=/>response</a> <var> response</var> , is to run these steps:
3083
+
3084
+ <ol>
3085
+ <li><p> Let <var> mimeType</var> be the result of <a>extracting a MIME type</a> from
3086
+ <var> response</var> 's <a for=response>header list</a> .
3087
+
3088
+ <li><p> Let <var> nosniff</var> be the result of <a>determining nosniff</a> given
3089
+ <var> response</var> 's <a for=response>header list</a> .
3090
+
3091
+ <li>
3092
+ <p> If <var> mimeType</var> is not failure, then:
3093
+
3094
+ <ol>
3095
+ <li><p> If <var> mimeType</var> is an <a>opaque-response-safelisted MIME type</a> , then return
3096
+ true.
3097
+
3098
+ <li><p> If <var> mimeType</var> is an <a>opaque-response-blocklisted-never-sniffed MIME type</a> ,
3099
+ then return false.
3100
+
3101
+ <li><p> If <var> response</var> 's <a for=response>status</a> is 206 and <var> mimeType</var> is an
3102
+ <a>opaque-response-blocklisted MIME type</a> , then return false.
3103
+
3104
+ <li><p> If <var> nosniff</var> is true and <var> mimeType</var> is an
3105
+ <a>opaque-response-blocklisted MIME type</a> or its <a for="MIME type">essence</a> is
3106
+ "<code> text/plain</code> ", then return false.
3107
+ </ol>
3108
+
3109
+ <li><p> If <var> request</var> 's <a for=request>no-cors media request state</a> is
3110
+ "<code> subsequent</code> ", then return true.
3111
+
3112
+ <li><p> If <var> response</var> 's <a for=response>status</a> is 206 and
3113
+ <a>validate a partial response</a> given 0 and <var> response</var> returns invalid, then return
3114
+ false.
3115
+ <!-- TODO Integrate https://wicg.github.io/background-fetch/#validate-a-partial-response into Fetch -->
3116
+
3117
+ <li><p> Let <var> bytes</var> be the result of running
3118
+ <a>obtain a copy of the first 1024 bytes of response</a> given <var> response</var> .
3119
+
3120
+ <li><p> If <var> bytes</var> is failure, then return false.
3121
+
3122
+ <li>
3123
+ <p> If the <a>audio or video type pattern matching algorithm</a> given <var> bytes</var> does not
3124
+ return undefined, then:
3125
+
3126
+ <ol>
3127
+ <li><p> If <var> requests</var> 's <a for=request>no-cors media request state</a> is not
3128
+ "<code> initial</code> ", then return false.
3129
+
3130
+ <li><p> If <var> response</var> 's <a for=response>status</a> is not 200 or 206, then return false.
3131
+
3132
+ <li><p> Return true.
3133
+ </ol>
3134
+
3135
+ <li><p> If <var> requests</var> 's <a for=request>no-cors media request state</a> is not
3136
+ "<code> N/A</code> ", then return false.
3137
+
3138
+ <li><p> If the <a>image type pattern matching algorithm</a> given <var> bytes</var> does not return
3139
+ undefined, then return true.
3140
+
3141
+ <li>
3142
+ <p> If <var> nosniff</var> is true, then return false.
3143
+
3144
+ <p class=note> This check is made late as unfortunately images and media are always sniffed.
3145
+
3146
+ <li><p> If <var> response</var> 's <a for=response>status</a> is not an <a>ok status</a> , then return
3147
+ false.
3148
+
3149
+ <li>
3150
+ <p> If <var> mimeType</var> is failure, then return true.
3151
+
3152
+ <p class=note> This could be improved at somewhat significant cost. See
3153
+ <a href=https://github.com/annevk/orb/issues/28>annevk/orb #28</a> .
3154
+
3155
+ <li><p> If <var> mimeType</var> 's <a for="MIME type">essence</a> <a for=string>starts with</a>
3156
+ "<code> audio/</code> ", "<code> image/</code> ", or "<code> video/</code> ", then return false.
3157
+
3158
+ <li><p> Return <a>determine if response is JavaScript and not JSON</a> given <var> response</var> .
3159
+ </ol>
3160
+
3161
+ <hr>
3162
+
3163
+ <p> To <dfn>obtain a copy of the first 1024 bytes of response</dfn> , given a <a for=/>response</a>
3164
+ <var> response</var> , run these steps:
3165
+
3166
+ <ol>
3167
+ <li><p> Let <var> first1024Bytes</var> be null.
3168
+
3169
+ <li>
3170
+ <p> <a for=/>In parallel</a> :
3171
+
3172
+ <ol>
3173
+ <li><p> Let <var> bytes</var> be the empty <a for=/>byte sequence</a> .
3174
+
3175
+ <li><p> Let <var> transformStream</var> be a new {{TransformStream}} .
3176
+
3177
+ <li>
3178
+ <p> Let <var> transformAlgorithm</var> given a <var> chunk</var> be these steps:
3179
+
3180
+ <ol>
3181
+ <li><p> <a for=ReadableStream>Enqueue</a> <var> chunk</var> in <var> transformStream</var> .
3182
+
3183
+ <li>
3184
+ <p> If <var> first1024Bytes</var> is null, then:
3185
+
3186
+ <ol>
3187
+ <li><p> Let <var> chunkBytes</var> be
3188
+ <a lt="get a copy of the bytes held by the buffer source">a copy of the bytes held by</a>
3189
+ <var> chunk</var> .
3190
+
3191
+ <li><p> Append <var> chunkBytes</var> to <var> bytes</var> .
3192
+
3193
+ <li>
3194
+ <p> If <var> bytes</var> 's <a for="byte sequencue">length</a> is greater than 1024, then:
3195
+
3196
+ <ol>
3197
+ <li><p> Truncate <var> bytes</var> from the end so that it only contains 1024 bytes.
3198
+
3199
+ <li><p> Set <var> first1024Bytes</var> to <var> bytes</var> .
3200
+ </ol>
3201
+ </ol>
3202
+ </ol>
3203
+
3204
+ <li><p> Let <var> flushAlgorithm</var> be this step: if <var> first1024Bytes</var> is null, then set
3205
+ <var> first1024Bytes</var> to <var> bytes</var> .
3206
+
3207
+ <li><p> <a for=TransformStream>Set up</a> <var> transformStream</var> with
3208
+ <a for="TransformStream/set up"><i>transformAlgorithm</i></a> set to
3209
+ <var> transformAlgorithm</var> and <a for="TransformStream/set up"><i>flushAlgorithm</i></a> set
3210
+ to <var> flushAlgorithm</var> .
3211
+
3212
+ <li><p> Set <var> response</var> 's <a for=response>body</a>' s <a for=body>stream</a> to the result
3213
+ of <var> response</var> 's <a for=response>body</a>' s <a for=body>stream</a>
3214
+ <a for=TransformStream>piped through</a> <var> transformStream</var> .
3215
+ </ol>
3216
+
3217
+ <li><p> Wait until <var> first1024Bytes</var> is non-null or <var> response</var> 's
3218
+ <a for=response>body</a> 's <a for=body>stream</a> is <a for=ReadableStream>errored</a> .
3219
+
3220
+ <li><p> If <var> first1024Bytes</var> is null, then return failure.
3221
+
3222
+ <li> Return <var> first1024Bytes</var> .
3223
+ </ol>
3224
+
3225
+ <hr>
3226
+
3227
+ <p> To <dfn>determine if response is JavaScript and not JSON</dfn> given a <a for=/>response</a>
3228
+ <var> response</var> , run these steps:</p>
3229
+
3230
+ <ol>
3231
+ <li><p> Let <var> responseBodyBytes</var> be null.
3232
+
3233
+ <li>
3234
+ <p> Let <var> processBody</var> given a <a for=/>byte sequence</a> <var> bytes</var> be these steps:
3235
+
3236
+ <ol>
3237
+ <li><p> Set <var> responseBodyBytes</var> to <var> bytes</var> .
3238
+
3239
+ <li><p> Set <var> response</var> 's <a for=response>body</a> to the <a for="body with type">body</a>
3240
+ of the result of <a for=BodyInit>safely extracting</a> <var> bytes</var> .
3241
+ </ol>
3242
+
3243
+ <li><p> Let <var> processBodyError</var> be this step: set <var> responseBodyBytes</var> to failure.
3244
+
3245
+ <li><p> <a>Fully read</a> <var> response</var> 's <a for=response>body</a> given <a>processBody</a>
3246
+ and <var> processBodyError</var> .
3247
+
3248
+ <li><p> Wait for <var> responseBodyBytes</var> to be non-null.
3249
+
3250
+ <li><p> If <var> responseBodyBytes</var> is failure, then return false.
3251
+
3252
+ <li><p> <a for=/>Assert</a> : <var> responseBodyBytes</var> is a <a for=/>byte sequence</a> .
3253
+
3254
+ <li>
3255
+ <p> If <a>parse JSON bytes to a JavaScript value</a> given <var> responseBodyBytes</var> does not
3256
+ throw, then return false. If it throws, catch the exception and ignore it.
3257
+
3258
+ <p class=note> If there is an exception, <var> response</var> is not JSON. If there is not, it is.
3259
+
3260
+ <li><p> Let <var> potentialMIMETypeForEncoding</var> be the result of <a>extracting a MIME type</a>
3261
+ given <var> response</var> 's <a for=response>header list</a> .
3262
+
3263
+ <li>
3264
+ <p> Let <var> encoding</var> be the result of <a>legacy extracting an encoding</a> given
3265
+ <var> potentialMIMETypeForEncoding</var> and <var> request</var> 's
3266
+ <a for=request>no-cors JavaScript fallback encoding</a> .
3267
+
3268
+ <p class=note> Equivalently to <a>fetch a classic script</a> , this ignores the
3269
+ <a for="MIME type" lt=essence>MIME type essence</a> .
3270
+
3271
+ <li><p> Let <var> sourceText</var> be the result of <a for=/>decoding</a>
3272
+ <var> responseBodyBytes</var> given <var> encoding</var> .
3273
+
3274
+ <li><p> If <a>ParseText</a> (<var> sourceText</var> , <a>Script</a> ) returns a <a>Script Record</a> ,
3275
+ then return true.
3276
+ <!-- Ideally HTML owns this so ECMAScript changes don't end up impacting Fetch. We could
3277
+ potentially make this use "create a classic script" instead with some mock data. Maybe that is
3278
+ better? -->
3279
+
3280
+ <li><p> Return false.
3281
+ </ol>
3282
+
3283
+
3284
+ <h4 id=orb-mime-type-sets>New MIME type sets</h4>
3285
+
3286
+ <p class=note> The definitions in this section are solely for the purpose of abstracting parts of the
3287
+ <a>opaque-response-safelist check</a> . They are not suited for usage elsewhere.
3288
+
3289
+ <p> An <dfn>opaque-response-safelisted MIME type</dfn> is a <a>JavaScript MIME type</a> or a
3290
+ <a for=/>MIME type</a> whose <a for="MIME type">essence</a> is "<code> text/css</code> " or
3291
+ "<code> image/svg+xml</code> ".
3292
+
3293
+ <p> An <dfn>opaque-response-blocklisted MIME type</dfn> is an <a>HTML MIME type</a> ,
3294
+ <a>JSON MIME type</a> , or <a>XML MIME type</a> .
3295
+
3296
+ <p> An <dfn>opaque-response-blocklisted-never-sniffed MIME type</dfn> is a <a for=/>MIME type</a>
3297
+ whose <a for="MIME type">essence</a> is one of:
3298
+
3299
+ <ul class=brief>
3300
+ <li> "<code> application/gzip</code> "
3301
+ <li> "<code> application/msexcel</code> "
3302
+ <li> "<code> application/mspowerpoint</code> "
3303
+ <li> "<code> application/msword</code> "
3304
+ <li> "<code> application/msword-template</code> "
3305
+ <li> "<code> application/pdf</code> "
3306
+ <li> "<code> application/vnd.ces-quickpoint</code> "
3307
+ <li> "<code> application/vnd.ces-quicksheet</code> "
3308
+ <li> "<code> application/vnd.ces-quickword</code> "
3309
+ <li> "<code> application/vnd.ms-excel</code> "
3310
+ <li> "<code> application/vnd.ms-excel.sheet.macroenabled.12</code> "
3311
+ <li> "<code> application/vnd.ms-powerpoint</code> "
3312
+ <li> "<code> application/vnd.ms-powerpoint.presentation.macroenabled.12</code> "
3313
+ <li> "<code> application/vnd.ms-word</code> "
3314
+ <li> "<code> application/vnd.ms-word.document.12</code> "
3315
+ <li> "<code> application/vnd.ms-word.document.macroenabled.12</code> "
3316
+ <li> "<code> application/vnd.msword</code> "
3317
+ <li> "<code> application/vnd.openxmlformats-officedocument.presentationml.presentation</code> "
3318
+ <li> "<code> application/vnd.openxmlformats-officedocument.presentationml.template</code> "
3319
+ <li> "<code> application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</code> "
3320
+ <li> "<code> application/vnd.openxmlformats-officedocument.spreadsheetml.template</code> "
3321
+ <li> "<code> application/vnd.openxmlformats-officedocument.wordprocessingml.document</code> "
3322
+ <li> "<code> application/vnd.openxmlformats-officedocument.wordprocessingml.template</code> "
3323
+ <li> "<code> application/vnd.presentation-openxml</code> "
3324
+ <li> "<code> application/vnd.presentation-openxmlm</code> "
3325
+ <li> "<code> application/vnd.spreadsheet-openxml</code> "
3326
+ <li> "<code> application/vnd.wordprocessing-openxml</code> "
3327
+ <li> "<code> application/x-gzip</code> "
3328
+ <li> "<code> application/x-protobuf</code> "
3329
+ <li> "<code> application/x-protobuffer</code> "
3330
+ <li> "<code> application/zip</code> "
3331
+ <li> "<code> multipart/byteranges</code> "
3332
+ <li> "<code> multipart/signed</code> "
3333
+ <li> "<code> text/event-stream</code> "
3334
+ <li> "<code> text/csv</code> "
3335
+ </ul>
3336
+
3337
+
3045
3338
3046
3339
<h2 id=http-extensions>HTTP extensions</h2>
3047
3340
@@ -4846,19 +5139,23 @@ these steps:
4846
5139
<li><p> Set <var> response</var> and <var> actualResponse</var> to the result of running
4847
5140
<a>HTTP-network-or-cache fetch</a> given <var> fetchParams</var> .
4848
5141
4849
- <li>
4850
- <p> If < var>request </var> 's <a for=request> response tainting </a> is " <code> cors </code> " and a
4851
- <a>CORS check</a> for <var> request</var> and <var> response</var> returns failure, then return a
4852
- <a>network error</a> .
5142
+ <li><p> If <var> request </var> 's <a for=request>response tainting</a> is " <code> opaque </code> ",
5143
+ < var>response </var> 's <a for=response>status </a> is not a <a>redirect status</a> , and the
5144
+ <a>opaque-response-safelist check</a> given <var> request</var> and <var> response</var> returns
5145
+ false, then return a <a>network error</a> .
4853
5146
4854
- <p class="note no-backref"> As the <a>CORS check </a> is not to be applied to
4855
- <a for=/>responses </a> whose <a for=response>status</a> is 304 or 407, or <a for=/>responses</a>
4856
- from a service worker for that matter, it is applied here .
5147
+ <li><p> If <var> request </var> 's <a for=request>response tainting </a> is " <code> cors </code> " and
5148
+ the <a>CORS check </a> for <var> request </var> and <var> response </var> returns failure, then return
5149
+ a <a>network error</a> .
4857
5150
4858
5151
<li><p> If the <a>TAO check</a> for <var> request</var> and <var> response</var> returns failure,
4859
5152
then set <var> request</var> 's <a for=request>timing allow failed flag</a> .
4860
5153
</ol>
4861
5154
5155
+ <p class=note> As the <a>opaque-response-safelist check</a> , <a>CORS check</a> , and
5156
+ <a>TAO check</a> are not to be applied to <a for=/>responses</a> whose <a for=response>status</a>
5157
+ is 304 or 407, or to <a for=/>responses</a> from a service worker, they are applied here.
5158
+
4862
5159
<li>
4863
5160
<p> If either <var> request</var> 's <a for=request>response tainting</a> or <var>response</var>' s
4864
5161
<a for=response>type</a> is "<code> opaque</code> ", and the
@@ -8421,6 +8718,7 @@ Mohamed Zergaoui,
8421
8718
Mohammed Zubair Ahmed<!-- M-ZubairAhmed; GitHub -->,
8422
8719
Moritz Kneilmann,
8423
8720
Ms2ger,
8721
+ Nathan Froyd,
8424
8722
Nico Schlömer,
8425
8723
Nicolás Peña Moreno,
8426
8724
Nidhi Jaju,
0 commit comments