Content Security Policy"

From Documentation
Line 1: Line 1:
{{ZKDevelopersReferencePageHeader}}
+
= What is Content security policy?=
= Overview =
+
Content-security-policy (CSP) is a security mechanism which helps web applications to prevent XSS attacks (cross-site scripting) and other content injection attacks.
Content-security-policy (CSP) is a security standard which helps to prevent XSS attacks (cross-site scripting) and other content injection attacks.
+
 
 +
To reduce those injection risks, CSP declares permissions to load script from specific, trusted sources.
 
We could configure our web server to return the CSP HTTP header, or use <meta> element.
 
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.
 
  
 
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 that not all the browsers support CSP.
 
+
(Support browsers: [https://caniuse.com/#feat=contentsecuritypolicy Content Security Policy 1.0], [https://caniuse.com/#feat=contentsecuritypolicy2 Content Security Policy Level 2])
1. CSP blocks the use of the inline <script> source.
 
 
 
There are several inline scripts created and removed immediately during the ZK page initialization.
 
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.
+
There are several "directive" recommended to be defined, which is in order to protect against XSS attacks.
  
It is necessary for ZK, because ZK evaluates the returned JSON like JS object from almost every AU response.
+
1. default-src
  
3.CSP blocks the use of the inline source in style attribute by default.
+
The default-src is the default policy for loading content such as Javascript, CSS, fonts, etc. .
  
To achieve the dimension or size calculation in ZK components, changing the style of DOM elements is necessary.
+
2. script-src / style-src / img-src / font-src
  
4.(Optional) Iframe and WebSocket issue
+
Defines valid sources of JavaScript/stylesheets/images/fonts.
  
Iframe-src is currently needed for file upload and download.
+
3. connect-src
  
If we want to use WebSocket in ZK, we need to specify the connection URL of WebSocket.
+
Applies to AJAX, WebSocket or EventSource.
  
'''Implementation'''
+
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'''
+
== Use Content security policy in ZK==
<source lang="java">
+
CSP is not fully supported in ZK, because we still need to use some 'unsafe-eval' and 'unsafe-inline' declaration when loading scripts and CSS from ZK.
public class CspPageRenderer extends PageRenderer implements Initiator {
+
Which means that there still are risks when attackers use eval() script or inline scripts.
  
public static final String SCRIPT_START = "<script class=\"z-runonce\" type=\"text/javascript\">";
+
But you can still use CSP in ZK by declaring the following directives.
public static final String SCRIPT_END = "</script>";
+
'''Example'''
 
+
<source lang="xml">
@Override
+
<?header name="Content-Security-Policy-Report-Only"
public void doInit(Page page, Map<String, Object> args) throws Exception {
+
    value="default-src 'none'; script-src 'self' 'unsafe-eval'; frame-src 'self'; connect-src 'self' ws://your.server.name:8080/;
Executions.getCurrent().setAttribute(PAGE_RENDERER, this);
+
    img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self';" ?>
}
 
 
 
@Override
 
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>
 
 
 
'''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>
 
</source>
 
=Version History=
 
{{LastUpdated}}
 
{| border='1px' | width="100%"
 
! Version !! Date !! Content
 
|-
 
| &nbsp;
 
| &nbsp;
 
| &nbsp;
 
|}
 
 
{{ZKDevelopersReferencePageFooter}}
 

Revision as of 10:52, 21 March 2018

What is Content security policy?

Content-security-policy (CSP) is a security mechanism which helps web applications to prevent XSS attacks (cross-site scripting) and other content injection attacks.

To reduce those injection risks, CSP declares permissions to load script from specific, trusted sources. We could configure our web server to return the CSP HTTP header, or use <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 that not all the browsers support CSP. (Support browsers: Content Security Policy 1.0, Content Security Policy Level 2)

There are several "directive" recommended to be defined, which is in order to protect against XSS attacks.

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;

Use Content security policy in ZK

CSP is not fully supported in ZK, because we still need to use some 'unsafe-eval' and 'unsafe-inline' declaration when loading scripts and CSS from ZK. Which means that there still are risks when attackers use eval() script or inline scripts.

But you can still use CSP in ZK by declaring the following directives. Example

<?header name="Content-Security-Policy-Report-Only"
    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';" ?>