From 69062c0ec148ccadaced3ef1d6eff63ba422c055 Mon Sep 17 00:00:00 2001 From: st782s Date: Wed, 3 Jan 2018 14:30:16 -0500 Subject: 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 --- .../interceptor/SessionTimeoutInterceptor.java | 19 ++++- .../core/logging/format/AlarmSeverityEnum.java | 16 ++++- .../onap/portalsdk/core/service/UrlAccessImpl.java | 82 ++++++++++++++++++++-- .../onap/portalsdk/core/util/SystemProperties.java | 2 + 4 files changed, 110 insertions(+), 9 deletions(-) (limited to 'ecomp-sdk/epsdk-core/src') diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/interceptor/SessionTimeoutInterceptor.java b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/interceptor/SessionTimeoutInterceptor.java index 809266d4..a6b98fdf 100644 --- a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/interceptor/SessionTimeoutInterceptor.java +++ b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/interceptor/SessionTimeoutInterceptor.java @@ -37,17 +37,21 @@ */ package org.onap.portalsdk.core.interceptor; +import java.net.MalformedURLException; +import java.net.URL; import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.commons.lang.StringUtils; import org.onap.portalsdk.core.controller.FusionBaseController; import org.onap.portalsdk.core.domain.User; import org.onap.portalsdk.core.exception.SessionExpiredException; import org.onap.portalsdk.core.listener.CollaborateListBindingListener; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.onap.portalsdk.core.util.SystemProperties; import org.onap.portalsdk.core.web.support.AppUtils; import org.onap.portalsdk.core.web.support.UserUtils; import org.springframework.web.method.HandlerMethod; @@ -56,7 +60,7 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class SessionTimeoutInterceptor extends HandlerInterceptorAdapter { private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SessionTimeoutInterceptor.class); - + /** * Checks all requests for valid session information. If not found, redirects to * a controller that will establish a valid session. @@ -98,6 +102,7 @@ public class SessionTimeoutInterceptor extends HandlerInterceptorAdapter { // "/context/single_signon.htm" final String redirectUrl = request.getContextPath() + singleSignonPrefix + "redirectToPortal=Yes&" + forwardUrlParm; + validateDomain(redirectUrl); logger.debug(EELFLoggerDelegate.debugLogger, "preHandle: session is expired, redirecting to {}", redirectUrl); response.sendRedirect(redirectUrl); @@ -107,6 +112,7 @@ public class SessionTimeoutInterceptor extends HandlerInterceptorAdapter { // Redirect to an absolute path in the webapp; e.g., // "/context/single_signon.htm" final String redirectUrl = request.getContextPath() + singleSignonPrefix + forwardUrlParm; + validateDomain(redirectUrl); logger.debug(EELFLoggerDelegate.debugLogger, "preHandle: took exception {}, redirecting to {}", ex.getMessage(), redirectUrl); response.sendRedirect(redirectUrl); @@ -119,4 +125,15 @@ public class SessionTimeoutInterceptor extends HandlerInterceptorAdapter { return super.preHandle(request, response, handler); } + private void validateDomain(final String redirectUrl) throws MalformedURLException { + if (StringUtils.isNotBlank(redirectUrl)) { + String hostName = new URL(redirectUrl).getHost(); + if (StringUtils.isNotBlank(hostName) + && !hostName.endsWith(SystemProperties.getProperty(SystemProperties.COOKIE_DOMAIN))) { + logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: accessing Unauthorized url", hostName); + throw new SecurityException("accessing Unauthorized url : " + hostName); + } + } + } + } diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/logging/format/AlarmSeverityEnum.java b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/logging/format/AlarmSeverityEnum.java index 5e202475..c2ce2b3d 100644 --- a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/logging/format/AlarmSeverityEnum.java +++ b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/logging/format/AlarmSeverityEnum.java @@ -38,5 +38,19 @@ package org.onap.portalsdk.core.logging.format; public enum AlarmSeverityEnum { - CRITICAL, MAJOR, MINOR, INFORMATIONAL, NONE, + CRITICAL("1"), + MAJOR("2"), + MINOR("3"), + INFORMATIONAL("4"), + NONE("0"); + + private final String severity; + + AlarmSeverityEnum(String severity) { + this.severity = severity; + } + + public String severity() { + return severity; + } } diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/service/UrlAccessImpl.java b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/service/UrlAccessImpl.java index 4dde6116..ddadc101 100644 --- a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/service/UrlAccessImpl.java +++ b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/service/UrlAccessImpl.java @@ -37,12 +37,15 @@ */ package org.onap.portalsdk.core.service; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Restrictions; import org.onap.portalsdk.core.domain.UrlsAccessible; import org.onap.portalsdk.core.web.support.UserUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -59,17 +62,18 @@ public class UrlAccessImpl implements UrlAccessService { @Override public boolean isUrlAccessible(HttpServletRequest request, String currentUrl) { boolean isAccessible = false; - Map params = new HashMap<>(); - params.put("current_url", currentUrl); - List list = dataAccessService.executeNamedQuery("restrictedUrls", params, null); + List list = getAccessUrlList(currentUrl); // loop through the list of restricted URL's if (list != null && !list.isEmpty()) { for (int i = 0; i < list.size(); i++) { - UrlsAccessible urlFunctions = (UrlsAccessible) list.get(i); - String functionCd = urlFunctions.getFunctionCd(); + UrlsAccessible urlFunction = (UrlsAccessible) list.get(i); + if (!matchPattern(currentUrl, urlFunction.getUrl())) + continue; + String functionCd = urlFunction.getFunctionCd(); if (UserUtils.isAccessible(request, functionCd)) { isAccessible = true; + break; } } return isAccessible; @@ -77,4 +81,68 @@ public class UrlAccessImpl implements UrlAccessService { return true; } + /* + * This Method returns all the entries in the database that start with the + * first part of the currentUrl split at the "/" character. + * + * Example: if currentUrl + * is "xyz/abc/1", all the entries in the corresponding tables that match + * with "xyz" are returned + */ + private List getAccessUrlList(String currentUrl) { + List list = null; + + if (currentUrl != null) { + int indexOfSlash = currentUrl.indexOf("/"); + String currentFirstUrl = (indexOfSlash > 0) ? currentUrl.substring(0, indexOfSlash) : currentUrl; + + if (currentFirstUrl != null) { + + List restrictionsList = new ArrayList(); + Criterion criterion1 = Restrictions.like("urlsAccessibleKey.url", currentFirstUrl + "%"); + restrictionsList.add(criterion1); + list = dataAccessService.getList(UrlsAccessible.class, null, restrictionsList, null); + + } + } + return list; + } + + /* + * This method compares the portalApiPath against the urlPattern; splits the + * portalApiPath by "/" and compares each part with that of the urlPattern. + * + * Example: "xyz/1/abc" matches with the pattern "xyz/* /abc" but not with + * "xyz/*" + * + */ + + private Boolean matchPattern(String portalApiPath, String urlPattern) { + String[] path = portalApiPath.split("/"); + if (path.length > 1) { + + String[] roleFunctionArray = urlPattern.split("/"); + boolean match = true; + if (roleFunctionArray.length == path.length) { + for (int i = 0; i < roleFunctionArray.length; i++) { + if (match) { + if (!roleFunctionArray[i].equals("*")) { + Pattern p = Pattern.compile(path[i], Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(roleFunctionArray[i]); + match = m.matches(); + + } + } + } + if (match) + return match; + } + } else { + if (portalApiPath.matches(urlPattern)) + return true; + + } + return false; + } + } diff --git a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/util/SystemProperties.java b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/util/SystemProperties.java index 6f119104..b6b03a44 100644 --- a/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/util/SystemProperties.java +++ b/ecomp-sdk/epsdk-core/src/main/java/org/onap/portalsdk/core/util/SystemProperties.java @@ -263,6 +263,8 @@ public class SystemProperties { // Left Menu public static final String LEFT_MENU_PARENT = "parentList"; public static final String LEFT_MENU_CHILDREND = "childItemList"; + public static final String COOKIE_DOMAIN = "cookie_domain"; + public enum RESULT_ENUM { SUCCESS, FAILURE -- cgit 1.2.3-korg