Fossil

Check-in [8d43bb87]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More thorough explanation of <script nonce> in www/defcsp.md, and explained the reason why Fossil has no way of providing that nonce in most content types rather than link to the "XSS via check-in rights" forum post. This new presentation of that post's ideas is more detailed and includes discussion of the feature's interaction with the TH1 docs feature.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8d43bb8786772d5737012216aa58982865cfa749d35ba2325a4ccf114ac01a2c
User & Date: wyoung 2019-08-21 11:01:22
Context
2019-08-21
11:09
Added a header to the new XSS material in defcsp.md so we can refer directly to it. check-in: 7b843f2d user: wyoung tags: trunk
11:01
More thorough explanation of <script nonce> in www/defcsp.md, and explained the reason why Fossil has no way of providing that nonce in most content types rather than link to the "XSS via check-in rights" forum post. This new presentation of that post's ideas is more detailed and includes discussion of the feature's interaction with the TH1 docs feature. check-in: 8d43bb87 user: wyoung tags: trunk
09:40
Major improvements to the new defcsp.md article. Expanded the introductory material to better describe what the CSP does; added named anchors to headers; moved the discussion of $default_csp overrides into this document from customskin.md, which now just says how you use that variable read-only; and added an entirely new section, "Replacing the Default CSP". check-in: 366b23a1 user: wyoung tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to www/defcsp.md.

87
88
89
90
91
92
93
94
95
96


97
98
99
100






101
102
103
104








105


















































106
107
108
109
110
111
112
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
170
171
172
173
174
175
176




177
178
179
180
181
182
183
184
185
186
187
do for JavaScript:


### <a name="script"></a> script-src 'self' 'nonce-%s'

This policy means HTML `<script>` tags are only allowed to be emitted
into the output HTML by Fossil C or TH1 code, because only code running
in those contexts can correctly apply the random “nonce” attribute to
the tag that matches the one declared in the CSP, which changes on each
HTTP hit Fossil handles.



This means the workarounds given above will not work for JavaScript. In
effect, the only JavaScript that Fossil can serve is that which it
directly provided, such as that for the CSS section of the skin and that






behind the default [hamburger menu](./customskin.md#menu).

We’re so restrictive about how we treat JavaScript because it can lead
to [difficult-to-avoid cross-site scripting attacks][xssci].





























































## <a name="override"></a>Replacing the Default CSP

If you wish to relax the default CSP’s restrictions or to tighten them
further, there are two ways to accomplish that:

................................................................................
        $ fossil set th1-setup 'set default_csp {default-src: *}'


### <a name="header"></a>Custom Skin Header

Fossil only inserts a CSP into the HTML pages it generates when the
[skin’s Header section](./customskin.md#headfoot) doesn’t contain a
`<head>` tag. None of the stock skins include a `<head>` tag,¹ so if you
haven’t [created a custom skin][cs], you should be getting Fossil’s
default CSP.

We say “should” because long-time Fossil users may be hanging onto a
legacy behavior from before Fossil 2.5, when Fossil added this automatic
`<head>` insertion feature. Repositories created before that release
where the admin either defined a custom skin *or chose one of the stock
................................................................................


------------


**Asides and Digressions:**





1.  The stock Bootstrap skin does actually include a `<head>` tag, but
    from Fossil 2.7 through Fossil 2.9, it just repeated the same CSP
    text that Fossil’s C code inserts into the HTML header for all other
    stock skins. With Fossil 2.10, the stock Bootstrap skin uses
    `$default_csp` instead, so you can [override it as above](#th1).


[cs]:    ./customskin.md
[csp]:   https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
[de]:    https://dopiaza.org/tools/datauri/index.php
[xssci]: https://fossil-scm.org/forum/forumpost/e7c386b21f







|
|
|
>
>

|
|
<
>
>
>
>
>
>
|


<
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







>
>
>
>
|









<
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

do for JavaScript:


### <a name="script"></a> script-src 'self' 'nonce-%s'

This policy means HTML `<script>` tags are only allowed to be emitted
into the output HTML by Fossil C or TH1 code, because only code running
in those contexts can insert the correct “nonce” tag attribute, matching
the one declared in the CSP.¹ Since the nonce is a very large random
number that changes on each HTTP hit Fossil handles, it is effectively
unguessable, which prevents attackers from inserting `<script>` tags
statically.

This means the workarounds given above will not work for JavaScript.
Under this policy, the only JavaScript that Fossil can serve is that

which it directly provided.

Users with the all-powerful Setup capability can insert arbitrary
JavaScript by [defining a custom skin][cs], adding it to the skin’s
“JavaScript” section, which has the random nonce automatically inserted
by Fossil when it serves the page. This is how the JS backing the
default skin’s [hamburger menu](./customskin.md#menu) works.

We’re so restrictive about how we treat JavaScript because it can lead

to difficult-to-avoid scripting attacks. If we used the same CSP for
`<script>` tags [as for `<style>` tags](#style), anyone with check-in
rights on your repository could add a JavaScript file to your repository
and then refer to it from other content added to the site.  Since
JavaScript code can access any data from any URI served under its same
Internet domain, and many Fossil users host multiple Fossil repositories
under a single Internet domain, such a CSP would only be safe if all of
those repositories are trusted equally.

Consider [the Chisel hosting service](http://chiselapp.com/), which
offers free Fossil repository hosting to anyone on the Internet, all
served under the same `http://chiselapp.com/user/$NAME/$REPO` URL
scheme. Any one of those hundreds of repositories could trick you into
visiting their repository home page, set to [an HTML-formatted embedded
doc page][hfed] via Admin → Configuration → Index&nbsp;Page, with this
content:

         <script src="/doc/trunk/bad.js"></script>

That script can then do anything allowed in JavaScript to *any other*
Chisel repository your browser can access.The possibilities for mischief
are *vast*. For just one example, if you have login cookies on four
different Chisel repositories, your attacker could harvest the login
cookies for all of them through this path if we allowed Fossil to serve
JavaScript files under the same CSP policy as we do for CSS files.

This is why the default configuration of Fossil has no way for [embedded
docs][ed], [wiki articles][wiki], [tickets][tkt], [forum posts][fp], or
[tech notes][tn] to automatically insert a nonce into the page content.
This is all user-provided content, which could link to user-provided
JavaScript via check-in rights, effectively giving all such users a
capability that is usually reserved to the repository’s administrator.

The default-disabled [TH1 documents feature][edtf] is the only known
path around this restriction.  If you are serving a Fossil repository
that has any user you do not implicitly trust to a level that you would
willingly run any JavaScript code they’ve provided, blind, you **must
not** give the `--with-th1-docs` option when configuring Fossil, because
that allows substitution of the [pre-defined `$nonce` TH1
variable](./th1.md#nonce) into [HTML-formatted embedded docs][hfed]:

         <script src="/doc/trunk/bad.js" nonce="$nonce"></script>

Even with this feature enabled, you cannot put `<script>` tags into
Fossil Wiki or Markdown-formatted content, because our HTML generators
for those formats purposely strip or disable such tags in the output.
Therefore, if you trust those users with check-in rights to provide
JavaScript but not those allowed to file tickets, append to wiki
articles, etc., you might justify enabling TH1 docs on your repository,
since the only way to create or modify HTML-formatted embedded docs is
through check-ins.

[ed]:   ./embeddeddoc.wiki
[edtf]: ./embeddeddoc.wiki#th1
[fp]:   ./forum.wiki
[hfed]: ./embeddeddoc.wiki#html
[tkt]:  ./tickets.wiki
[tn]:   ./event.wiki
[wiki]: ./wikitheory.wiki


## <a name="override"></a>Replacing the Default CSP

If you wish to relax the default CSP’s restrictions or to tighten them
further, there are two ways to accomplish that:

................................................................................
        $ fossil set th1-setup 'set default_csp {default-src: *}'


### <a name="header"></a>Custom Skin Header

Fossil only inserts a CSP into the HTML pages it generates when the
[skin’s Header section](./customskin.md#headfoot) doesn’t contain a
`<head>` tag. None of the stock skins include a `<head>` tag,² so if you
haven’t [created a custom skin][cs], you should be getting Fossil’s
default CSP.

We say “should” because long-time Fossil users may be hanging onto a
legacy behavior from before Fossil 2.5, when Fossil added this automatic
`<head>` insertion feature. Repositories created before that release
where the admin either defined a custom skin *or chose one of the stock
................................................................................


------------


**Asides and Digressions:**

1.  There is actually a third context that can correctly insert this
    nonce attribute: [a CGI server extension](./serverext.wiki), by use of
    the `FOSSIL_NONCE` variable sent to the CGI by Fossil.

2.  The stock Bootstrap skin does actually include a `<head>` tag, but
    from Fossil 2.7 through Fossil 2.9, it just repeated the same CSP
    text that Fossil’s C code inserts into the HTML header for all other
    stock skins. With Fossil 2.10, the stock Bootstrap skin uses
    `$default_csp` instead, so you can [override it as above](#th1).


[cs]:    ./customskin.md
[csp]:   https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
[de]:    https://dopiaza.org/tools/datauri/index.php

Changes to www/embeddeddoc.wiki.

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
[/md_rules  | Markdown markup language].
Documentation files ending in ".txt" are plain text.
Wiki, markdown, and plain text documentation files
are rendered with the standard fossil header and footer added.
Most other mimetypes are delivered directly to the requesting
web browser without interpretation, additions, or changes.

Files with the mimetype "text/html" (the .html or .htm suffix) are
usually rendered directly to the browser without interpretation.
However, if the file begins with a &lt;div&gt; element like this:

    <b>&lt;div class='fossil-doc' data-title='<i>Title Text</i>'&gt;</b>

Then the standard Fossil header and footer are added to the document
prior to being displayed.  The "class='fossil-doc'" attribute is
................................................................................
</pre></nowiki>

As you can see, this happens for all source document types that end up
rendering as HTML, not just source documents in the HTML
<tt>fossil-doc</tt> format described at the end of the prior section.


<h3>2. TH1 Documents</h3>

Fossil will substitute the value of [./th1.md | TH1 expressions] within
<tt>{</tt> curly braces <tt>}</tt> into the output HTML if you have
configured it with the <tt>--with-th1-docs</tt> option, which is
disabled by default.









|







 







|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
[/md_rules  | Markdown markup language].
Documentation files ending in ".txt" are plain text.
Wiki, markdown, and plain text documentation files
are rendered with the standard fossil header and footer added.
Most other mimetypes are delivered directly to the requesting
web browser without interpretation, additions, or changes.

<a name="html"></a>Files with the mimetype "text/html" (the .html or .htm suffix) are
usually rendered directly to the browser without interpretation.
However, if the file begins with a &lt;div&gt; element like this:

    <b>&lt;div class='fossil-doc' data-title='<i>Title Text</i>'&gt;</b>

Then the standard Fossil header and footer are added to the document
prior to being displayed.  The "class='fossil-doc'" attribute is
................................................................................
</pre></nowiki>

As you can see, this happens for all source document types that end up
rendering as HTML, not just source documents in the HTML
<tt>fossil-doc</tt> format described at the end of the prior section.


<h3 id="th1">2. TH1 Documents</h3>

Fossil will substitute the value of [./th1.md | TH1 expressions] within
<tt>{</tt> curly braces <tt>}</tt> into the output HTML if you have
configured it with the <tt>--with-th1-docs</tt> option, which is
disabled by default.