diff options
author | st782s <statta@research.att.com> | 2018-01-03 14:30:16 -0500 |
---|---|---|
committer | TATTAVARADA <statta@research.att.com> | 2018-01-03 14:31:40 -0500 |
commit | 69062c0ec148ccadaced3ef1d6eff63ba422c055 (patch) | |
tree | 153af87b560baa991263ad66797f44e1c475431f /ecomp-sdk/epsdk-app-os/src/main | |
parent | ed07ebfbce4031ef4dfbd2f42147f6a7b351aeb8 (diff) |
Harden code
Issue-ID: PORTAL-145,PORTAL-119,PORTAL-118
Harden code to address SQL injecton, XSS vulnerabilities; Separate
docker images for portal, sdk app and DMaaPBC ui; Missing error page
Change-Id: I1818fbf86c601dd41b274729038e731fb2ec8f7d
Signed-off-by: st782s <statta@research.att.com>
Diffstat (limited to 'ecomp-sdk/epsdk-app-os/src/main')
3 files changed, 100 insertions, 47 deletions
diff --git a/ecomp-sdk/epsdk-app-os/src/main/java/org/onap/portalapp/filter/SecurityXssFilter.java b/ecomp-sdk/epsdk-app-os/src/main/java/org/onap/portalapp/filter/SecurityXssFilter.java index 71ab7359..aad01286 100644 --- a/ecomp-sdk/epsdk-app-os/src/main/java/org/onap/portalapp/filter/SecurityXssFilter.java +++ b/ecomp-sdk/epsdk-app-os/src/main/java/org/onap/portalapp/filter/SecurityXssFilter.java @@ -38,71 +38,119 @@ */ package org.onap.portalapp.filter; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import javax.servlet.FilterChain; +import javax.servlet.ReadListener; import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpStatus; import org.onap.portalapp.util.SecurityXssValidator; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.springframework.web.filter.OncePerRequestFilter; -import org.springframework.web.util.ContentCachingRequestWrapper; -import org.springframework.web.util.ContentCachingResponseWrapper; -import org.springframework.web.util.WebUtils; public class SecurityXssFilter extends OncePerRequestFilter { - private static final String BAD_REQUEST = "BAD_REQUEST"; + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SecurityXssFilter.class); + + private static final String APPLICATION_JSON = "application/json"; + + private static final String ERROR_BAD_REQUEST = "{\"error\":\"BAD_REQUEST\"}"; private SecurityXssValidator validator = SecurityXssValidator.getInstance(); - private static String getRequestData(final HttpServletRequest request) throws UnsupportedEncodingException { - String payload = null; - ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class); - if (wrapper != null) { - byte[] buf = wrapper.getContentAsByteArray(); - if (buf.length > 0) { - payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding()); - } + public class RequestWrapper extends HttpServletRequestWrapper { + + private ByteArrayOutputStream cachedBytes; + + public RequestWrapper(HttpServletRequest request) { + super(request); } - return payload; - } - private static String getResponseData(final HttpServletResponse response) throws IOException { - String payload = null; - ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, - ContentCachingResponseWrapper.class); - if (wrapper != null) { - byte[] buf = wrapper.getContentAsByteArray(); - if (buf.length > 0) { - payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding()); - wrapper.copyBodyToResponse(); + @Override + public ServletInputStream getInputStream() throws IOException { + if (cachedBytes == null) + cacheInputStream(); + + return new CachedServletInputStream(); + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + private void cacheInputStream() throws IOException { + cachedBytes = new ByteArrayOutputStream(); + IOUtils.copy(super.getInputStream(), cachedBytes); + } + + public class CachedServletInputStream extends ServletInputStream { + private ByteArrayInputStream input; + + public CachedServletInputStream() { + input = new ByteArrayInputStream(cachedBytes.toByteArray()); } + + @Override + public int read() throws IOException { + return input.read(); + } + + public boolean isFinished() { + return false; + } + + public boolean isReady() { + return false; + } + + public void setReadListener(ReadListener readListener) { + + } + } - return payload; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - - if (request.getMethod().equalsIgnoreCase("POST") || request.getMethod().equalsIgnoreCase("PUT")) { - - HttpServletRequest requestToCache = new ContentCachingRequestWrapper(request); - HttpServletResponse responseToCache = new ContentCachingResponseWrapper(response); - filterChain.doFilter(requestToCache, responseToCache); - String requestData = getRequestData(requestToCache); - String responseData = getResponseData(responseToCache); - if (StringUtils.isNotBlank(requestData) && validator.denyXSS(requestData)) { - throw new SecurityException(BAD_REQUEST); + if (validateRequestType(request)) { + request = new RequestWrapper(request); + String requestData = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8.toString()); + try { + if (StringUtils.isNotBlank(requestData) && validator.denyXSS(requestData)) { + response.setContentType(APPLICATION_JSON); + response.setStatus(HttpStatus.SC_BAD_REQUEST); + response.getWriter().write(ERROR_BAD_REQUEST); + throw new SecurityException(ERROR_BAD_REQUEST); + } + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, "doFilterInternal() failed due to BAD_REQUEST", e); + response.getWriter().close(); + return; } + filterChain.doFilter(request, response); } else { filterChain.doFilter(request, response); } } -} + + private boolean validateRequestType(HttpServletRequest request) { + return (request.getMethod().equalsIgnoreCase("POST") || request.getMethod().equalsIgnoreCase("PUT") + || request.getMethod().equalsIgnoreCase("DELETE")); + } +}
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/conf/system.properties b/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/conf/system.properties index de056a3d..0dc81301 100644 --- a/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/conf/system.properties +++ b/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/conf/system.properties @@ -69,4 +69,6 @@ instance_uuid=8da691c9-987d-43ed-a358-00ac2f35685d # app_base_url = https://www.openecomp.org/app_context/ #authenticate user server -authenticate_user_server=http://todo_enter_auth_server_hostname:8383/openid-connect-server-webapp/allUsers
\ No newline at end of file +authenticate_user_server=http://todo_enter_auth_server_hostname:8383/openid-connect-server-webapp/allUsers +#cookie domain +cookie_domain = onap.org
\ No newline at end of file diff --git a/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/web.xml b/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/web.xml index f5039df4..76a372be 100644 --- a/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/web.xml +++ b/ecomp-sdk/epsdk-app-os/src/main/webapp/WEB-INF/web.xml @@ -1,8 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee" - xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" - version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"> + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" + version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"> <display-name>ecomp-sdk-app-os</display-name> @@ -14,12 +13,16 @@ <tracking-mode>COOKIE</tracking-mode> </session-config> <filter> - <filter-name>SecurityXssFilter</filter-name> - <filter-class>org.onap.portalapp.filter.SecurityXssFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>SecurityXssFilter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> + <filter-name>SecurityXssFilter</filter-name> + <filter-class>org.onap.portalapp.filter.SecurityXssFilter + </filter-class> + </filter> + <filter-mapping> + <filter-name>SecurityXssFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <error-page> + <location>/WEB-INF/jsp/error.jsp</location> + </error-page> </web-app>
\ No newline at end of file |