|
1
|
# The Default Content Security Policy (CSP) |
|
2
|
|
|
3
|
When Fossil’s web interface generates an HTML page, it normally includes |
|
4
|
a [Content Security Policy][csp] (CSP) in the `<head>`. The CSP specifies |
|
5
|
allowed sources for external resources such as images, |
|
6
|
CSS, javascript, and so forth. |
|
7
|
The purpose of CSP is to provide an extra layer of protection against |
|
8
|
[cross-site scripting][xss] (XSS) and code injection |
|
9
|
attacks. Compatible web browsers will not use external resources unless |
|
10
|
they are specifically allowed by the CSP, which dramatically reduces |
|
11
|
the attack surface of the application. |
|
12
|
|
|
13
|
Fossil does not rely on CSP for security. |
|
14
|
A Fossil server should be secure from attack even without CSP. |
|
15
|
Fossil includes built-in server-side content filtering logic. |
|
16
|
For example, Fossil purposely breaks `<script>` tags when it finds |
|
17
|
them in Markdown and Fossil Wiki documents. And the Fossil build |
|
18
|
process scans the source code for potential injection vulnerabilities |
|
19
|
and refuses to compile if any problems are found. |
|
20
|
However, CSP provides an additional layer of defense against undetected |
|
21
|
bugs that might lead to a vulnerability. |
|
22
|
|
|
23
|
## The Default Restrictions |
|
24
|
|
|
25
|
The default CSP used by Fossil is as follows: |
|
26
|
|
|
27
|
<pre> |
|
28
|
default-src 'self' data:; |
|
29
|
script-src 'self' 'nonce-$nonce'; |
|
30
|
style-src 'self' 'unsafe-inline'; |
|
31
|
img-src * data:; |
|
32
|
</pre> |
|
33
|
|
|
34
|
The default is recommended for most installations. However, |
|
35
|
the site administrators can overwrite this default CSP using the |
|
36
|
[default-csp setting](/help/default-csp). For example, |
|
37
|
CSP restrictions can be completely disabled by setting the default-csp to: |
|
38
|
|
|
39
|
default-src *; |
|
40
|
|
|
41
|
The following sections detail the maining of the default CSP setting. |
|
42
|
|
|
43
|
### <a id="base"></a> default-src 'self' data: |
|
44
|
|
|
45
|
This policy means mixed-origin content isn’t allowed, so you can’t refer |
|
46
|
to resources on other web domains. Browsers will ignore a link like the |
|
47
|
one in the following Markdown under our default CSP: |
|
48
|
|
|
49
|
 |
|
50
|
|
|
51
|
If you look in the browser’s developer console, you should see a CSP |
|
52
|
error when attempting to render such a page. |
|
53
|
|
|
54
|
The default policy does allow inline `data:` URIs, which means you could |
|
55
|
[data-encode][de] your image content and put it inline within the |
|
56
|
document: |
|
57
|
|
|
58
|
 |
|
59
|
|
|
60
|
That method is best used for fairly small resources. Large `data:` URIs |
|
61
|
are hard to read and edit. There are secondary problems as well: if you |
|
62
|
put a large image into a Fossil forum post this way, anyone subscribed |
|
63
|
to email alerts will get a copy of the raw URI text, which can amount to |
|
64
|
pages and pages of [ugly Base64-encoded text][b64]. |
|
65
|
|
|
66
|
For inline images within [embedded documentation][ed], it suffices to |
|
67
|
store the referred-to files in the repo and then refer to them using |
|
68
|
repo-relative URLs: |
|
69
|
|
|
70
|
 |
|
71
|
|
|
72
|
This avoids bloating the doc text with `data:` URI blobs: |
|
73
|
|
|
74
|
There are many other cases, [covered below](#serving). |
|
75
|
|
|
76
|
[b64]: https://en.wikipedia.org/wiki/Base64 |
|
77
|
[svr]: ./server/ |
|
78
|
|
|
79
|
|
|
80
|
### <a id="img"></a> img-src * data: |
|
81
|
|
|
82
|
It was not always thus, but after careful consideration, we’ve chosen to |
|
83
|
leave the source of inline images unrestricted by default in Fossil. |
|
84
|
This allows you to pull them in from remote systems, to pull them from |
|
85
|
within the Fossil repository itself, or to use `data:` URIs. |
|
86
|
|
|
87
|
If you are certain all images come from only within the repository, you |
|
88
|
can close off certain risks — tracking pixels, broken image format |
|
89
|
decoders, system dialog box spoofing, etc. — by changing this to |
|
90
|
“`img-src 'self'`” possibly followed by “`data:`” if you will also use |
|
91
|
`data:` URIs. |
|
92
|
|
|
93
|
|
|
94
|
### <a id="style"></a> style-src 'self' 'unsafe-inline' |
|
95
|
|
|
96
|
This policy allows CSS information to come from separate files hosted |
|
97
|
under the Fossil repo server’s Internet domain. It also allows inline CSS |
|
98
|
`<style>` tags within the document text. |
|
99
|
|
|
100
|
The `'unsafe-inline'` declaration allows CSS within individual HTML |
|
101
|
elements: |
|
102
|
|
|
103
|
<p style="margin-left: 4em">Indented text.</p> |
|
104
|
|
|
105
|
As the "`unsafe-`" prefix on the name implies, the `'unsafe-inline'` |
|
106
|
feature is suboptimal for security. However, there are |
|
107
|
a few places in the Fossil-generated HTML that benefit from this |
|
108
|
flexibility and the work-arounds are verbose and difficult to maintain. |
|
109
|
Furthermore, the harm that can be done with style injections is far |
|
110
|
less than the harm possible with injected javascript. And so the |
|
111
|
`'unsafe-inline'` compromise is accepted for now, though it might |
|
112
|
go away in some future release of Fossil. |
|
113
|
|
|
114
|
|
|
115
|
### <a id="script"></a> script-src 'self' 'nonce-%s' |
|
116
|
|
|
117
|
This policy disables in-line JavaScript and only allows `<script>` |
|
118
|
elements if the `<script>` includes a `nonce` attribute that matches the |
|
119
|
one declared by the CSP. That nonce is a large random number, unique for |
|
120
|
each HTTP page generated by Fossil, so an attacker cannot guess the |
|
121
|
value, so the browser will ignore an attacker’s injected JavaScript. |
|
122
|
|
|
123
|
That nonce can only come from one of three sources, all of which should |
|
124
|
be protected at the system administration level on the Fossil server: |
|
125
|
|
|
126
|
* **Fossil server C code:** All code paths in Fossil that emit |
|
127
|
`<script>` elements include the `nonce` attribute. There are several |
|
128
|
cases, such as the “JavaScript” section of a [custom skin][cs]. |
|
129
|
That text is currently inserted into each HTML page generated by |
|
130
|
Fossil,¹ which means it needs to include a `nonce` attribute to |
|
131
|
allow it to run under this default CSP. We consider JavaScript |
|
132
|
emitted via these paths to be safe because it’s audited by the |
|
133
|
Fossil developers. We assume that you got your Fossil server’s code |
|
134
|
from a trustworthy source and that an attacker cannot replace your |
|
135
|
Fossil server binary. |
|
136
|
|
|
137
|
* **TH1 code:** The Fossil TH1 interpreter pre-defines the |
|
138
|
[`$nonce` variable](./th1.md#nonce) for use in [custom skins][cs]. For |
|
139
|
example, some of the stock skins that ship with Fossil include a |
|
140
|
wall clock feature up in the corner that updates once a minute. |
|
141
|
These paths are safe in the default Fossil configuration because |
|
142
|
only the [all-powerful Setup user][su] can write TH1 code that |
|
143
|
executes in the server’s running context. |
|
144
|
|
|
145
|
There is, however, [a default-disabled path](#xss) to beware of, |
|
146
|
covered in the next section. |
|
147
|
|
|
148
|
* **[CGI server extensions][ext]:** Fossil exports the nonce to the |
|
149
|
CGI in the `FOSSIL_NONCE` environment variable, which it can then |
|
150
|
use in `<script>` elements it generates. Because these extensions |
|
151
|
can only be installed by the Fossil server’s system administrator, |
|
152
|
this path is also considered safe. |
|
153
|
|
|
154
|
[ext]: ./serverext.wiki |
|
155
|
[su]: ./caps/admin-v-setup.md#apsu |
|
156
|
|
|
157
|
|
|
158
|
#### <a id="xss"></a>Cross-Site Scripting via Ordinary User Capabilities |
|
159
|
|
|
160
|
We’re so restrictive about how we treat JavaScript because it can lead |
|
161
|
to difficult-to-avoid scripting attacks. If we used the same CSP for |
|
162
|
`<script>` tags [as for `<style>` tags](#style), anyone with check-in |
|
163
|
rights on your repository could add a JavaScript file to your repository |
|
164
|
and then refer to it from other content added to the site. Since |
|
165
|
JavaScript code can access any data from any URI served under its same |
|
166
|
Internet domain, and many Fossil users host multiple Fossil repositories |
|
167
|
under a single Internet domain, such a CSP would only be safe if all of |
|
168
|
those repositories are trusted equally. |
|
169
|
|
|
170
|
Consider [the Chisel hosting service](http://chiselapp.com/), which |
|
171
|
offers free Fossil repository hosting to anyone on the Internet, all |
|
172
|
served under the same `http://chiselapp.com/user/$NAME/$REPO` URL |
|
173
|
scheme. Any one of those hundreds of repositories could trick you into |
|
174
|
visiting their repository home page, set to [an HTML-formatted embedded |
|
175
|
doc page][hfed] via Admin → Configuration → Index Page, with this |
|
176
|
content: |
|
177
|
|
|
178
|
<script src="/doc/trunk/bad.js"></script> |
|
179
|
|
|
180
|
That script can then do anything allowed in JavaScript to *any other* |
|
181
|
Chisel repository your browser can access. The possibilities for mischief |
|
182
|
are *vast*. For just one example, if you have login cookies on four |
|
183
|
different Chisel repositories, your attacker could harvest the login |
|
184
|
cookies for all of them through this path if we allowed Fossil to serve |
|
185
|
JavaScript files under the same CSP policy as we do for CSS files. |
|
186
|
|
|
187
|
This is why the default configuration of Fossil has no way for [embedded |
|
188
|
docs][ed], [wiki articles][wiki], [tickets][tkt], [forum posts][fp], or |
|
189
|
[tech notes][tn] to automatically insert a nonce into the page content. |
|
190
|
This is all user-provided content, which could link to user-provided |
|
191
|
JavaScript via check-in rights, effectively giving all such users a |
|
192
|
capability that is usually reserved to the repository’s administrator. |
|
193
|
|
|
194
|
The default-disabled [TH1 documents feature][edtf] is the only known |
|
195
|
path around this restriction. If you are serving a Fossil repository |
|
196
|
that has any user you do not implicitly trust to a level that you would |
|
197
|
willingly run any JavaScript code they’ve provided, blind, you **must |
|
198
|
not** give the `--with-th1-docs` option when configuring Fossil, because |
|
199
|
that allows substitution of the [pre-defined `$nonce` TH1 |
|
200
|
variable](./th1.md#nonce) into [HTML-formatted embedded docs][hfed]: |
|
201
|
|
|
202
|
<script src="/doc/trunk/bad.js" nonce="$nonce"></script> |
|
203
|
|
|
204
|
Even with this feature enabled, you cannot put `<script>` tags into |
|
205
|
Fossil Wiki or Markdown-formatted content, because our HTML generators |
|
206
|
for those formats purposely strip or disable such tags in the output. |
|
207
|
Therefore, if you trust those users with check-in rights to provide |
|
208
|
JavaScript but not those allowed to file tickets, append to wiki |
|
209
|
articles, etc., you might justify enabling TH1 docs on your repository, |
|
210
|
since the only way to create or modify HTML-formatted embedded docs is |
|
211
|
through check-ins. |
|
212
|
|
|
213
|
[ed]: ./embeddeddoc.wiki |
|
214
|
[edtf]: ./embeddeddoc.wiki#th1 |
|
215
|
[hfed]: ./embeddeddoc.wiki#html |
|
216
|
|
|
217
|
|
|
218
|
## <a id="serving"></a>Serving Files Within the Limits |
|
219
|
|
|
220
|
There are several ways to serve files within the above restrictions, |
|
221
|
avoiding the need to [override the default CSP](#override). In |
|
222
|
decreasing order of simplicity and preference: |
|
223
|
|
|
224
|
1. Within [embedded documentation][ed] (only!) you can refer to files |
|
225
|
stored in the repo using document-relative file URLs: |
|
226
|
|
|
227
|
 |
|
228
|
|
|
229
|
2. Relative file URLs don’t work from [wiki articles][wiki], |
|
230
|
[tickets][tkt], [forum posts][fp], or [tech notes][tn], but you can |
|
231
|
still refer to them inside the repo with [`/doc`][du] or |
|
232
|
[`/raw`][ru] URLs: |
|
233
|
|
|
234
|
 |
|
235
|
<img src="/raw/logo.png" style="float: right; margin-left: 2em"> |
|
236
|
|
|
237
|
3. Store the files as [unversioned content][uv], referred to using |
|
238
|
[`/uv`][uu] URLs instead: |
|
239
|
|
|
240
|
 |
|
241
|
|
|
242
|
4. Use the [optional CGI server extensions feature](./serverext.wiki) |
|
243
|
to serve such content via `/ext` URLs. |
|
244
|
|
|
245
|
5. Put Fossil behind a [front-end proxy server][svr] as a virtual |
|
246
|
subdirectory within the site, so that our default CSP’s “self” rules |
|
247
|
match static file routes on that same site. For instance, your repo |
|
248
|
might be at `https://example.com/code`, allowing documents in that |
|
249
|
repo to refer to: |
|
250
|
|
|
251
|
* images as `/image/foo.png` |
|
252
|
* JavaScript files as `/js/bar.js` |
|
253
|
* CSS style sheets as `/style/qux.css` |
|
254
|
|
|
255
|
Although those files are all outside the Fossil repo at `/code`, |
|
256
|
keep in mind that it is the browser’s notion of “self” that matters |
|
257
|
here, not Fossil’s. All resources come from the same Internet |
|
258
|
domain, so the browser cannot distinguish Fossil-provided content |
|
259
|
from static content served directly by the proxy server. |
|
260
|
|
|
261
|
This method opens up many other potential benefits, such as |
|
262
|
[TLS encryption][tls], high-performance tuning via custom HTTP |
|
263
|
headers, integration with other web technologies like PHP, etc. |
|
264
|
|
|
265
|
You might wonder why we rank in-repo content as most preferred above. It |
|
266
|
is because the first two options are the only ones that cause such |
|
267
|
resources to be included in an initial clone or in subsequent repo |
|
268
|
syncs. The methods further down the list have a number of undesirable |
|
269
|
properties: |
|
270
|
|
|
271
|
1. Relative links to out-of-repo files break in `fossil ui` when run on |
|
272
|
a clone. |
|
273
|
|
|
274
|
2. Absolute links back to the public repo instance solve that: |
|
275
|
|
|
276
|
 |
|
277
|
|
|
278
|
...but using them breaks some types of failover and load-balancing |
|
279
|
schemes, because it creates a [single point of failure][spof]. |
|
280
|
|
|
281
|
3. Absolute links fail when one’s purpose in using a clone is to |
|
282
|
recover from the loss of a project web site by standing that clone |
|
283
|
up [as a server][svr] elsewhere. You probably forgot to copy such |
|
284
|
external resources in the backup copies, so that when the main repo |
|
285
|
site disappears, so do those files. |
|
286
|
|
|
287
|
Unversioned content is in the middle of the first list above — between |
|
288
|
fully-external content and fully in-repo content — because it isn’t |
|
289
|
included in a clone unless you give the `--unversioned` flag. If you |
|
290
|
then want updates to the unversioned content to be included in syncs, |
|
291
|
you have to give the same flag to [a `sync` command](/help/sync). |
|
292
|
There is no equivalent with other commands such as `up` and `pull`, so |
|
293
|
you must then remember to give `fossil uv` commands when necessary to |
|
294
|
pull new unversioned content down. |
|
295
|
|
|
296
|
Thus our recommendation that you refer to in-repo resources exclusively. |
|
297
|
|
|
298
|
[du]: /help/www/doc |
|
299
|
[fp]: ./forum.wiki |
|
300
|
[ru]: /help/www/raw |
|
301
|
[spof]: https://en.wikipedia.org/wiki/Single_point_of_failure |
|
302
|
[tkt]: ./tickets.wiki |
|
303
|
[tn]: ./event.wiki |
|
304
|
[tls]: ./server/debian/nginx.md |
|
305
|
[uu]: /help/www/uv |
|
306
|
[uv]: ./unvers.wiki |
|
307
|
[wiki]: ./wikitheory.wiki |
|
308
|
|
|
309
|
|
|
310
|
## <a id="override"></a>Overriding the Default CSP |
|
311
|
|
|
312
|
If you wish to relax the default CSP’s restrictions or to tighten them |
|
313
|
further, there are multiple ways to accomplish that. |
|
314
|
|
|
315
|
The following methods are listed in top-down order to give the simplest |
|
316
|
and most straightforward method first. Further methods dig down deeper |
|
317
|
into the stack, which is helpful to understand even if you end up using |
|
318
|
a higher-level method. |
|
319
|
|
|
320
|
|
|
321
|
### <a id="cspsetting"></a>The `default-csp` Setting |
|
322
|
|
|
323
|
If the [`default-csp` setting](/help/default-csp) is defined and is |
|
324
|
not an empty string, its value is injected into the page using |
|
325
|
[TH1](./th1.md) via one or more of the methods below, depending on the |
|
326
|
skin you’re using and local configuration. |
|
327
|
|
|
328
|
Changing this setting is the easiest way to set a nonstandard CSP on |
|
329
|
your site. |
|
330
|
|
|
331
|
Because a blank setting tells Fossil to use its hard-coded default CSP, |
|
332
|
you have to say something like the following to get a repository without |
|
333
|
content security policy restrictions: |
|
334
|
|
|
335
|
$ fossil set -R /path/to/served/repo.fossil default-csp 'default-src *' |
|
336
|
|
|
337
|
We recommend that instead of using the command line to change this |
|
338
|
setting that you do it via the repository’s web interface, in |
|
339
|
Admin → Settings. Write your CSP rules in the edit box marked |
|
340
|
"`default-csp`". Do not add hard newlines in that box: the setting needs |
|
341
|
to be on a single long line. Beware that changes take effect |
|
342
|
immediately, so be careful with your edits: you could end up locking |
|
343
|
yourself out of the repository with certain CSP changes! |
|
344
|
|
|
345
|
There are a few reasons why changing this setting via the command line |
|
346
|
is inadvisable, except for very short settings like the example above: |
|
347
|
|
|
348
|
1. You have to be sure to set it on the repository where you want the |
|
349
|
CSP to apply. Changing this setting on your local clone doesn’t |
|
350
|
affect the remote repo you cloned from, which is most likely where |
|
351
|
you want the CSP restrictions. |
|
352
|
|
|
353
|
2. For more complicated CSPs, the quoting rules for your shell and the |
|
354
|
CSP syntax may interact, making it difficult or impossible to set |
|
355
|
your desired CSP via the command line. Setting it via the web UI |
|
356
|
doesn’t have this problem. |
|
357
|
|
|
358
|
|
|
359
|
|
|
360
|
### <a id="th1"></a>TH1 Setup Hook |
|
361
|
|
|
362
|
Fossil sets [the TH1 variable `$default_csp`][thvar] from the |
|
363
|
`default-csp` setting and uses *that* to inject the value into generated |
|
364
|
HTML pages in its stock configuration. |
|
365
|
|
|
366
|
This means that another way you can override this value is to use |
|
367
|
the [`th1-setup` hook script](./th1-hooks.md), which runs before TH1 |
|
368
|
processing happens during skin processing: |
|
369
|
|
|
370
|
$ fossil set th1-setup "set default_csp {default-src 'self'}" |
|
371
|
|
|
372
|
After [the above](#admin-ui), this is the cleanest method. |
|
373
|
|
|
374
|
[thvar]: ./customskin.md#vars |
|
375
|
|
|
376
|
|
|
377
|
|
|
378
|
### <a id="csrc"></a>Fossil C Source Code |
|
379
|
|
|
380
|
When you do neither of the above things, Fossil uses |
|
381
|
[a hard-coded default](/info?ln=527-530&name=65a555d0d4fb846b). |
|
382
|
|
|
383
|
We tell you about this not to suggest that you hack the Fossil C source |
|
384
|
code to change the CSP but simply to document the next step before we |
|
385
|
move down-stack. |
|
386
|
|
|
387
|
|
|
388
|
|
|
389
|
### <a id="header"></a>Skin Header |
|
390
|
|
|
391
|
[In the normal case](./customskin.md#override), Fossil injects the CSP |
|
392
|
retrieved by one of the above methods into the header of all HTML |
|
393
|
documents it generates: |
|
394
|
|
|
395
|
```HTML |
|
396
|
<head>... |
|
397
|
<meta http-equiv="Content-Security-Policy" content="..."> |
|
398
|
... |
|
399
|
``` |
|
400
|
|
|
401
|
Fossil skips this when you’re using a custom skin *and* its |
|
402
|
[Header section](./customskin.md#headfoot) includes a `<body>` tag. This |
|
403
|
is because prior to Fossil 2.5, the Header for a custom skin normally |
|
404
|
contained everything from the opening `<html>` tag through the leading |
|
405
|
`<body>` tag. From that version onward, Fossil now generates that header |
|
406
|
when possible, so that the skin’s Header normally provides only the |
|
407
|
opening tags of the document body, rather than the HTML header. |
|
408
|
|
|
409
|
When we added CSP support in Fossil 2.7, we made use of that mechanism |
|
410
|
to inject the CSP into the generated HTML document header. |
|
411
|
|
|
412
|
For backwards compatibility, Fossil skips this when the skin’s Header |
|
413
|
includes a `<body>` tag. Fossil takes that as a hint that it’s dealing |
|
414
|
with a skin made in the pre-Fossil-2.5 days and doesn’t try to blindly |
|
415
|
override it. |
|
416
|
|
|
417
|
The problem then is that you may be a Fossil user from the days before |
|
418
|
Fossil 2.5, and you may be using a custom skin. This includes users who |
|
419
|
selected one of the stock skins, since for the purposes of this section, |
|
420
|
there is no difference between the cases. If you go into Admin → Skins → |
|
421
|
Header and find a `<body>` tag, none of the above will apply to your |
|
422
|
repo since Fossil will not be injecting its CSP into your pages. |
|
423
|
|
|
424
|
If you selected one of the stock skins (e.g. Khaki) prior to upgrading |
|
425
|
to Fossil 2.5+ and didn’t make any changes to it since that time, you |
|
426
|
can take the simplest option, which is to simply revert to the stock |
|
427
|
version of the skin, so your pages will have the CSP injected, at which |
|
428
|
point this document will begin describing what Fossil does with that |
|
429
|
repo. |
|
430
|
|
|
431
|
If you’re using a customized version of one of the stock skins, the |
|
432
|
skinning mechanism has a diff feature to make it easier to fold your |
|
433
|
local changes into the stock version. |
|
434
|
|
|
435
|
If you’re using a fully customized skin, we recommend replicating the |
|
436
|
method that [the Bootstrap skin uses][dcinj].² Alone among the stock |
|
437
|
Fossil skins, Bootstrap still does old-style Header processing, |
|
438
|
providing the entire HTML header and the start of the document body. |
|
439
|
|
|
440
|
We do *not* recommend injecting an explicit `Content-Security-Policy` |
|
441
|
meta tag into a header to override Fossil’s default CSP. That means you |
|
442
|
have to edit the skin every time you want to change the CSP. Use the TH1 |
|
443
|
`$default_csp` variable like the Bootstrap skin does so you can use one |
|
444
|
of the methods above with your custom skin, so the CSP can vary |
|
445
|
independently of the skin. |
|
446
|
|
|
447
|
[dcinj]: /info?ln=7&name=bef080a6929a3e6f |
|
448
|
|
|
449
|
|
|
450
|
### <a id="fep"></a>Front-End Proxy |
|
451
|
|
|
452
|
If your Fossil repo is behind some sort of HTTP [front-end proxy][svr], |
|
453
|
the [preferred method][pmcsp] for setting the CSP is via a custom HTTP |
|
454
|
header, which most HTTP reverse proxy programs allow. |
|
455
|
|
|
456
|
Beware that if you have a CSP set via both the HTTP and HTML headers |
|
457
|
that the two CSPs [merge](https://stackoverflow.com/a/51153816/142454), |
|
458
|
taking the most restrictive elements of each CSP. If you wish the proxy |
|
459
|
layer’s setting to completely override Fossil’s setting, you will need |
|
460
|
to combine that with one of the methods above to either remove the |
|
461
|
Fossil-provided CSP or to make Fossil provide a no-restrictions CSP |
|
462
|
which the front-end proxy can then tighten down. |
|
463
|
|
|
464
|
[pmcsp]: https://developers.google.com/web/fundamentals/security/csp/#the_meta_tag |
|
465
|
|
|
466
|
|
|
467
|
|
|
468
|
------------ |
|
469
|
|
|
470
|
|
|
471
|
**Asides and Digressions:** |
|
472
|
|
|
473
|
1. Fossil might someday switch to serving the “JavaScript” section of a |
|
474
|
custom skin as a virtual text file, allowing it to be cached by the |
|
475
|
browser, reducing page load times. |
|
476
|
|
|
477
|
2. The stock Bootstrap skin *did* provide redundant CSP text from |
|
478
|
Fossil 2.7 through Fossil 2.9, so setting the CSP via the higher |
|
479
|
level methods did not work with that skin. We fixed this in Fossil |
|
480
|
2.10, but if you selected the Bootstrap skin prior to that, you’re |
|
481
|
now running on a *copy* of it stored in your repo settings table, so |
|
482
|
the change to the stock version of the skin won’t affect that repo |
|
483
|
automatically. You will have to either merge the diffs in with your |
|
484
|
local changes or revert to the stock version of the skin. |
|
485
|
|
|
486
|
|
|
487
|
[cs]: ./customskin.md |
|
488
|
[csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP |
|
489
|
[de]: https://dopiaza.org/tools/datauri/index.php |
|
490
|
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting |
|
491
|
|