You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A Content Security Policy informs the client (browser) where your page loads resources from. Setting this can make your app more secure by declaring trusted sources for your resources. For more information, see the W3C recommendation [Content Security Policy Level 2](https://www.w3.org/TR/CSP2/).
324
+
A Content Security Policy (CSP) informs the client (browser) where your page loads resources from. Setting this can make your app more secure by declaring trusted sources for your resources. For more information, see the W3C recommendation [Content Security Policy Level 2](https://www.w3.org/TR/CSP2/).
325
+
326
+
{{% alert color="info" %}}
327
+
For complete CSP support, including nonce-based CSP, use the [Headers](/refguide/configuration/#headers) custom runtime setting instead of the HTTP Headers UI. For detailed implementation instructions, see [Content Security Policy](/howto/security/csp/).
328
+
{{% /alert %}}
325
329
326
330
The process for setting a full content security policy depends on what your app does. However, a starting point that declares the content security policy that works with a basic Mendix app is given below:
Copy file name to clipboardExpand all lines: content/en/docs/howto/security/csp.md
+164-2Lines changed: 164 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -174,6 +174,168 @@ After redeploying your app locally, it should function as normal. If your app do
174
174
175
175
After you finish testing locally, remember to remove the line of code in the `head` tag.
176
176
177
-
### Enabling the Header in the Cloud
177
+
## CSP Support in Java Request Handlers
178
178
179
-
To enable the header in the cloud, follow the instructions in the [HTTP Headers](/developerportal/deploy/environments-details/#http-headers) section of *Environment Details*.
179
+
When developing Marketplace modules or custom Java actions that include request handlers, you may need to implement CSP support to ensure compatibility with strict CSP policies. This includes support for CSP Level 2+ features such as nonces for inline scripts and styles.
180
+
181
+
{{% alert color="info" %}}
182
+
CSP support is only relevant for request handlers that serve static content such as HTML pages, not for API endpoints that return JSON or other data formats.
183
+
{{% /alert %}}
184
+
185
+
This section describes how to properly handle CSP headers in Java request handlers when serving HTML content.
186
+
187
+
### Available CSP APIs
188
+
189
+
Mendix provides two APIs to support CSP in Java request handlers:
190
+
191
+
#### IMxRuntimeResponse Methods
192
+
193
+
The `IMxRuntimeResponse` interface provides these basic CSP methods:
194
+
195
+
* `addContentSecurityPolicyHeader()` – Adds the Content-Security-Policy header as configured in the application
196
+
* `getNonce()` – Returns a secure, uniquely generated nonce for the response that you can use in CSP directives
197
+
* `addHeader(String key, String value)` – Adds a custom header to the response
198
+
199
+
#### CspHelper Interface (Recommended)
200
+
201
+
The `CspHelper` interface provides additional utility methods for more advanced CSP handling:
202
+
203
+
* `getTemplate()` – Gets the template used for the Content-Security-Policy header value
204
+
* `getNonce(IMxRuntimeResponse response)` – Gets the generated nonce of the current HTTP response
205
+
* `hasNonce(IMxRuntimeResponse response)` – Returns true if the configured CSP template contains the `{{ NONCE }}` placeholder. For example: `Content-Security-Policy: script-src 'nonce-{{ NONCE }}'`
206
+
* `addHeader(IMxRuntimeResponse response)` – Adds Content-Security-Policy header to the response using the configured template
207
+
208
+
### Example Implementation
209
+
210
+
Here's how to implement CSP support in a Java request handler using the `CspHelper` interface:
When implementing CSP support in your request handlers, follow these best practices:
279
+
280
+
***Use `CspHelper`for conditional nonce support** – Always check if nonce is configured before using it:
281
+
282
+
```java
283
+
if (Core.csp().hasNonce(response)) {
284
+
String nonce = Core.csp().getNonce(response);
285
+
// Use nonce for inline content
286
+
} else {
287
+
// Use external resources or alternative approach
288
+
}
289
+
```
290
+
291
+
***Always add CSP headers** – Use `Core.csp().addHeader(response)` to ensure your module respects the application's CSP configuration when serving HTML content.
292
+
293
+
* **CSP is only needed for HTML content** – Only implement CSP support in request handlers that serve HTML pages. API endpoints returning JSON, XML, or other data formats do not need CSP headers.
294
+
295
+
* **Avoid inline scripts and styles when possible** – Use external files that can be loaded via `'self'` directive.
296
+
297
+
* **Test with strict CSP** – Test your request handlers with `default-src: 'self'` to ensure they work with the strictest CSP settings.
298
+
299
+
### Common CSP Issues in Request Handlers
300
+
301
+
When working with CSP in request handlers, you may encounter these common issues:
302
+
303
+
#### Base64 Images
304
+
305
+
Strict CSP blocks inline Base64 images that your request handler generates. Consider these alternatives:
306
+
307
+
* Serve images as separate endpoints
308
+
* Use external image hosting
309
+
* Add `data:` to `img-src` directive (less secure)
310
+
311
+
#### Dynamic Script Generation
312
+
313
+
Avoid generating `<script>` tags dynamically without nonces. Instead:
314
+
315
+
* Use the provided nonce for any inline scripts
316
+
* Move logic to external JavaScript files
317
+
* Use data attributes and external scripts to handle dynamic behavior
318
+
319
+
#### Third-party Resources
320
+
321
+
If your module loads external resources, make sure they are allowed by the CSP or provide configuration options for developers to whitelist them.
322
+
323
+
#### Error Handling
324
+
325
+
When CSP violations occur, implement proper error handling:
326
+
327
+
```java
328
+
// Log CSP-related errors for debugging
329
+
if (Core.csp().hasNonce(response)) {
330
+
logger.debug("Using CSP with nonce: " + Core.csp().getNonce(response));
331
+
} else {
332
+
logger.debug("CSP configured without nonce support");
333
+
}
334
+
```
335
+
336
+
## Enabling the Header in the Cloud
337
+
338
+
There are two ways to enable the header in the cloud:
339
+
340
+
1. **[Headers](/refguide/configuration/#headers) custom runtime setting (Recommended)**: Use this if you need nonce-based CSP support. Configure this in the Developer Portal under [Custom Runtime Settings](/developerportal/deploy/environments-details/#custom-runtime-settings).
341
+
2. **HTTP Headers UI:** This method works for basic CSP support. For more details, refer to the [HTTP Headers](/developerportal/deploy/environments-details/#http-headers) section of *Environment Details*.
Copy file name to clipboardExpand all lines: content/en/docs/refguide/runtime/custom-settings/_index.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -72,6 +72,7 @@ The following custom settings can be configured:
72
72
| <aid="ScheduledEventExecution"href="#ScheduledEventExecution">ScheduledEventExecution</a> | Specify which scheduled events should be executed. Choices are `ALL`, `NONE`, or `SPECIFIED`. In the case of `SPECIFIED`, enumerate the scheduled events using the `MyScheduledEvents` configuration option described below. {{% alert color="warning" %}}This setting cannot be configured when running locally. To enable and disable scheduled events when running locally, please use the 'Enabled' setting on the [Scheduled Events execution properties](/refguide/scheduled-events/) in Studio Pro.{{% /alert %}} | NONE |
73
73
| <aid="SessionKeepAliveUpdatesInterval"href="#SessionKeepAliveUpdatesInterval">SessionKeepAliveUpdatesInterval</a> | Defines how often a runtime writes session LastActive dates in its memory back to the database. | one sixth of the value configured for the `SessionTimeout` setting; if the `SessionTimeout` is not set, this value defaults to 100000 (100 seconds) |
74
74
| <aid="SessionTimeout"href="#SessionTimeout">SessionTimeout</a> | Defines after how much time a session becomes invalid (in milliseconds). After that timeout, a session becomes eligible for removal. The session will not be destroyed until the next time a scheduled task runs to clean up the active sessions. <br> {{% alert color="warning" %}} Logging out can also be triggered by a query to the runtime after the session becomes eligible for removal. Navigating between pages is not enough to trigger a query to the runtime. To force a query to the runtime, use microflows. For example, create a microflow that shows the Home page, then configure your app's navigation to call this microflow rather than relying on the navigation to directly show the page itself. This will ensure the runtime is queried and the user is logged out of their session. {{% /alert %}} | 600000 (10 minutes) |
75
+
| <aid="Headers"href="#Headers">Headers</a> | A JSON object containing custom headers as key/value pairs, and can be used to define a `Content-Security-Policy`. For example, `{ "Content-Security-Policy": "script-src 'nonce-{{ NONCE }}'" }`. |`{}`|
75
76
| <aid="TaskQueueShutdownGracePeriod"href="#TaskQueueShutdownGracePeriod">TaskQueue.<wbr>ShutdownGracePeriod</a> | Time in ms to wait for task in a task queue to finish when shutting down. | 10000 (10 seconds) |
76
77
| <aid="TempPath"href="#TempPath">TempPath</a> | The location of the temporary files. |[deployment folder]\data\tmp |
77
78
| <aid="TrackWebServiceUserLastLogin"href="#TrackWebServiceUserLastLogin">TrackWebServiceUserLastLogin</a> | Defines whether to update a user's `LastLogin` field on each login when logging in to a published REST, OData, or web service. When this happens a database update query has to be sent and this can have performance consequences on heavy load systems. When this setting is set to false, no database interaction is necessary. | true |
0 commit comments