Skip to content

Commit d58ce83

Browse files
committed
docs: add csp.rst and move existing contents
1 parent 3266127 commit d58ce83

6 files changed

Lines changed: 128 additions & 116 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
.. _content-security-policy:
2+
3+
#######################
4+
Content Security Policy
5+
#######################
6+
7+
.. contents::
8+
:local:
9+
:depth: 2
10+
11+
********************************
12+
What is Content Security Policy?
13+
********************************
14+
15+
One of the best protections you have against XSS attacks is to implement a Content Security Policy on the site.
16+
This forces you to whitelist every single source of content that is pulled in from your site's HTML,
17+
including images, stylesheets, javascript files, etc. The browser will refuse content from sources that don't meet
18+
the whitelist. This whitelist is created within the response's ``Content-Security-Policy`` header and has many
19+
different ways it can be configured.
20+
21+
This sounds complex, and on some sites, can definitely be challenging. For many simple sites, though, where all content
22+
is served by the same domain (http://example.com), it is very simple to integrate.
23+
24+
As this is a complex subject, this user guide will not go over all of the details. For more information, you should
25+
visit the following sites:
26+
27+
* `Content Security Policy main site <https://content-security-policy.com/>`_
28+
* `W3C Specification <https://www.w3.org/TR/CSP>`_
29+
* `Introduction at HTML5Rocks <https://www.html5rocks.com/en/tutorials/security/content-security-policy/>`_
30+
* `Article at SitePoint <https://www.sitepoint.com/improving-web-security-with-the-content-security-policy/>`_
31+
32+
**************
33+
Turning CSP On
34+
**************
35+
36+
.. important:: The :ref:`Debug Toolbar <the-debug-toolbar>` may use Kint, which
37+
outputs inline scripts. Therefore, when CSP is turned on, CSP nonce is
38+
automatically output for the Debug Toolbar. However, if you are not using
39+
CSP nonce, this will change the CSP header to something you do not intend,
40+
and it will behave differently than in production; if you want to verify CSP
41+
behavior, turn off the Debug Toolbar.
42+
43+
By default, support for this is off. To enable support in your application, edit the ``CSPEnabled`` value in
44+
**app/Config/App.php**:
45+
46+
.. literalinclude:: csp/011.php
47+
48+
When enabled, the response object will contain an instance of ``CodeIgniter\HTTP\ContentSecurityPolicy``. The
49+
values set in **app/Config/ContentSecurityPolicy.php** are applied to that instance, and if no changes are
50+
needed during runtime, then the correctly formatted header is sent and you're all done.
51+
52+
With CSP enabled, two header lines are added to the HTTP response: a **Content-Security-Policy** header, with
53+
policies identifying content types or origins that are explicitly allowed for different
54+
contexts, and a **Content-Security-Policy-Report-Only** header, which identifies content types
55+
or origins that will be allowed but which will also be reported to the destination
56+
of your choice.
57+
58+
Our implementation provides for a default treatment, changeable through the ``reportOnly()`` method.
59+
When an additional entry is added to a CSP directive, as shown below, it will be added
60+
to the CSP header appropriate for blocking or preventing. That can be overridden on a per
61+
call basis, by providing an optional second parameter to the adding method call.
62+
63+
*********************
64+
Runtime Configuration
65+
*********************
66+
67+
If your application needs to make changes at run-time, you can access the instance at ``$this->response->getCSP()`` in your controllers. The
68+
class holds a number of methods that map pretty clearly to the appropriate header value that you need to set.
69+
Examples are shown below, with different combinations of parameters, though all accept either a directive
70+
name or an array of them:
71+
72+
.. literalinclude:: csp/012.php
73+
74+
The first parameter to each of the "add" methods is an appropriate string value,
75+
or an array of them.
76+
77+
The ``reportOnly()`` method allows you to specify the default reporting treatment
78+
for subsequent sources, unless over-ridden. For instance, you could specify
79+
that youtube.com was allowed, and then provide several allowed but reported sources:
80+
81+
.. literalinclude:: csp/013.php
82+
83+
**************
84+
Inline Content
85+
**************
86+
87+
It is possible to set a website to not protect even inline scripts and styles on its own pages, since this might have
88+
been the result of user-generated content. To protect against this, CSP allows you to specify a nonce within the
89+
``<style>`` and ``<script>`` tags, and to add those values to the response's header. This is a pain to handle in real
90+
life, and is most secure when generated on the fly. To make this simple, you can include a ``{csp-style-nonce}`` or
91+
``{csp-script-nonce}`` placeholder in the tag and it will be handled for you automatically::
92+
93+
// Original
94+
<script {csp-script-nonce}>
95+
console.log("Script won't run as it doesn't contain a nonce attribute");
96+
</script>
97+
98+
// Becomes
99+
<script nonce="Eskdikejidojdk978Ad8jf">
100+
console.log("Script won't run as it doesn't contain a nonce attribute");
101+
</script>
102+
103+
// OR
104+
<style {csp-style-nonce}>
105+
. . .
106+
</style>
107+
108+
.. warning:: If an attacker injects a string like ``<script {csp-script-nonce}>``, it might become the real nonce attribute with this functionality. You can customize the placeholder string with the ``$scriptNonceTag`` and ``$styleNonceTag`` properties in **app/Config/ContentSecurityPolicy.php**.
109+
110+
If you don't like this auto replacement functionality, you can turn it off with setting ``$autoNonce = false`` in **app/Config/ContentSecurityPolicy.php**.
111+
112+
In this case, you can use the functions, :php:func:`csp_script_nonce()` and :php:func:`csp_style_nonce()`::
113+
114+
// Original
115+
<script <?= csp_script_nonce() ?>>
116+
console.log("Script won't run as it doesn't contain a nonce attribute");
117+
</script>
118+
119+
// Becomes
120+
<script nonce="Eskdikejidojdk978Ad8jf">
121+
console.log("Script won't run as it doesn't contain a nonce attribute");
122+
</script>
123+
124+
// OR
125+
<style <?= csp_style_nonce() ?>>
126+
. . .
127+
</style>
File renamed without changes.
File renamed without changes.
File renamed without changes.

user_guide_src/source/outgoing/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ View components are used to build what is returned to the user.
1616
table
1717
response
1818
api_responses
19+
csp
1920
localization
2021
alternative_php

user_guide_src/source/outgoing/response.rst

Lines changed: 0 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -199,122 +199,6 @@ to the ``Cache-Control`` header. You are free to set all of the options exactly
199199
situation. While most of the options are applied to the ``Cache-Control`` header, it intelligently handles
200200
the ``etag`` and ``last-modified`` options to their appropriate header.
201201

202-
.. _content-security-policy:
203-
204-
Content Security Policy
205-
=======================
206-
207-
One of the best protections you have against XSS attacks is to implement a Content Security Policy on the site.
208-
This forces you to whitelist every single source of content that is pulled in from your site's HTML,
209-
including images, stylesheets, javascript files, etc. The browser will refuse content from sources that don't meet
210-
the whitelist. This whitelist is created within the response's ``Content-Security-Policy`` header and has many
211-
different ways it can be configured.
212-
213-
This sounds complex, and on some sites, can definitely be challenging. For many simple sites, though, where all content
214-
is served by the same domain (http://example.com), it is very simple to integrate.
215-
216-
As this is a complex subject, this user guide will not go over all of the details. For more information, you should
217-
visit the following sites:
218-
219-
* `Content Security Policy main site <https://content-security-policy.com/>`_
220-
* `W3C Specification <https://www.w3.org/TR/CSP>`_
221-
* `Introduction at HTML5Rocks <https://www.html5rocks.com/en/tutorials/security/content-security-policy/>`_
222-
* `Article at SitePoint <https://www.sitepoint.com/improving-web-security-with-the-content-security-policy/>`_
223-
224-
Turning CSP On
225-
--------------
226-
227-
.. important:: The :ref:`Debug Toolbar <the-debug-toolbar>` may use Kint, which
228-
outputs inline scripts. Therefore, when CSP is turned on, CSP nonce is
229-
automatically output for the Debug Toolbar. However, if you are not using
230-
CSP nonce, this will change the CSP header to something you do not intend,
231-
and it will behave differently than in production; if you want to verify CSP
232-
behavior, turn off the Debug Toolbar.
233-
234-
By default, support for this is off. To enable support in your application, edit the ``CSPEnabled`` value in
235-
**app/Config/App.php**:
236-
237-
.. literalinclude:: response/011.php
238-
239-
When enabled, the response object will contain an instance of ``CodeIgniter\HTTP\ContentSecurityPolicy``. The
240-
values set in **app/Config/ContentSecurityPolicy.php** are applied to that instance, and if no changes are
241-
needed during runtime, then the correctly formatted header is sent and you're all done.
242-
243-
With CSP enabled, two header lines are added to the HTTP response: a **Content-Security-Policy** header, with
244-
policies identifying content types or origins that are explicitly allowed for different
245-
contexts, and a **Content-Security-Policy-Report-Only** header, which identifies content types
246-
or origins that will be allowed but which will also be reported to the destination
247-
of your choice.
248-
249-
Our implementation provides for a default treatment, changeable through the ``reportOnly()`` method.
250-
When an additional entry is added to a CSP directive, as shown below, it will be added
251-
to the CSP header appropriate for blocking or preventing. That can be overridden on a per
252-
call basis, by providing an optional second parameter to the adding method call.
253-
254-
Runtime Configuration
255-
---------------------
256-
257-
If your application needs to make changes at run-time, you can access the instance at ``$this->response->getCSP()`` in your controllers. The
258-
class holds a number of methods that map pretty clearly to the appropriate header value that you need to set.
259-
Examples are shown below, with different combinations of parameters, though all accept either a directive
260-
name or an array of them:
261-
262-
.. literalinclude:: response/012.php
263-
264-
The first parameter to each of the "add" methods is an appropriate string value,
265-
or an array of them.
266-
267-
The ``reportOnly()`` method allows you to specify the default reporting treatment
268-
for subsequent sources, unless over-ridden. For instance, you could specify
269-
that youtube.com was allowed, and then provide several allowed but reported sources:
270-
271-
.. literalinclude:: response/013.php
272-
273-
Inline Content
274-
--------------
275-
276-
It is possible to set a website to not protect even inline scripts and styles on its own pages, since this might have
277-
been the result of user-generated content. To protect against this, CSP allows you to specify a nonce within the
278-
``<style>`` and ``<script>`` tags, and to add those values to the response's header. This is a pain to handle in real
279-
life, and is most secure when generated on the fly. To make this simple, you can include a ``{csp-style-nonce}`` or
280-
``{csp-script-nonce}`` placeholder in the tag and it will be handled for you automatically::
281-
282-
// Original
283-
<script {csp-script-nonce}>
284-
console.log("Script won't run as it doesn't contain a nonce attribute");
285-
</script>
286-
287-
// Becomes
288-
<script nonce="Eskdikejidojdk978Ad8jf">
289-
console.log("Script won't run as it doesn't contain a nonce attribute");
290-
</script>
291-
292-
// OR
293-
<style {csp-style-nonce}>
294-
. . .
295-
</style>
296-
297-
.. warning:: If an attacker injects a string like ``<script {csp-script-nonce}>``, it might become the real nonce attribute with this functionality. You can customize the placeholder string with the ``$scriptNonceTag`` and ``$styleNonceTag`` properties in **app/Config/ContentSecurityPolicy.php**.
298-
299-
If you don't like this auto replacement functionality, you can turn it off with setting ``$autoNonce = false`` in **app/Config/ContentSecurityPolicy.php**.
300-
301-
In this case, you can use the functions, :php:func:`csp_script_nonce()` and :php:func:`csp_style_nonce()`::
302-
303-
// Original
304-
<script <?= csp_script_nonce() ?>>
305-
console.log("Script won't run as it doesn't contain a nonce attribute");
306-
</script>
307-
308-
// Becomes
309-
<script nonce="Eskdikejidojdk978Ad8jf">
310-
console.log("Script won't run as it doesn't contain a nonce attribute");
311-
</script>
312-
313-
// OR
314-
<style <?= csp_style_nonce() ?>>
315-
. . .
316-
</style>
317-
318202
Class Reference
319203
===============
320204

0 commit comments

Comments
 (0)