Content Security Policy"

From Documentation
m (remove empty version history (via JWB))
 
(29 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
= Overview =
+
 
Content-security-policy (CSP) is a security standard which helps to prevent XSS attacks (cross-site scripting) and other content injection attacks.
+
 
We could configure our web server to return the CSP HTTP header, or use <meta> element.
+
 
After CSP is enabled, it would restrict contents that could be loaded from.
+
= What is Content security policy?=
 +
Content-security-policy (CSP) is a security standard introduced to prevent XSS attacks (cross-site scripting) and other content injection attacks.
 +
 
 +
To reduce those injection risks, CSP provides a way for web applications and website owners to declare permissions for loading scripts from only approved and trusted sources.
 +
To enable CSP, you can either configure your web server to return the CSP HTTP header, or use the <meta> element.
  
 
See more: [https://www.w3.org/TR/CSP2/ Content Security Policy Level 2]
 
See more: [https://www.w3.org/TR/CSP2/ Content Security Policy Level 2]
  
== CSP Implementations and limitations in ZK==
+
= How to use Content security policy? =
To implement CSP, there are several issues in ZK according to the CSP spec.
+
To use CSP in your web application, the first thing you need to know is that not all the browsers support CSP.
  
1. CSP blocks the use of the inline <script> source.
+
(Support browsers: [https://caniuse.com/#feat=contentsecuritypolicy Content Security Policy 1.0], [https://caniuse.com/#feat=contentsecuritypolicy2 Content Security Policy Level 2])
  
There are several inline scripts created and removed immediately during the ZK page initialization.
+
To enable CSP, you can either configure your web server to return the CSP HTTP header, or use the <meta> element. The following "directives" are recommended to be defined, which is for protecting against XSS attacks. For complete information please reference [https://www.w3.org/TR/CSP/ CSP official documents].
Attached a custom PageRenderer and AuExtension which allows removing the script-src 'unsafe-inline' policy.
 
  
2. CSP blocks the use of eval() and new Function() in javascript.
+
== 1. default-src ==
  
It is necessary for ZK, because ZK evaluates the returned JSON like JS object from almost every AU response.
+
The default-src is the default policy for loading content such as Javascript, CSS, fonts, etc.
  
3.CSP blocks the use of the inline source in style attribute by default.
+
== 2. script-src / style-src / img-src / font-src ==
  
To achieve the dimension or size calculation in ZK components, changing the style of DOM elements is necessary.
+
Defines valid sources of JavaScript/stylesheets/images/fonts.
  
4.(Optional) Iframe and WebSocket issue
+
== 3. connect-src ==
  
Iframe-src is currently needed for file upload and download.
+
Applies to AJAX, WebSocket or EventSource.
  
If we want to use WebSocket in ZK, we need to specify the connection of WebSocket URL.
+
== 4. child-src ==
  
To avoid all those errors the policies would need to be loosened like that:
+
Governs the creation of nested browsing contexts as well as Worker execution contexts.
  
 +
'''Examples'''
 +
 +
1. Only allows loading resources from the same origin.
 
<source lang="xml">
 
<source lang="xml">
<?header name="Content-Security-Policy-Report-Only"
+
default-src 'self';
    value="default-src 'none';
 
    script-src 'self' 'unsafe-eval';
 
    frame-src 'self'; connect-src 'self' ws://your.server.name:8080/;
 
    img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self';" ?>
 
 
</source>
 
</source>
  
'''Custom setting of PageRenderer and AuExtension'''
+
2. Allows loading scripts from the same origin and Google Analytics.
 
<source lang="xml">
 
<source lang="xml">
<listener>
+
script-src 'self' www.google-analytics.com;
<listener-class>zk.custom.AuCsp</listener-class>
 
</listener>
 
<listener>
 
<listener-class>zk.custom.CspPageRenderer</listener-class>
 
</listener>
 
 
</source>
 
</source>
  
'''Custom PageRenderer'''
+
= Using Content Security Policy in ZK=
<source lang="java">
+
We don't suggest applying too strict CSP to ZK, because internally ZK still needs to use some 'unsafe-eval' and 'unsafe-inline' declarations when loading scripts and CSS files. However, you can still use CSP in ZK to enhance supported parts and make your application safer than before. Here's an example of a relaxed policy used in a ZK application:
public class CspPageRenderer extends PageRenderer implements Initiator {
 
  
public static final String SCRIPT_START = "<script class=\"z-runonce\" type=\"text/javascript\">";
+
<source lang="xml">
public static final String SCRIPT_END = "</script>";
+
<?header name="Content-Security-Policy-Report-Only"
 
+
value="default-src 'none';
@Override
+
script-src 'self' 'unsafe-inline' 'unsafe-eval';
public void doInit(Page page, Map<String, Object> args) throws Exception {
+
frame-src 'self';
Executions.getCurrent().setAttribute(PAGE_RENDERER, this);
+
connect-src 'self' ws://your.server.name:8080/;
}
+
img-src 'self';
 
+
style-src 'self' 'unsafe-inline';
@Override
+
font-src 'self'" ?>
protected void renderDesktop(Execution exec, Page page, Writer out) throws IOException {
 
StringBuilder renderBuffer = renderDesktopToBuffer(exec, page);
 
 
 
int begin = renderBuffer.indexOf(SCRIPT_START);
 
int beginAfterTag = begin + SCRIPT_START.length();
 
int end = renderBuffer.indexOf(SCRIPT_END, begin);
 
int endAfterTag = end + SCRIPT_END.length();
 
 
 
String desktopRenderScript = renderBuffer.substring(beginAfterTag, end);
 
String desktopRenderScriptUrl = AuCsp.createUrlForDesktopRenderScript(page.getDesktop(), desktopRenderScript);
 
 
 
out.write(renderBuffer.substring(0, begin));
 
out.write("<script class=\"z-runonce\" src=\"" + desktopRenderScriptUrl + "\"></script>");
 
out.write(renderBuffer.substring(endAfterTag));
 
}
 
 
 
private StringBuilder renderDesktopToBuffer(Execution exec, Page page) throws IOException {
 
StringBuilder sb = new StringBuilder();
 
StringBuilderWriter outBuffer = new StringBuilderWriter(sb);
 
 
 
//render to a buffer first
 
super.renderDesktop(exec, page, outBuffer);
 
return sb;
 
}
 
}
 
 
</source>
 
</source>
 +
* Using [https://www.zkoss.org/wiki/ZUML_Reference/ZUML/Processing_Instructions/header <?header ?>] to specify a response header.
  
'''Custom AuExtension'''
 
<source lang="java">
 
public class AuCsp implements AuExtension, WebAppInit {
 
private static final Logger log = LoggerFactory.getLogger(AuRedirect.class);
 
 
public static final String DESKTOP_RENDER_SCRIPT = "desktopRenderScript";
 
public static final String URI_PREFIX = "/desktopRender";
 
 
@Override
 
public void init(WebApp wapp) throws Exception {
 
if (DHtmlUpdateServlet.getAuExtension(wapp, URI_PREFIX) == null) {
 
try {
 
DHtmlUpdateServlet.addAuExtension(wapp, URI_PREFIX, this);
 
} catch (Throwable ex) {
 
log.error("could not initialize AuCsp extension", ex);
 
throw new IllegalStateException("could not initialize AuCsp extension", ex);
 
}
 
}
 
}
 
 
@Override
 
public void init(DHtmlUpdateServlet servlet) throws ServletException {
 
}
 
 
@Override
 
public void destroy() {
 
}
 
 
@Override
 
public void service(HttpServletRequest request, HttpServletResponse response, String pi)
 
throws ServletException, IOException {
 
DesktopCache desktopCache = ((SessionCtrl) Sessions.getCurrent()).getDesktopCache();
 
Desktop desktop = desktopCache.getDesktop(pi.substring(URI_PREFIX.length() + 1));
 
response.getWriter().write(String.valueOf(desktop.removeAttribute(DESKTOP_RENDER_SCRIPT)));
 
}
 
 
public static String createUrlForDesktopRenderScript(Desktop desktop, String desktopRenderScript) {
 
desktop.setAttribute(DESKTOP_RENDER_SCRIPT, desktopRenderScript);
 
return desktop.getUpdateURI(URI_PREFIX + "/" + desktop.getId());
 
}
 
}
 
</source>
 
  
=Version History=
 
{{LastUpdated}}
 
{| border='1px' | width="100%"
 
! Version !! Date !! Content
 
|-
 
| &nbsp;
 
| &nbsp;
 
| &nbsp;
 
|}
 
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 10:24, 5 February 2024


Content Security Policy




What is Content security policy?

Content-security-policy (CSP) is a security standard introduced to prevent XSS attacks (cross-site scripting) and other content injection attacks.

To reduce those injection risks, CSP provides a way for web applications and website owners to declare permissions for loading scripts from only approved and trusted sources. To enable CSP, you can either configure your web server to return the CSP HTTP header, or use the <meta> element.

See more: Content Security Policy Level 2

How to use Content security policy?

To use CSP in your web application, the first thing you need to know is that not all the browsers support CSP.

(Support browsers: Content Security Policy 1.0, Content Security Policy Level 2)

To enable CSP, you can either configure your web server to return the CSP HTTP header, or use the <meta> element. The following "directives" are recommended to be defined, which is for protecting against XSS attacks. For complete information please reference CSP official documents.

1. default-src

The default-src is the default policy for loading content such as Javascript, CSS, fonts, etc.

2. script-src / style-src / img-src / font-src

Defines valid sources of JavaScript/stylesheets/images/fonts.

3. connect-src

Applies to AJAX, WebSocket or EventSource.

4. child-src

Governs the creation of nested browsing contexts as well as Worker execution contexts.

Examples

1. Only allows loading resources from the same origin.

default-src 'self';

2. Allows loading scripts from the same origin and Google Analytics.

script-src 'self' www.google-analytics.com;

Using Content Security Policy in ZK

We don't suggest applying too strict CSP to ZK, because internally ZK still needs to use some 'unsafe-eval' and 'unsafe-inline' declarations when loading scripts and CSS files. However, you can still use CSP in ZK to enhance supported parts and make your application safer than before. Here's an example of a relaxed policy used in a ZK application:

<?header name="Content-Security-Policy-Report-Only"
		value="default-src 'none';
		script-src 'self' 'unsafe-inline' 'unsafe-eval';
		frame-src 'self';
		connect-src 'self' ws://your.server.name:8080/;
		img-src 'self';
		style-src 'self' 'unsafe-inline';
		font-src 'self'" ?>




Last Update : 2024/02/05

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.