Package hudson.security.csrf

Source Code of hudson.security.csrf.CrumbFilter

/**
* Copyright (c) 2008-2009 Yahoo! Inc.
* All rights reserved.
* The copyrights to the contents of this file are licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
package hudson.security.csrf;

import hudson.model.Hudson;

import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Checks for and validates crumbs on requests that cause state changes, to
* protect against cross site request forgeries.
*
* @author dty
*/
public class CrumbFilter implements Filter {
    /**
     * Because servlet containers generally don't specify the ordering of the initialization
     * (and different implementations indeed do this differently --- See HUDSON-3878),
     * we cannot use Hudson to the CrumbIssuer into CrumbFilter eagerly.
     */
    public CrumbIssuer getCrumbIssuer() {
        Hudson h = Hudson.getInstance();
        if(h==null)     return null;    // before Hudson is initialized?
        return h.getCrumbIssuer();
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        CrumbIssuer crumbIssuer = getCrumbIssuer();
        if (crumbIssuer == null || !(request instanceof HttpServletRequest)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String crumbFieldName = crumbIssuer.getDescriptor().getCrumbRequestField();
        String crumbSalt = crumbIssuer.getDescriptor().getCrumbSalt();

        if ("POST".equals(httpRequest.getMethod())) {
            String crumb = httpRequest.getHeader(crumbFieldName);
            boolean valid = false;
            if (crumb == null) {
                Enumeration<?> paramNames = request.getParameterNames();
                while (paramNames.hasMoreElements()) {
                    String paramName = (String) paramNames.nextElement();
                    if (crumbFieldName.equals(paramName)) {
                        crumb = request.getParameter(paramName);
                        break;
                    }
                }
            }
            if (crumb != null) {
                if (crumbIssuer.validateCrumb(httpRequest, crumbSalt, crumb)) {
                    valid = true;
                } else {
                    LOGGER.warning("Found invalid crumb " + crumb +
                            ".  Will check remaining parameters for a valid one...");
                }
            }
            // Multipart requests need to be handled by each handler.
            if (valid || isMultipart(httpRequest)) {
                chain.doFilter(request, response);
            } else {
                LOGGER.warning("No valid crumb was included in request for " + httpRequest.getRequestURI() + ".  Returning " + HttpServletResponse.SC_FORBIDDEN + ".");
                HttpServletResponse httpResponse = (HttpServletResponse) response;
                httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,"No valid crumb was included in the request");
            }
        } else {
            chain.doFilter(request, response);
        }
    }

    protected static boolean isMultipart(HttpServletRequest request) {
        if (request == null) {
            return false;
        }

        String contentType = request.getContentType();
        if (contentType == null) {
            return false;
        }

        String[] parts = contentType.split(";");
        if (parts.length == 0) {
            return false;
        }

        for (int i = 0; i < parts.length; i++) {
            if ("multipart/form-data".equals(parts[i])) {
                return true;
            }
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public void destroy() {
    }

    private static final Logger LOGGER = Logger.getLogger(CrumbFilter.class.getName());
}
TOP

Related Classes of hudson.security.csrf.CrumbFilter

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.