Content Security Policy Library
This library enables you to implement a Content Security Policy on your site. A CSP is one of the best protective measures that can reduce the risk of content injection attacks, such as Cross Site Scripting (XSS). The CSP library generates two headers:
- a Content-Security-Policy HTTP header, which contains directives that whitelist domains from which the browser is allowed to load resources, including images, stylesheets, javascript files, etc. The browser will block loading resources from somewhere that isn't on this whitelist.
- a Content-Security-Policy-Report-Only HTTP header that works just like the CSP header, but it only reports on violations of the policy without blocking restricted resources.
Both headers are sent at the same time, enforcing policies while monitoring others if needed.
For more information, you should visit the following sites:
https://content-security-policy.com/
https://www.w3.org/TR/CSP
https://www.sitepoint.com/improving-web-security-with-the-content-security-policy/
Initializing the Library
The Content Security Policy Library is initialized in your controller like most other libraries in revIgniter using the rigLoaderLoadLibrary handler:
rigLoaderLoadLibrary "Contentsecuritypolicy"
Note: This library needs to be loaded before the "ASYNergy" library and before the "Pagination" library if you load one or both of them additionally.
Setting CSP Directives
Setting Directives Manually
Note: Many directives have default values/keywords that will be used if you do not set them. See the Directives table below. If no changes are needed the default Content-Security-Policy header is sent and you're all done just by loading the library.
Directives are set during runtime by passing a single value/keyword, multiple values/keywords or an array that sets multiple directives at once to the library, like in the following examples (please note the single quotes used for keywords):
# SET A DIRECTIVE USING A SINGLE VALUE/KEYWORD
rigCspSet "script-src", "'none'"
# SET A DIRECTIVE USING MULTIPLE VALUES/KEYWORDS
rigCspSet "style-src", "'self' css.example.com"
# SET MULTIPLE DIRECTIVES USING AN ARRAY
put "'self' css.example.com" into tCspA["style-src"]
put "'none'" into tCspA["script-src"]
rigCspSet tCspA
Adding Values/Keywords to Directives Manually
You can add values/keywords to directives like in the following example:
# ADD A SINGLE VALUE/KEYWORD TO A DIRECTIVE
rigCspAdd "style-src", "css.example.com"
# Add MULTIPLE VALUES/KEYWORDS TO A DIRECTIVE
rigCspAdd "style-src", "'unsafe-inline' css.example.com"
# ADD VALUES/KEYWORDS TO MULTIPLE DIRECTIVES USING AN ARRAY
put "'self' script.example.com" into tCspA["script-src"]
put "'unsafe-inline'" into tCspA["style-src"]
rigCspAdd tCspA
Note: If a directive already includes a specific value/keyword, the assignment will be ignored.
Reporting
You can instruct the browser to send (POST) JSON-formatted violation reports to a location specified in a report-uri directive. Example:
# SET A REPORT URI
rigCspSet "report-uri", "report.example.com/myparser"
To ask the browser to monitor a policy, reporting violations but not enforcing the restrictions, you can set the third parameter to "report". Valid values are "allow" and "report", the default value is "allow". If the third parameter is set to "report" directives are set in the whitelist of the Content-Security-Policy-Report-Only HTTP header. Example:
# IF DIRECTIVE IS VIOLATED SEND A REPORT WITHOUT BLOCKING
rigCspSet "report-uri", "report.example.com/myparser", "report"
rigCspSet "style-src", "'self' css.example.com", "report"
Setting Directives in a Config File
If you prefer not to set directives using the above method, you can instead store them in a config file. Simply create a new file called contentSecurityPolicy.lc and add the Config array in that file. At the end of the file write: rigRunInitialContentsecuritypolicyConfig yourArrayVariableName. Then save the file at config/contentSecurityPolicy.lc and it will be used automatically. Example:
local sDirectivesA
put TRUE into sDirectivesA["upgrade-insecure-requests"]
put "media.example.com" into sDirectivesA["media-src"]
put "'unsafe-inline' css.example.com" into sDirectivesA["style-src"]
rigRunInitialContentsecuritypolicyConfig sDirectivesA
To report violations without enforcing restrictions you can set the "report-only" directive to true like in the following example:
local sDirectivesA
put TRUE into sDirectivesA["report-only"]
put TRUE into sDirectivesA["upgrade-insecure-requests"]
put "media.example.com" into sDirectivesA["media-src"]
put "'unsafe-inline' css.example.com" into sDirectivesA["style-src"]
rigRunInitialContentsecuritypolicyConfig sDirectivesA
Directives
The following directives/settings are available. The default value, if available any, indicates what will be used if you do not specify that directive.
Preference | Default Value | Options | Description |
---|---|---|---|
omit-script-nonce | false | false, true | Flag to prevent automatic insertion of a script source nonce value into the CSP header, 'unsafe-inline' is ignored if a nonce value is present in the source list |
omit-style-nonce | false | false, true | Flag to prevent automatic insertion of a style source nonce value into the CSP header, 'unsafe-inline' is ignored if a nonce value is present in the source list |
report-only | false | false, true | Flag for report only policy |
report-uri | No Default | None | The URI where a browser will send reports when a content security policy is violated |
upgrade-insecure-requests | false | false, true | Rewrite URL schemes, changes HTTP to HTTPS |
default-src | 'self' | Any valid value/keyword | Default policy for fetching resources |
script-src | 'self' | Any valid value/keyword | Defines valid sources of JavaScript |
style-src | 'self' | Any valid value/keyword | Defines valid sources of stylesheets or CSS |
img-src | 'self' | Any valid value/keyword | Defines the origins from which images can be loaded |
base-uri | 'self' | None | Restricts the URLs that can be used in the src attribute of a HTML base tag |
child-src | 'self' | Any valid value/keyword | Lists the URLs for workers and embedded frame contents |
connect-src | 'self' | Any valid value/keyword | Limits the origins that you can connect to (via XHR, WebSockets, and EventSource) |
font-src | No Default | Any valid value/keyword | Specifies the origins that can serve web fonts |
form-action | 'self' | Any valid value/keyword | Lists valid endpoints for submission from <form> tags |
frame-ancestors | No Default | Any valid value/keyword | Specifies the sources that can embed the current page |
media-src | No Default | Any valid value/keyword | Restricts the origins allowed to deliver video and audio |
object-src | 'self' | Any valid value/keyword | Allows control over Flash and other plugins |
manifest-src | No Default | Any valid value/keyword | Restricts the URLs that application manifests can be loaded |
plugin-types | No Default | None | Defines valid MIME types for plugins invoked via <object> and <embed> |
sandbox | No Default | None | Enables a sandbox for the requested resource similar to the iframe sandbox attribute |
Using a Nonce to Protect Inline Styles and Scripts
A nonce (a number used once) is just a random string generated by the CSP library. When included in the CSP header, an inline script or inline CSS can be executed if the script or style tag contains a nonce attribute that matches the nonce specified in the CSP header. Nonces are automatically generated if you add
"{{g_ScriptNonce_}}" or "{{g_StyleNonce_}}" respectively to the script tag or style tag in question. These placeholders will be replaced during runtime with the generated nonce. Examples:
<style {{g_StyleNonce_}}>
body {
margin: 40px;
padding: 0;
background-color: #fff;
}
</style>
<script {{g_ScriptNonce_}}>
console.log("Script will run if it contains a nonce attribute");
</script>
Note: There are inline scripts (JavaScript) and inline CSS generated dynamically by various revIgniter libraries. Using the CSP library nonces are automatically attached to these script or style tags.
Handler Reference
rigCspSet pDirective, pValue, pMode
Setter for content security policy directives.
Parameters
- pDirective: A valid CSP directive or an array of directives.
- pValue: Keywords or other options. This parameter is redundant if the first parameter is an array.
- pMode: A boolean to specify the HTTP header (either Content-Security-Policy or Content-Security-Policy-Report-Only) where the directives are to be written. This parameter is optional. Valid values are "allow" and "report", the default value is "allow".
Examples:
rigCspSet "upgrade-insecure-requests", TRUE, "report"
put "'unsafe-inline' 'unsafe-eval'" into tCspA["script-src"] # PLEASE DON'T
put "'unsafe-inline'" into tCspA["style-src"]
rigCspSet tCspA
rigCspAdd pDirective, pValue, pMode
Add options to content security policy directives.
Parameters
- pDirective: A valid CSP directive or an array of directives.
- pValue: Keywords or other options. This parameter is redundant if the first parameter is an array.
- pMode: A boolean to specify the HTTP header (either Content-Security-Policy or Content-Security-Policy-Report-Only) where the directives are to be written. This parameter is optional. Valid values are "allow" and "report", the default value is "allow".
If a directive already includes a specific value/keyword, the assignment will be ignored.
Examples:
rigCspAdd "style-src", "'unsafe-inline' css.example.com"
put "js.example.com" into tCspA["script-src"]
put "'unsafe-inline' css.example.com" into tCspA["style-src"]
rigCspAdd tCspA
rigCspGet( pDirective, pMode )
Get options of content security policy directives included in the CSP HTTP header. You will probably rarely need this function.
Parameters
- pDirective: A valid CSP directive.
- pMode: This optional parameter specifies the whitelist (standard or report only) the options should fetched from. Valid values are "allow" or "report", default is "allow".
Example:
put rigCspGet("script-src", "report") into tScriptSrcOptions