diff --git a/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md b/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md index c994594dd29..7add31038c8 100644 --- a/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md +++ b/content/en/docs/deployment/mendix-cloud-deploy/environments-details.md @@ -323,6 +323,10 @@ document.cookie = "originURI=/login.html" + (window.location.protocol === "https 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/). +{{% alert color="info" %}} +For full CSP support including nonce-based CSP, use the [Headers](/refguide/configuration/#headers) custom runtime setting instead of the HTTP Headers UI. The custom runtime setting method is recommended as it provides more comprehensive CSP capabilities. For detailed implementation guidance, see [Content Security Policy](/howto/security/csp/). +{{% /alert %}} + 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: ```text diff --git a/content/en/docs/howto/security/csp.md b/content/en/docs/howto/security/csp.md index 10fb173ebf6..133ee695eef 100644 --- a/content/en/docs/howto/security/csp.md +++ b/content/en/docs/howto/security/csp.md @@ -174,6 +174,160 @@ After redeploying your app locally, it should function as normal. If your app do After you finish testing locally, remember to remove the line of code in the `head` tag. -### Enabling the Header in the Cloud +## CSP Support in Java Request Handlers -To enable the header in the cloud, follow the instructions in the [HTTP Headers](/developerportal/deploy/environments-details/#http-headers) section of *Environment Details*. +If you are 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 like nonces for inline scripts and styles. + +{{% alert color="info" %}} +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. +{{% /alert %}} + +This section describes how to properly handle CSP headers in your Java request handlers when serving HTML content. + +### Available CSP APIs + +Mendix provides two APIs for CSP support in Java request handlers: + +#### IMxRuntimeResponse Methods + +The `IMxRuntimeResponse` interface provides basic CSP methods: + +* `addContentSecurityPolicyHeader()` - Adds the Content-Security-Policy header as configured in the application +* `getNonce()` - Returns a uniquely generated secure nonce for the response that can be used in CSP directives +* `addHeader(String key, String value)` - Adds a custom header to the response + +#### CspHelper Interface (Recommended) + +The `CspHelper` interface provides additional utility methods for more sophisticated CSP handling: + +* `getTemplate()` - Get the template used for the Content-Security-Policy header value +* `getNonce(IMxRuntimeResponse response)` - Get the generated nonce of the current HTTP response +* `hasNonce(IMxRuntimeResponse response)` - Returns true if the configured CSP template contains the `{{ NONCE }}` placeholder, for example: `Content-Security-Policy: script-src 'nonce-{{ NONCE }}'` +* `addHeader(IMxRuntimeResponse response)` - Add Content-Security-Policy header to the response using the configured template + +### Example Implementation + +Here's how to implement CSP support in a Java request handler using the `CspHelper`: + +```java +package your.module.requesthandlers; + +import com.mendix.externalinterface.connector.RequestHandler; +import com.mendix.m2ee.api.IMxRuntimeRequest; +import com.mendix.m2ee.api.IMxRuntimeResponse; +import com.mendix.http.CspHelper; +import com.mendix.core.Core; + +public class YourRequestHandler extends RequestHandler { + + @Override + protected void processRequest(IMxRuntimeRequest request, IMxRuntimeResponse response, String path) throws Exception { + try { + // Add the configured CSP header from the application + Core.csp().addHeader(response); + + // Set response content type + response.setContentType("text/html"); + + // Generate your response content with conditional nonce support + String htmlContent = generateHtmlWithCSP(response); + + // Write the response + response.getWriter().write(htmlContent); + + } catch (Exception e) { + logger.error("Error processing request: " + e.getMessage(), e); + response.setStatus(IMxRuntimeResponse.INTERNAL_SERVER_ERROR); + response.sendError("Internal server error"); + } + } + + private String generateHtmlWithCSP(IMxRuntimeResponse response) { + StringBuilder html = new StringBuilder(); + html.append("\n"); + html.append("\n"); + html.append("
\n"); + html.append("