Package org.auraframework.http

Source Code of org.auraframework.http.AuraCSPFilter

/*
* Copyright (C) 2013 salesforce.com, inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.auraframework.http;

import java.io.IOException;
import java.util.Set;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.auraframework.http.CSP.PolicyBuilder;
import org.auraframework.util.javascript.directive.JavascriptGeneratorMode;

import com.google.common.collect.ImmutableSet;

/**
* Servlet filter for adding Content Security Policy headers,
* per the <a href="http://www.w3.org/TR/CSP/">W3C Content Security
* Policy 1.0 spec</a>.
*/
public class AuraCSPFilter implements Filter {
   
    /* TODO: try and get rid of these--see comments on doesUrlAllowInline() */
    private static final String APPLICATION = ".*\\.app";
    private static final String COMPONENT   = ".*\\.cmp";
    private static final String FRAMEWORK_JS= ".*/aura_" + getFrameworkJsSuffixRegex() + "\\.js";
   
    private static final Set<String> INLINE_ALLOWED_URLS = ImmutableSet.of(APPLICATION, COMPONENT, FRAMEWORK_JS);
   
    protected static final String CHROME_EXTENSION = "chrome-extension:";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
       
        // set the policy to only report--not disallow--violations
        if (response.getHeader(CSP.Header.REPORT_ONLY) == null) {
            /*
             * only set header if not already set--important because Aura request URIs get rewritten
             * and run through here multiple times, and we must use the client's (first) version of the URI
             * to choose our policy
             */
            response.setHeader(CSP.Header.REPORT_ONLY, getPolicy(request.getRequestURI()));
        }
       
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {}
   
    @Override
    public void destroy() {}
   
    protected String getPolicy(String url) {
        PolicyBuilder p = new PolicyBuilder();
        p.connect_src(CSP.SELF)
            .default_src(CSP.SELF)
            .img_src(CSP.ALL)
            .font_src(CSP.ALL)
            .report_uri(CSPReporterServlet.URL);
       
        // note that chrome-extensions can cause violations, and we don't generally care.
        if (doesUrlAllowInline(url)) {
            p.script_src(CSP.SELF, CHROME_EXTENSION, CSP.UNSAFE_EVAL, CSP.UNSAFE_INLINE)
                .style_src(CSP.SELF, CHROME_EXTENSION, CSP.UNSAFE_INLINE);
        } else {
            p.script_src(CSP.SELF, CHROME_EXTENSION)
                .style_src(CSP.SELF, CHROME_EXTENSION);
        }
       
        return p.build();
    }
   
    /*
     * This is a (hopefully) temporary solution.
     *
     * As the names imply, CSP strongly discourages use of unsafe-eval and unsafe-inline,
     * but parts of the Aura client depend on inlining, in particular the initial page template,
     * and fixing this the last week of feature development is scary.
     *
     * NOTE: this should be fixed sooner rather than later, because the initial template *is*
     * configurable by consumers, and is therefore a vector for attack.
     */
    protected final boolean doesUrlAllowInline(String url) {
        for (String pattern : INLINE_ALLOWED_URLS) {
            if (url.matches(pattern)) {
                return true;
            }
        }
       
        return false;
    }
   
    private static String getFrameworkJsSuffixRegex() {
        StringBuilder sb = new StringBuilder();
        sb.append("(");
        boolean first = true;
        for (String suffix : JavascriptGeneratorMode.getSuffixes()) {
            if (!first) {
                sb.append("|");
            }
            sb.append(suffix);
           
            first = false;
        }
        sb.append(")");
       
        return sb.toString();
    }
}
TOP

Related Classes of org.auraframework.http.AuraCSPFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.