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 --- ecomp-sdk/epsdk-app-common/README.md | 4 +-- .../controller/core/FnMenuController.java | 13 ++++----- .../controller/core/ProfileController.java | 6 ++-- .../portalapp/controller/core/RoleController.java | 8 ++--- .../controller/core/RoleListController.java | 4 +-- .../controller/core/SingleSignOnController.java | 18 +++++++++++- .../controller/sample/BroadcastController.java | 11 +++++-- .../controller/sample/BroadcastListController.java | 4 +-- .../onap/portalapp/util/SecurityXssValidator.java | 34 +++++++++------------- 9 files changed, 57 insertions(+), 45 deletions(-) (limited to 'ecomp-sdk/epsdk-app-common') diff --git a/ecomp-sdk/epsdk-app-common/README.md b/ecomp-sdk/epsdk-app-common/README.md index fa3e7bc4..e72d9420 100644 --- a/ecomp-sdk/epsdk-app-common/README.md +++ b/ecomp-sdk/epsdk-app-common/README.md @@ -29,9 +29,9 @@ Version 1.4.0 - PORTAL-42 Use OParent as parent POM - PORTAL-72 Address Sonar Scan code issues - PORTAL-90 Use approved ONAP license text -- Portal-86 Remove application specific usages from tests and other files +- PORTAL-86 Remove application specific usages from tests and other files - PORTAL-78 Fix SingleSignon by force session creation prior to redirection to portal - +- PORTAL-118 Missing Error page in Portal-SDK app when there is an exception happen in the backend. Version 1.3.0, 28 August 2017 - Portal-19 Renaming the Group Id in the POM file to org.onap.portal.sdk diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/FnMenuController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/FnMenuController.java index dfc735b1..c441417b 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/FnMenuController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/FnMenuController.java @@ -76,7 +76,7 @@ public class FnMenuController extends RestrictedBaseController { @Autowired FnMenuService service; - + @Autowired FunctionalMenuListService functionalMenuListService; @@ -91,7 +91,7 @@ public class FnMenuController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "getParentListFailed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the getParentList () "); } } @@ -104,7 +104,7 @@ public class FnMenuController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "getFunctionCDList", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the getFunctionCDList ()"); } } @@ -160,7 +160,6 @@ public class FnMenuController extends RestrictedBaseController { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JsonNode root = mapper.readTree(request.getReader()); Menu fnMenuItem = mapper.readValue(root.get("availableFnMenuItem").toString(), Menu.class); - service.saveFnMenu(fnMenuItem); request.getSession() .removeAttribute(SystemProperties.getProperty(SystemProperties.APPLICATION_MENU_ATTRIBUTE_NAME)); @@ -183,7 +182,7 @@ public class FnMenuController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the updateFnMenu () "); } return null; @@ -198,9 +197,7 @@ public class FnMenuController extends RestrictedBaseController { JsonNode root = mapper.readTree(request.getReader()); Menu fnMenuItem = mapper.readValue(root.get("fnMenuItem").toString(), Menu.class); Menu fnMenuItemRow = service.getMenuItemRow(fnMenuItem.getId()); - service.removeMenuItem(fnMenuItemRow); - response.setCharacterEncoding("UTF-8"); response.setContentType("application / json"); request.setCharacterEncoding("UTF-8"); @@ -215,7 +212,7 @@ public class FnMenuController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the removeFnMenu ()"); } return null; diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/ProfileController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/ProfileController.java index c83e926e..b63d24aa 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/ProfileController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/ProfileController.java @@ -229,7 +229,7 @@ public class ProfileController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); try { PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the saveProfile ()"); } catch (IOException e1) { logger.error(EELFLoggerDelegate.errorLogger, "saveProfile: failed to write", e1); } @@ -279,7 +279,7 @@ public class ProfileController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "removeRole failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the removeRole ()"); return null; } } @@ -322,7 +322,7 @@ public class ProfileController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred in the addNewRole ()"); return null; } diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleController.java index 69a25e66..bd1a6ab0 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleController.java @@ -232,7 +232,7 @@ public class RoleController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "removeRole failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred removeRole failed in the removeRoleFunction"); return null; } @@ -269,7 +269,7 @@ public class RoleController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "removeRoleFunction failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred removeRoleFunction failed in the removeRoleFunction"); return null; } @@ -305,7 +305,7 @@ public class RoleController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "removeChildRole failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred removeChildRole failed in the removeChildRole()"); return null; } @@ -342,7 +342,7 @@ public class RoleController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "addChildRole failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred addChildRole failed in the addChildRole()"); return null; } diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java index b89cb43c..c7804e5f 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/RoleListController.java @@ -141,7 +141,7 @@ public class RoleListController extends RestrictedBaseController { logger.error(EELFLoggerDelegate.errorLogger, "toggleRole failed", e); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred while saving Role in the toggleRole()"); return null; } @@ -180,7 +180,7 @@ public class RoleListController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred while removing Role in the toggleRole()"); return null; } diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/SingleSignOnController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/SingleSignOnController.java index fb2e3b80..982a60b8 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/SingleSignOnController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/core/SingleSignOnController.java @@ -37,6 +37,8 @@ */ package org.onap.portalapp.controller.core; +import java.net.MalformedURLException; +import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashMap; @@ -47,6 +49,7 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import org.apache.commons.lang.StringUtils; import org.onap.portalsdk.core.auth.LoginStrategy; import org.onap.portalsdk.core.command.LoginBean; import org.onap.portalsdk.core.controller.UnRestrictedBaseController; @@ -159,6 +162,7 @@ public class SingleSignOnController extends UnRestrictedBaseController { // both user and session are non-null. logger.info(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: redirecting to the forwardURL {}", forwardURL); + validateDomain(forwardURL); return new ModelAndView("redirect:" + forwardURL); } @@ -180,6 +184,7 @@ public class SingleSignOnController extends UnRestrictedBaseController { // application can publish a base URL in system.properties String appUrl = SystemProperties.getProperty(SystemProperties.APP_BASE_URL); returnToAppUrl = appUrl + (appUrl.endsWith("/") ? "" : "/") + forwardURL; + validateDomain(returnToAppUrl); logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: using app base URL {} and redirectURL {}", appUrl, returnToAppUrl); } else { @@ -190,6 +195,7 @@ public class SingleSignOnController extends UnRestrictedBaseController { // should always find the specified token. returnToAppUrl = request.getRequestURL().toString().replace("single_signon.htm", forwardURL); + validateDomain(returnToAppUrl); logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: computed redirectURL {}", returnToAppUrl); } @@ -202,7 +208,6 @@ public class SingleSignOnController extends UnRestrictedBaseController { final String redirectUrl = portalUrl + "?uebAppKey=" + uebAppKey + "&redirectUrl=" + encodedReturnToAppUrl; logger.debug(EELFLoggerDelegate.debugLogger, "singleSignOnLogin: portal-bound redirect URL is {}", redirectUrl); - // this line may not be necessary but jsessionid coockie is not getting created in all cases; // so force the cookie creation request.getSession(true); @@ -211,6 +216,17 @@ public class SingleSignOnController extends UnRestrictedBaseController { } } + private void validateDomain(String forwardURL) throws MalformedURLException { + if (StringUtils.isNotBlank(forwardURL)) { + String hostName = new URL(forwardURL).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); + } + } + } + protected void initateSessionMgtHandler(HttpServletRequest request) { String portalJSessionId = getPortalJSessionId(request); String jSessionId = getJessionId(request); diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastController.java index 316f35cd..c4f0d430 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastController.java @@ -45,8 +45,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; +import org.onap.portalapp.util.SecurityXssValidator; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.domain.BroadcastMessage; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.service.BroadcastService; import org.onap.portalsdk.core.util.SystemProperties; import org.onap.portalsdk.core.web.support.AppUtils; @@ -65,6 +67,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; @RequestMapping("/") public class BroadcastController extends RestrictedBaseController { + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(BroadcastController.class); + @Autowired private BroadcastService broadcastService; @@ -77,7 +81,7 @@ public class BroadcastController extends RestrictedBaseController { model.put("broadcastMessage", mapper.writeValueAsString(broadcastService.getBroadcastMessage(request))); model.put("broadcastSites", mapper.writeValueAsString(referenceData(request).get("broadcastSites"))); } catch (Exception e) { - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger, "broadcast() failed", e); } return new ModelAndView(getViewName(), model); } @@ -96,7 +100,7 @@ public class BroadcastController extends RestrictedBaseController { response.getWriter().write(j.toString()); } catch (Exception e) { - e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger, "getBroadcast() failed", e); } } @@ -141,7 +145,8 @@ public class BroadcastController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred while saving the BroadcastMessage in the save () mapping-/broadcast/save "); + logger.error(EELFLoggerDelegate.errorLogger, "save() failed", e); return null; } diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastListController.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastListController.java index aeeaca56..2a9af812 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastListController.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/controller/sample/BroadcastListController.java @@ -121,7 +121,7 @@ public class BroadcastListController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred while removing the BroadcastMessage in the remove ()"); logger.error(EELFLoggerDelegate.errorLogger, "remove() failed", e); return null; } @@ -156,7 +156,7 @@ public class BroadcastListController extends RestrictedBaseController { response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); - out.write(e.getMessage()); + out.write("An error occurred while saving the BroadcastMessage in the toggleActive () "); logger.error(EELFLoggerDelegate.errorLogger, "toggleActive() failed", e); return null; } diff --git a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java index b51cb8db..97545508 100644 --- a/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java +++ b/ecomp-sdk/epsdk-app-common/src/main/java/org/onap/portalapp/util/SecurityXssValidator.java @@ -60,6 +60,7 @@ public class SecurityXssValidator { private static final String MYSQL_DB = "mysql"; private static final String ORACLE_DB = "oracle"; private static final String MARIA_DB = "mariadb"; + private static final int FLAGS = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL; static SecurityXssValidator validator = null; private static Codec instance; @@ -82,46 +83,39 @@ public class SecurityXssValidator { private SecurityXssValidator() { // Avoid anything between script tags - XSS_INPUT_PATTERNS.add(Pattern.compile("", Pattern.CASE_INSENSITIVE)); + XSS_INPUT_PATTERNS.add(Pattern.compile("", FLAGS)); // avoid iframes - XSS_INPUT_PATTERNS.add(Pattern.compile("(.*?)", Pattern.CASE_INSENSITIVE)); + XSS_INPUT_PATTERNS.add(Pattern.compile("(.*?)", FLAGS)); // Avoid anything in a src='...' type of expression - XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", - Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", FLAGS)); - XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", - Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", FLAGS)); - XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*([^>]+)", - Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)); + XSS_INPUT_PATTERNS.add(Pattern.compile("src[\r\n]*=[\r\n]*([^>]+)", FLAGS)); // Remove any lonesome tag - XSS_INPUT_PATTERNS.add(Pattern.compile("", Pattern.CASE_INSENSITIVE)); + XSS_INPUT_PATTERNS.add(Pattern.compile("", FLAGS)); - XSS_INPUT_PATTERNS.add(Pattern.compile(".*().*", Pattern.CASE_INSENSITIVE)); + XSS_INPUT_PATTERNS.add(Pattern.compile(".*().*", FLAGS)); - XSS_INPUT_PATTERNS.add(Pattern.compile(".*().*", Pattern.CASE_INSENSITIVE)); + XSS_INPUT_PATTERNS.add(Pattern.compile(".*().*", FLAGS)); // Remove any lonesome