Fossil SCM
Added a new section to www/defcsp.md, "Serving Files Within the Limits". It pulls together a bit of info already in the document on the topic and then expands it considerably. The overall message is, "You probably don't have to override the default CSP."
Commit
58883ecceaf8cfe38a442b48f886849016343e942898b8c85744adb5c20c0363
Parent
ab2b8de8962831e…
1 file changed
+100
-43
+100
-43
| --- www/defcsp.md | ||
| +++ www/defcsp.md | ||
| @@ -70,50 +70,19 @@ | ||
| 70 | 70 | are hard to read and edit. There are secondary problems as well: if you |
| 71 | 71 | put a large image into a Fossil forum post this way, anyone subscribed |
| 72 | 72 | to email alerts will get a copy of the raw URI text, which can amount to |
| 73 | 73 | pages and pages of [ugly Base64-encoded text][b64]. |
| 74 | 74 | |
| 75 | -Fossil offers several alternatives for serving large content resources | |
| 76 | -from within the repository: | |
| 77 | - | |
| 78 | -* **versioned content** via [`/raw`](/help?cmd=/raw) | |
| 79 | -* **[unversioned content](./unvers.wiki)** via [`/uv`](/help?cmd=/uv) | |
| 80 | -* **relative links** | |
| 81 | - | |
| 82 | -Only the first two options work in [wiki articles][wiki], | |
| 83 | -[tickets][tkt], [forum posts][fp], and [tech notes][tn]. The last | |
| 84 | -option is a much simpler alternative, but it only works within [embedded | |
| 85 | -documentation][ed]: | |
| 75 | +For inline images within [embedded documentation][ed], it suffices to | |
| 76 | +store the referred-to files in the repo and then refer to them using | |
| 77 | +repo-relative URLs: | |
| 86 | 78 | |
| 87 | 79 |  |
| 88 | 80 | |
| 89 | -Because all of these methods pull content from within the Fossil | |
| 90 | -repository, they all count as “self” for the purposes of the CSP. | |
| 91 | - | |
| 92 | -This rule also works when the Fossil repository is but one path in a | |
| 93 | -larger website. The browser can’t distinguish Fossil-served content from | |
| 94 | -that served by the rest of the same web domain, so your repository can | |
| 95 | -refer to other resources within that same web site, whether they are | |
| 96 | -static files served by [an HTTP proxy in front of Fossil][svr], by | |
| 97 | -another Fossil repository served under that same domain, or dynamic | |
| 98 | -content served by, say, a PHP app on that same site. | |
| 99 | - | |
| 100 | -Beware that there are a number of problems that come up with using such | |
| 101 | -out-of-repository resources, which all stem from the fact that they | |
| 102 | -aren’t included in a [sync](/help?cmd=sync): | |
| 103 | - | |
| 104 | -1. Relative links break in `fossil ui` when run on a clone. | |
| 105 | - | |
| 106 | -2. Absolute links break under certain types of failover and | |
| 107 | - load-balancing schemes. | |
| 108 | - | |
| 109 | -3. Absolute links fail when one’s purpose in using a clone is to | |
| 110 | - recover from the loss of a project web site by standing that clone | |
| 111 | - up [as a server][svr] elsewhere. | |
| 112 | - | |
| 113 | -You can avoid all of these problems by referring to in-repo resources | |
| 114 | -exclusively. | |
| 81 | +This avoids bloating the doc text with `data:` URI blobs: | |
| 82 | + | |
| 83 | +There are many other cases, [covered below](#serving). | |
| 115 | 84 | |
| 116 | 85 | [b64]: https://en.wikipedia.org/wiki/Base64 |
| 117 | 86 | [svr]: ./server/ |
| 118 | 87 | |
| 119 | 88 | |
| @@ -160,12 +129,12 @@ | ||
| 160 | 129 | emitted via these paths to be safe because it’s audited by the |
| 161 | 130 | Fossil developers. We assume that you got your Fossil server’s code |
| 162 | 131 | from a trustworthy source and that an attacker cannot replace your |
| 163 | 132 | Fossil server binary. |
| 164 | 133 | |
| 165 | -* **TH1 code:** The Fossil TH1 interpreter pre-defines the [`$nonce` | |
| 166 | - variable](./th1.md#nonce) for use in [custom skins][cs]. For | |
| 134 | +* **TH1 code:** The Fossil TH1 interpreter pre-defines the | |
| 135 | + [`$nonce` variable](./th1.md#nonce) for use in [custom skins][cs]. For | |
| 167 | 136 | example, some of the stock skins that ship with Fossil include a |
| 168 | 137 | wall clock feature up in the corner that updates once a minute. |
| 169 | 138 | These paths are safe in the default Fossil configuration because |
| 170 | 139 | only the [all-powerful Setup user][su] can write TH1 code that |
| 171 | 140 | executes in the server’s running context. |
| @@ -177,11 +146,12 @@ | ||
| 177 | 146 | CGI in the `FOSSIL_NONCE` environment variable, which it can then |
| 178 | 147 | use in `<script>` elements it generates. Because these extensions |
| 179 | 148 | can only be installed by the Fossil server’s system administrator, |
| 180 | 149 | this path is also considered safe. |
| 181 | 150 | |
| 182 | -[su]: ./admin-v-setup.md | |
| 151 | +[su]: ./admin-v-setup.md | |
| 152 | +[ext]: ./serverext.wiki | |
| 183 | 153 | |
| 184 | 154 | |
| 185 | 155 | #### <a name="xss"></a>Cross-Site Scripting via Ordinary User Capabilities |
| 186 | 156 | |
| 187 | 157 | We’re so restrictive about how we treat JavaScript because it can lead |
| @@ -237,18 +207,105 @@ | ||
| 237 | 207 | since the only way to create or modify HTML-formatted embedded docs is |
| 238 | 208 | through check-ins. |
| 239 | 209 | |
| 240 | 210 | [ed]: ./embeddeddoc.wiki |
| 241 | 211 | [edtf]: ./embeddeddoc.wiki#th1 |
| 242 | -[ext]: ./serverext.wiki | |
| 243 | -[fp]: ./forum.wiki | |
| 244 | 212 | [hfed]: ./embeddeddoc.wiki#html |
| 213 | + | |
| 214 | + | |
| 215 | +## <a name="serving"></a>Serving Files Within the Limits | |
| 216 | + | |
| 217 | +There are several ways to serve files within the above restrictions, | |
| 218 | +avoiding the need to [override the default CSP](#override). In | |
| 219 | +decreasing order of simplicity and preference: | |
| 220 | + | |
| 221 | +1. Within [embedded documentation][ed] (only!) you can refer to files | |
| 222 | + stored in the repo using document-relative file URLs: | |
| 223 | + | |
| 224 | +  | |
| 225 | + | |
| 226 | +2. Relative file URLs don’t work from [wiki articles][wiki], | |
| 227 | + [tickets][tkt], [forum posts][fp], or [tech notes][tn], but you can | |
| 228 | + still refer to them inside the repo with [`/doc`][du] or | |
| 229 | + [`/raw`][ru] URLs: | |
| 230 | + | |
| 231 | +  | |
| 232 | + <img src="/raw/logo.png" style="float: right; margin-left: 2em"> | |
| 233 | + | |
| 234 | +3. Store the files as [unversioned content][uv], referred to using | |
| 235 | + [`/uv`][uu] URLs instead: | |
| 236 | + | |
| 237 | +  | |
| 238 | + | |
| 239 | +4. Use the [optional CGI server extensions feature](./serverext.wiki) | |
| 240 | + to serve such content via `/ext` URLs. | |
| 241 | + | |
| 242 | +5. Put Fossil behind a [front-end proxy server][svr] as a virtual | |
| 243 | + subdirectory within the site, so that our default CSP’s “self” rules | |
| 244 | + match static file routes on that same site. For instance, your repo | |
| 245 | + might be at `https://example.com/code`, allowing documentes in that | |
| 246 | + repo to refer to: | |
| 247 | + | |
| 248 | + * images as `/image/foo.png` | |
| 249 | + * JavaScript files as `/js/bar.js` | |
| 250 | + * CSS style sheets as `/style/qux.css` | |
| 251 | + | |
| 252 | + Although those files are all outside the Fossil repo at `/code`, | |
| 253 | + keep in mind that it is the browser’s notion of “self” that matters | |
| 254 | + here, not Fossil’s. All resources come from the same Internet | |
| 255 | + domain, so the browser cannot distinguish Fossil-provided content | |
| 256 | + from static content served directly by the proxy server. | |
| 257 | + | |
| 258 | + This method opens up many other potential benefits, such as [TLS | |
| 259 | + encryption](./tls-nginx.md), high-performance tuning via custom HTTP | |
| 260 | + headers, integration with other web technologies like PHP, etc. | |
| 261 | + | |
| 262 | +You might wonder why we rank in-repo content as most preferred above. It | |
| 263 | +is because the first two options are the only ones that cause such | |
| 264 | +resources to be included in an initial clone or in subsequent repo | |
| 265 | +syncs. The methods further down the list have a number of undesirable | |
| 266 | +properties: | |
| 267 | + | |
| 268 | +1. Relative links to out-of-repo files break in `fossil ui` when run on | |
| 269 | + a clone. | |
| 270 | + | |
| 271 | +2. Absolute links back to the public repo instance solve that: | |
| 272 | + | |
| 273 | +  | |
| 274 | + | |
| 275 | + ...but using them breaks some types of failover and load-balancing | |
| 276 | + schemes, because it creates a [single point of failure][spof]. | |
| 277 | + | |
| 278 | +3. Absolute links fail when one’s purpose in using a clone is to | |
| 279 | + recover from the loss of a project web site by standing that clone | |
| 280 | + up [as a server][svr] elsewhere. You probably forgot to copy such | |
| 281 | + external resources in the backup copies, so that when the main repo | |
| 282 | + site disappears, so do those files. | |
| 283 | + | |
| 284 | +Unversioned content is in the middle of the first list above — between | |
| 285 | +fully-external content and fully in-repo content — because it isn’t | |
| 286 | +included in a clone unless you give the `--unversioned` flag. If you | |
| 287 | +then want updates to the unversioned content to be included in syncs, | |
| 288 | +you have to give the same flag to [a `sync` command](/help?cmd=sync). | |
| 289 | +There is no equivalent with other commands such as `up` and `pull`, so | |
| 290 | +you must then remember to give `fossil uv` commands when necessary to | |
| 291 | +pull new unversioned content down. | |
| 292 | + | |
| 293 | +Thus our recommendation that you refer to in-repo resources exclusively. | |
| 294 | + | |
| 295 | +[du]: /help?cmd=/doc | |
| 296 | +[fp]: ./forum.wiki | |
| 297 | +[ru]: /help?cmd=/raw | |
| 298 | +[spof]: https://en.wikipedia.org/wiki/Single_point_of_failure | |
| 245 | 299 | [tkt]: ./tickets.wiki |
| 246 | 300 | [tn]: ./event.wiki |
| 301 | +[uu]: /help?cmd=/uv | |
| 302 | +[uv]: ./unvers.wiki | |
| 247 | 303 | [wiki]: ./wikitheory.wiki |
| 248 | 304 | |
| 249 | -## <a name="override"></a>Replacing the Default CSP | |
| 305 | + | |
| 306 | +## <a name="override"></a>Overriding the Default CSP | |
| 250 | 307 | |
| 251 | 308 | If you wish to relax the default CSP’s restrictions or to tighten them |
| 252 | 309 | further, there are two ways to accomplish that: |
| 253 | 310 | |
| 254 | 311 | |
| 255 | 312 |
| --- www/defcsp.md | |
| +++ www/defcsp.md | |
| @@ -70,50 +70,19 @@ | |
| 70 | are hard to read and edit. There are secondary problems as well: if you |
| 71 | put a large image into a Fossil forum post this way, anyone subscribed |
| 72 | to email alerts will get a copy of the raw URI text, which can amount to |
| 73 | pages and pages of [ugly Base64-encoded text][b64]. |
| 74 | |
| 75 | Fossil offers several alternatives for serving large content resources |
| 76 | from within the repository: |
| 77 | |
| 78 | * **versioned content** via [`/raw`](/help?cmd=/raw) |
| 79 | * **[unversioned content](./unvers.wiki)** via [`/uv`](/help?cmd=/uv) |
| 80 | * **relative links** |
| 81 | |
| 82 | Only the first two options work in [wiki articles][wiki], |
| 83 | [tickets][tkt], [forum posts][fp], and [tech notes][tn]. The last |
| 84 | option is a much simpler alternative, but it only works within [embedded |
| 85 | documentation][ed]: |
| 86 | |
| 87 |  |
| 88 | |
| 89 | Because all of these methods pull content from within the Fossil |
| 90 | repository, they all count as “self” for the purposes of the CSP. |
| 91 | |
| 92 | This rule also works when the Fossil repository is but one path in a |
| 93 | larger website. The browser can’t distinguish Fossil-served content from |
| 94 | that served by the rest of the same web domain, so your repository can |
| 95 | refer to other resources within that same web site, whether they are |
| 96 | static files served by [an HTTP proxy in front of Fossil][svr], by |
| 97 | another Fossil repository served under that same domain, or dynamic |
| 98 | content served by, say, a PHP app on that same site. |
| 99 | |
| 100 | Beware that there are a number of problems that come up with using such |
| 101 | out-of-repository resources, which all stem from the fact that they |
| 102 | aren’t included in a [sync](/help?cmd=sync): |
| 103 | |
| 104 | 1. Relative links break in `fossil ui` when run on a clone. |
| 105 | |
| 106 | 2. Absolute links break under certain types of failover and |
| 107 | load-balancing schemes. |
| 108 | |
| 109 | 3. Absolute links fail when one’s purpose in using a clone is to |
| 110 | recover from the loss of a project web site by standing that clone |
| 111 | up [as a server][svr] elsewhere. |
| 112 | |
| 113 | You can avoid all of these problems by referring to in-repo resources |
| 114 | exclusively. |
| 115 | |
| 116 | [b64]: https://en.wikipedia.org/wiki/Base64 |
| 117 | [svr]: ./server/ |
| 118 | |
| 119 | |
| @@ -160,12 +129,12 @@ | |
| 160 | emitted via these paths to be safe because it’s audited by the |
| 161 | Fossil developers. We assume that you got your Fossil server’s code |
| 162 | from a trustworthy source and that an attacker cannot replace your |
| 163 | Fossil server binary. |
| 164 | |
| 165 | * **TH1 code:** The Fossil TH1 interpreter pre-defines the [`$nonce` |
| 166 | variable](./th1.md#nonce) for use in [custom skins][cs]. For |
| 167 | example, some of the stock skins that ship with Fossil include a |
| 168 | wall clock feature up in the corner that updates once a minute. |
| 169 | These paths are safe in the default Fossil configuration because |
| 170 | only the [all-powerful Setup user][su] can write TH1 code that |
| 171 | executes in the server’s running context. |
| @@ -177,11 +146,12 @@ | |
| 177 | CGI in the `FOSSIL_NONCE` environment variable, which it can then |
| 178 | use in `<script>` elements it generates. Because these extensions |
| 179 | can only be installed by the Fossil server’s system administrator, |
| 180 | this path is also considered safe. |
| 181 | |
| 182 | [su]: ./admin-v-setup.md |
| 183 | |
| 184 | |
| 185 | #### <a name="xss"></a>Cross-Site Scripting via Ordinary User Capabilities |
| 186 | |
| 187 | We’re so restrictive about how we treat JavaScript because it can lead |
| @@ -237,18 +207,105 @@ | |
| 237 | since the only way to create or modify HTML-formatted embedded docs is |
| 238 | through check-ins. |
| 239 | |
| 240 | [ed]: ./embeddeddoc.wiki |
| 241 | [edtf]: ./embeddeddoc.wiki#th1 |
| 242 | [ext]: ./serverext.wiki |
| 243 | [fp]: ./forum.wiki |
| 244 | [hfed]: ./embeddeddoc.wiki#html |
| 245 | [tkt]: ./tickets.wiki |
| 246 | [tn]: ./event.wiki |
| 247 | [wiki]: ./wikitheory.wiki |
| 248 | |
| 249 | ## <a name="override"></a>Replacing the Default CSP |
| 250 | |
| 251 | If you wish to relax the default CSP’s restrictions or to tighten them |
| 252 | further, there are two ways to accomplish that: |
| 253 | |
| 254 | |
| 255 |
| --- www/defcsp.md | |
| +++ www/defcsp.md | |
| @@ -70,50 +70,19 @@ | |
| 70 | are hard to read and edit. There are secondary problems as well: if you |
| 71 | put a large image into a Fossil forum post this way, anyone subscribed |
| 72 | to email alerts will get a copy of the raw URI text, which can amount to |
| 73 | pages and pages of [ugly Base64-encoded text][b64]. |
| 74 | |
| 75 | For inline images within [embedded documentation][ed], it suffices to |
| 76 | store the referred-to files in the repo and then refer to them using |
| 77 | repo-relative URLs: |
| 78 | |
| 79 |  |
| 80 | |
| 81 | This avoids bloating the doc text with `data:` URI blobs: |
| 82 | |
| 83 | There are many other cases, [covered below](#serving). |
| 84 | |
| 85 | [b64]: https://en.wikipedia.org/wiki/Base64 |
| 86 | [svr]: ./server/ |
| 87 | |
| 88 | |
| @@ -160,12 +129,12 @@ | |
| 129 | emitted via these paths to be safe because it’s audited by the |
| 130 | Fossil developers. We assume that you got your Fossil server’s code |
| 131 | from a trustworthy source and that an attacker cannot replace your |
| 132 | Fossil server binary. |
| 133 | |
| 134 | * **TH1 code:** The Fossil TH1 interpreter pre-defines the |
| 135 | [`$nonce` variable](./th1.md#nonce) for use in [custom skins][cs]. For |
| 136 | example, some of the stock skins that ship with Fossil include a |
| 137 | wall clock feature up in the corner that updates once a minute. |
| 138 | These paths are safe in the default Fossil configuration because |
| 139 | only the [all-powerful Setup user][su] can write TH1 code that |
| 140 | executes in the server’s running context. |
| @@ -177,11 +146,12 @@ | |
| 146 | CGI in the `FOSSIL_NONCE` environment variable, which it can then |
| 147 | use in `<script>` elements it generates. Because these extensions |
| 148 | can only be installed by the Fossil server’s system administrator, |
| 149 | this path is also considered safe. |
| 150 | |
| 151 | [su]: ./admin-v-setup.md |
| 152 | [ext]: ./serverext.wiki |
| 153 | |
| 154 | |
| 155 | #### <a name="xss"></a>Cross-Site Scripting via Ordinary User Capabilities |
| 156 | |
| 157 | We’re so restrictive about how we treat JavaScript because it can lead |
| @@ -237,18 +207,105 @@ | |
| 207 | since the only way to create or modify HTML-formatted embedded docs is |
| 208 | through check-ins. |
| 209 | |
| 210 | [ed]: ./embeddeddoc.wiki |
| 211 | [edtf]: ./embeddeddoc.wiki#th1 |
| 212 | [hfed]: ./embeddeddoc.wiki#html |
| 213 | |
| 214 | |
| 215 | ## <a name="serving"></a>Serving Files Within the Limits |
| 216 | |
| 217 | There are several ways to serve files within the above restrictions, |
| 218 | avoiding the need to [override the default CSP](#override). In |
| 219 | decreasing order of simplicity and preference: |
| 220 | |
| 221 | 1. Within [embedded documentation][ed] (only!) you can refer to files |
| 222 | stored in the repo using document-relative file URLs: |
| 223 | |
| 224 |  |
| 225 | |
| 226 | 2. Relative file URLs don’t work from [wiki articles][wiki], |
| 227 | [tickets][tkt], [forum posts][fp], or [tech notes][tn], but you can |
| 228 | still refer to them inside the repo with [`/doc`][du] or |
| 229 | [`/raw`][ru] URLs: |
| 230 | |
| 231 |  |
| 232 | <img src="/raw/logo.png" style="float: right; margin-left: 2em"> |
| 233 | |
| 234 | 3. Store the files as [unversioned content][uv], referred to using |
| 235 | [`/uv`][uu] URLs instead: |
| 236 | |
| 237 |  |
| 238 | |
| 239 | 4. Use the [optional CGI server extensions feature](./serverext.wiki) |
| 240 | to serve such content via `/ext` URLs. |
| 241 | |
| 242 | 5. Put Fossil behind a [front-end proxy server][svr] as a virtual |
| 243 | subdirectory within the site, so that our default CSP’s “self” rules |
| 244 | match static file routes on that same site. For instance, your repo |
| 245 | might be at `https://example.com/code`, allowing documentes in that |
| 246 | repo to refer to: |
| 247 | |
| 248 | * images as `/image/foo.png` |
| 249 | * JavaScript files as `/js/bar.js` |
| 250 | * CSS style sheets as `/style/qux.css` |
| 251 | |
| 252 | Although those files are all outside the Fossil repo at `/code`, |
| 253 | keep in mind that it is the browser’s notion of “self” that matters |
| 254 | here, not Fossil’s. All resources come from the same Internet |
| 255 | domain, so the browser cannot distinguish Fossil-provided content |
| 256 | from static content served directly by the proxy server. |
| 257 | |
| 258 | This method opens up many other potential benefits, such as [TLS |
| 259 | encryption](./tls-nginx.md), high-performance tuning via custom HTTP |
| 260 | headers, integration with other web technologies like PHP, etc. |
| 261 | |
| 262 | You might wonder why we rank in-repo content as most preferred above. It |
| 263 | is because the first two options are the only ones that cause such |
| 264 | resources to be included in an initial clone or in subsequent repo |
| 265 | syncs. The methods further down the list have a number of undesirable |
| 266 | properties: |
| 267 | |
| 268 | 1. Relative links to out-of-repo files break in `fossil ui` when run on |
| 269 | a clone. |
| 270 | |
| 271 | 2. Absolute links back to the public repo instance solve that: |
| 272 | |
| 273 |  |
| 274 | |
| 275 | ...but using them breaks some types of failover and load-balancing |
| 276 | schemes, because it creates a [single point of failure][spof]. |
| 277 | |
| 278 | 3. Absolute links fail when one’s purpose in using a clone is to |
| 279 | recover from the loss of a project web site by standing that clone |
| 280 | up [as a server][svr] elsewhere. You probably forgot to copy such |
| 281 | external resources in the backup copies, so that when the main repo |
| 282 | site disappears, so do those files. |
| 283 | |
| 284 | Unversioned content is in the middle of the first list above — between |
| 285 | fully-external content and fully in-repo content — because it isn’t |
| 286 | included in a clone unless you give the `--unversioned` flag. If you |
| 287 | then want updates to the unversioned content to be included in syncs, |
| 288 | you have to give the same flag to [a `sync` command](/help?cmd=sync). |
| 289 | There is no equivalent with other commands such as `up` and `pull`, so |
| 290 | you must then remember to give `fossil uv` commands when necessary to |
| 291 | pull new unversioned content down. |
| 292 | |
| 293 | Thus our recommendation that you refer to in-repo resources exclusively. |
| 294 | |
| 295 | [du]: /help?cmd=/doc |
| 296 | [fp]: ./forum.wiki |
| 297 | [ru]: /help?cmd=/raw |
| 298 | [spof]: https://en.wikipedia.org/wiki/Single_point_of_failure |
| 299 | [tkt]: ./tickets.wiki |
| 300 | [tn]: ./event.wiki |
| 301 | [uu]: /help?cmd=/uv |
| 302 | [uv]: ./unvers.wiki |
| 303 | [wiki]: ./wikitheory.wiki |
| 304 | |
| 305 | |
| 306 | ## <a name="override"></a>Overriding the Default CSP |
| 307 | |
| 308 | If you wish to relax the default CSP’s restrictions or to tighten them |
| 309 | further, there are two ways to accomplish that: |
| 310 | |
| 311 | |
| 312 |