Fossil SCM

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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button