Search in sources :

Example 1 with ContentSecurityPolicyConfig

use of org.sablo.security.ContentSecurityPolicyConfig in project servoy-client by Servoy.

the class AngularIndexPageWriter method writeIndexPage.

public static void writeIndexPage(String page, HttpServletRequest request, HttpServletResponse response, String solutionName, String contentSecurityPolicyNonce) throws IOException, ServletException {
    if (request.getCharacterEncoding() == null)
        request.setCharacterEncoding("UTF8");
    String uri = request.getRequestURI();
    String clientnr = getClientNr(uri, request);
    Pair<FlattenedSolution, Boolean> pair = getFlattenedSolution(solutionName, clientnr, request, response);
    FlattenedSolution fs = pair.getLeft();
    if (fs != null) {
        StringBuilder sb = new StringBuilder(756);
        String indexHtml = page;
        final String path = Settings.getInstance().getProperty("servoy.context.path", request.getContextPath() + '/');
        sb.append("<base href=\"");
        sb.append(path);
        sb.append("\">");
        ContentSecurityPolicyConfig contentSecurityPolicyConfig = getContentSecurityPolicyConfig(request);
        if (contentSecurityPolicyNonce != null) {
            indexHtml = indexHtml.replace("<script ", "<script nonce='" + contentSecurityPolicyNonce + '\'');
        }
        String titleText = fs.getSolution().getTitleText();
        if (StringUtils.isBlank(titleText)) {
            titleText = fs.getSolution().getName();
        } else if (titleText.equals("<empty>") || titleText.contains("i18n:") || titleText.contains(TagParser.TAGCHAR)) {
            titleText = "";
        }
        sb.append("\n  <title>");
        sb.append(titleText);
        sb.append("</title>");
        if (fs.getMedia("manifest.json") != null) {
            String url = "resources/" + FLATTENED_SOLUTION_ACCESS + "/" + fs.getName() + "/manifest.json";
            sb.append("\n  <link rel=\"manifest\" href=\"");
            sb.append(url);
            sb.append("\">");
        }
        Media headExtension = fs.getMedia("head-index-contributions.html");
        if (headExtension != null) {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(headExtension.getMediaData()), "UTF8"))) {
                String line;
                for (int count = 0; count < 1000 && (line = reader.readLine()) != null; count++) {
                    if (line.trim().startsWith("<meta") || line.trim().startsWith("<link")) {
                        sb.append("\n  ");
                        sb.append(line);
                    }
                }
            } catch (Exception e) {
                Debug.error(e);
            }
        }
        sb.append("\n  <script ");
        if (contentSecurityPolicyConfig != null) {
            sb.append("nonce='");
            sb.append(contentSecurityPolicyConfig.getNonce());
            sb.append("' ");
        }
        sb.append("src=\"solution/");
        sb.append(solutionName);
        sb.append('/');
        sb.append(clientnr);
        sb.append("/main/startup.js?");
        sb.append(HTTPUtils.generateQueryString(request.getParameterMap(), request.getCharacterEncoding()));
        sb.append("\"></script>");
        indexHtml = indexHtml.replace("<base href=\"/\">", sb.toString());
        String requestLanguage = request.getHeader("accept-language");
        if (requestLanguage != null) {
            indexHtml = indexHtml.replace("lang=\"en\"", "lang=\"" + request.getLocale().getLanguage() + "\"");
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html");
        response.setContentLengthLong(indexHtml.length());
        response.getWriter().write(indexHtml);
        if (pair.getRight().booleanValue())
            fs.close(null);
    }
    return;
}
Also used : InputStreamReader(java.io.InputStreamReader) ByteArrayInputStream(java.io.ByteArrayInputStream) Media(com.servoy.j2db.persistence.Media) BufferedReader(java.io.BufferedReader) FlattenedSolution(com.servoy.j2db.FlattenedSolution) Utils.getAsBoolean(com.servoy.j2db.util.Utils.getAsBoolean) ContentSecurityPolicyConfig(org.sablo.security.ContentSecurityPolicyConfig) ServletException(javax.servlet.ServletException) JSONException(org.json.JSONException) IOException(java.io.IOException)

Example 2 with ContentSecurityPolicyConfig

use of org.sablo.security.ContentSecurityPolicyConfig in project servoy-client by Servoy.

the class AngularIndexPageWriter method getContentSecurityPolicyConfig.

/**
 * Get the ContentSecurityPolicyConfig is it should be applied, otherwise return null;
 *
 * Only when configured and when the browser is a modern browser that supports Content-Security-Policy level 3.
 */
private static ContentSecurityPolicyConfig getContentSecurityPolicyConfig(HttpServletRequest request) {
    Settings settings = Settings.getInstance();
    if (!getAsBoolean(settings.getProperty("servoy.ngclient.setContentSecurityPolicyHeader", "true"))) {
        Debug.trace("ContentSecurityPolicyHeader is disabled by configuration");
        return null;
    }
    String userAgentHeader = request.getHeader("user-agent");
    if (!HCUtils.supportsContentSecurityPolicyLevel3(userAgentHeader)) {
        if (Debug.tracing()) {
            Debug.trace("ContentSecurityPolicyHeader is disabled, user agent '" + userAgentHeader + "' does not support ContentSecurityPolicy level 3");
        }
        return null;
    }
    ContentSecurityPolicyConfig contentSecurityPolicyConfig = new ContentSecurityPolicyConfig(HTTPUtils.getNonce(request));
    // Overridable directives
    setDirectiveOverride(contentSecurityPolicyConfig, "frame-src", settings);
    setDirectiveOverride(contentSecurityPolicyConfig, "frame-ancestors", settings);
    setDirectiveOverride(contentSecurityPolicyConfig, "style-src", settings);
    setDirectiveOverride(contentSecurityPolicyConfig, "img-src", settings);
    setDirectiveOverride(contentSecurityPolicyConfig, "font-src", settings);
    return contentSecurityPolicyConfig;
}
Also used : Settings(com.servoy.j2db.util.Settings) ContentSecurityPolicyConfig(org.sablo.security.ContentSecurityPolicyConfig)

Example 3 with ContentSecurityPolicyConfig

use of org.sablo.security.ContentSecurityPolicyConfig in project servoy-client by Servoy.

the class NGClientEntryFilter method doFilter.

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    try {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if ("GET".equalsIgnoreCase(request.getMethod())) {
            if (request.getCharacterEncoding() == null)
                request.setCharacterEncoding("UTF8");
            String uri = request.getRequestURI();
            if (handleShortSolutionRequest(request, response)) {
                return;
            }
            if (handleDeeplink(request, response)) {
                return;
            }
            if (handleRecording(request, response)) {
                return;
            }
            if (uri != null && (uri.endsWith(".html") || uri.endsWith(".js"))) {
                String solutionName = getSolutionNameFromURI(uri);
                if (solutionName != null) {
                    String clientnr = AngularIndexPageWriter.getClientNr(uri, request);
                    INGClientWebsocketSession wsSession = null;
                    HttpSession httpSession = request.getSession(false);
                    if (clientnr != null && httpSession != null) {
                        wsSession = (INGClientWebsocketSession) WebsocketSessionManager.getSession(CLIENT_ENDPOINT, httpSession, Integer.parseInt(clientnr));
                    }
                    FlattenedSolution fs = null;
                    boolean closeFS = false;
                    if (wsSession != null) {
                        fs = wsSession.getClient().getFlattenedSolution();
                    }
                    if (fs == null) {
                        try {
                            closeFS = true;
                            IApplicationServer as = ApplicationServerRegistry.getService(IApplicationServer.class);
                            if (AngularIndexPageWriter.applicationServerUnavailable(response, as)) {
                                return;
                            }
                            SolutionMetaData solutionMetaData = (SolutionMetaData) ApplicationServerRegistry.get().getLocalRepository().getRootObjectMetaData(solutionName, SOLUTIONS);
                            if (AngularIndexPageWriter.solutionMissing(response, solutionName, solutionMetaData)) {
                                return;
                            }
                            fs = new FlattenedSolution(solutionMetaData, new AbstractActiveSolutionHandler(as) {

                                @Override
                                public IRepository getRepository() {
                                    return ApplicationServerRegistry.get().getLocalRepository();
                                }
                            });
                        } catch (Exception e) {
                            Debug.error("error loading solution: " + solutionName + " for clientnr: " + clientnr, e);
                        }
                    }
                    if (fs != null) {
                        try {
                            if (handleMainJs(request, response, fs)) {
                                return;
                            }
                            if (handleForm(request, response, wsSession, fs)) {
                                return;
                            }
                            if (AngularIndexPageWriter.handleMaintenanceMode(request, response, wsSession)) {
                                return;
                            }
                            // prepare for possible index.html lookup
                            Map<String, Object> variableSubstitution = getSubstitutions(request, solutionName, clientnr, fs);
                            List<String> extraMeta = new ArrayList<String>();
                            addManifest(fs, extraMeta);
                            addHeadIndexContributions(fs, extraMeta);
                            ContentSecurityPolicyConfig contentSecurityPolicyConfig = addcontentSecurityPolicyHeader(request, response, true);
                            super.doFilter(servletRequest, servletResponse, filterChain, asList(SERVOY_CSS), new ArrayList<String>(getFormScriptReferences(fs)), extraMeta, variableSubstitution, contentSecurityPolicyConfig == null ? null : contentSecurityPolicyConfig.getNonce());
                            return;
                        } finally {
                            if (closeFS) {
                                fs.close(null);
                            }
                        }
                    }
                }
            }
            if (!uri.contains(ModifiablePropertiesGenerator.PUSH_TO_SERVER_BINDINGS_LIST))
                Debug.log("No solution found for this request, calling the default filter: " + uri);
        }
        super.doFilter(servletRequest, servletResponse, filterChain, null, null, null, null, null);
    } catch (RuntimeException | Error e) {
        Debug.error(e);
        throw e;
    }
}
Also used : HttpSession(javax.servlet.http.HttpSession) ArrayList(java.util.ArrayList) HttpServletResponse(javax.servlet.http.HttpServletResponse) FlattenedSolution(com.servoy.j2db.FlattenedSolution) IApplicationServer(com.servoy.j2db.server.shared.IApplicationServer) SolutionMetaData(com.servoy.j2db.persistence.SolutionMetaData) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) ContentSecurityPolicyConfig(org.sablo.security.ContentSecurityPolicyConfig) HttpServletRequest(javax.servlet.http.HttpServletRequest) AbstractActiveSolutionHandler(com.servoy.j2db.AbstractActiveSolutionHandler) JSONObject(org.json.JSONObject)

Example 4 with ContentSecurityPolicyConfig

use of org.sablo.security.ContentSecurityPolicyConfig in project servoy-client by Servoy.

the class AngularIndexPageFilter method doFilter.

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String requestURI = request.getRequestURI();
    String solutionName = getSolutionNameFromURI(requestURI);
    if ("GET".equalsIgnoreCase(request.getMethod()) && solutionName != null) {
        if ((requestURI.endsWith("/") || requestURI.endsWith("/" + solutionName) || requestURI.toLowerCase().endsWith("/index.html"))) {
            String clientnr = AngularIndexPageWriter.getClientNr(requestURI, request);
            INGClientWebsocketSession wsSession = null;
            HttpSession httpSession = request.getSession(false);
            if (clientnr != null && httpSession != null) {
                wsSession = (INGClientWebsocketSession) WebsocketSessionManager.getSession(CLIENT_ENDPOINT, httpSession, Integer.parseInt(clientnr));
            }
            if (AngularIndexPageWriter.handleMaintenanceMode(request, response, wsSession)) {
                return;
            }
            request.getSession();
            // for NG2 remove the unsafe-eval
            ContentSecurityPolicyConfig contentSecurityPolicyConfig = addcontentSecurityPolicyHeader(request, response, false);
            if (this.indexPage != null)
                AngularIndexPageWriter.writeIndexPage(this.indexPage, request, response, solutionName, contentSecurityPolicyConfig == null ? null : contentSecurityPolicyConfig.getNonce());
            else {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/html");
                String indexHtml = "<html><body>No NGClient2 resources exported</body></html>";
                response.setContentLengthLong(indexHtml.length());
                response.getWriter().write(indexHtml);
                Debug.error("Trying to service NGClient2, but no resouces are generatd for that in the exporter (-NG2 flag) or an error happend when exporting");
            }
            return;
        } else if (requestURI.toLowerCase().endsWith("/startup.js")) {
            AngularIndexPageWriter.writeStartupJs(request, (HttpServletResponse) servletResponse, solutionName);
            return;
        } else if (AngularIndexPageWriter.handleDeeplink(request, (HttpServletResponse) servletResponse)) {
            return;
        }
    }
    chain.doFilter(servletRequest, servletResponse);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpSession(javax.servlet.http.HttpSession) HttpServletResponse(javax.servlet.http.HttpServletResponse) ContentSecurityPolicyConfig(org.sablo.security.ContentSecurityPolicyConfig)

Aggregations

ContentSecurityPolicyConfig (org.sablo.security.ContentSecurityPolicyConfig)4 FlattenedSolution (com.servoy.j2db.FlattenedSolution)2 IOException (java.io.IOException)2 ServletException (javax.servlet.ServletException)2 HttpServletRequest (javax.servlet.http.HttpServletRequest)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 HttpSession (javax.servlet.http.HttpSession)2 AbstractActiveSolutionHandler (com.servoy.j2db.AbstractActiveSolutionHandler)1 Media (com.servoy.j2db.persistence.Media)1 SolutionMetaData (com.servoy.j2db.persistence.SolutionMetaData)1 IApplicationServer (com.servoy.j2db.server.shared.IApplicationServer)1 Settings (com.servoy.j2db.util.Settings)1 Utils.getAsBoolean (com.servoy.j2db.util.Utils.getAsBoolean)1 BufferedReader (java.io.BufferedReader)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStreamReader (java.io.InputStreamReader)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1 JSONException (org.json.JSONException)1