Content Security Policy
Introduction
By employing a content security policy (CSP) in your app, you can protect it from malicious content which might try to take advantage of the app’s trusted web page context. A rigorous CSP allows you to control which resources are loaded in the app.
A web app (including progressive web apps) can be made more strict and secure by setting its CSP to default-src: self
. By doing so, only resources from the same domain can be loaded and no resources can be loaded inline (such as Base64 images or inline JavaScript).
For more background information on CSPs, see Content Security Policy from Mozilla.
Setup
In order to be able to use the strictest setting of a CSP (default-src: self
) you must make some changes in your application. See the sections below for guidance.
Updating the Theme Folder
To upgrade your theme directory to latest version, complete the following steps:
- Rename your current theme directory. For example, you can use theme_backup as the new name.
- Download the new theme files from this GitHub link: theme.zip. Extract the downloaded file into the root of your Mendix app folder. The folder structure should be similar to the previous folder, (meaning the Mendix app root, then the theme, and then the web and native folders).
- After extracting the new theme files, restore your custom styling from the backup by copying over the new theme folder files. You will see the main changes enacted to make things compatible with strict CSP involve the
login.html
file and one JavaScript file for the toggled password.
Changing the Theme
Create a new file to contain the Dojo configuration in your theme folder (theme/web/appSetup.js) with the following configuration:
window.dojoConfig = {
// Default Dojo config
isDebug: false,
useCustomLogger: true,
async: true,
baseUrl: "mxclientsystem/dojo/",
cacheBust: "{{cachebust}}",
rtlDirect: "index-rtl.html",
// CSP Dojo config
has: {
"csp-restrictions": true
},
blankGif: "mxclientsystem/dojo/resources/blank.gif"
};
if (!document.cookie || !document.cookie.match(/(^|;) *originURI=/gi))
document.cookie = "originURI=/login.html" + (window.location.protocol === "https:" ? ";SameSite=None;Secure" : "");
Create a second file to contain the script for unsupported browsers (theme/web/unsupported-browser.js):
// Redirect to unsupported browser page if opened from browser that doesn't support Symbols
if (typeof Symbol !== "function") {
var homeUrl = window.location.origin + window.location.pathname;
var appUrl = homeUrl.slice(0, homeUrl.lastIndexOf("/") + 1);
window.location.replace(appUrl + "unsupported-browser.html");
}
Finally, the theme/web/index.html file needs to be changed to use these files directly. If you lack this file, please follow the Customizing index.html (Web) section of Customize Styling.
In theme/web/index.html do the following:
-
Remove the line with the
{{unsupportedbrowsers}}
tag -
Remove the
<script>
tag with thedojoConfig
inside -
At the top of the
<head
> tag, add a reference to theunsupported-browser.js
script:<html> <head> <script src="unsupported-browser.js"></script> ... </head> ... </html>
-
In the
<body>
tag, add a reference to theappSetup.js
script beforemxui.js
is loaded:<html> <body> ... <div id-"content"></div> <script src="appSetup.js"></script> <script src="mxclientsystem/mxui/mxui.js?{{cachebust}}"></script> </body> </html>
Lastly, ensure you are not using any external fonts by checking your theme’s styling to confirm all of the fonts are loaded locally.
Testing Your Changes Locally
To check that your changes are working locally, you can temporarily enforce the header by adding the following theme/web/index.html at the top of the <head>
tag:
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
</head>
</html>
After redeploying your app locally, it should function as normal. If your app does not load or if there are errors, check that you have completed all steps listed above.
After you finish testing locally, remember to remove the line of code in the head
tag.
Enabling the Header in the Cloud
To enable the header in the cloud, follow the instructions in the HTTP Headers section of Environment Details.