Merge "XSS Vulnerability fix in DashboardSearchResultController"
authorSunder Tattavarada <statta@research.att.com>
Fri, 14 Jun 2019 16:18:10 +0000 (16:18 +0000)
committerGerrit Code Review <gerrit@onap.org>
Fri, 14 Jun 2019 16:18:10 +0000 (16:18 +0000)
ecomp-portal-BE-os/src/main/java/org/onap/portalapp/portal/controller/DashboardSearchResultController.java
ecomp-portal-BE-os/src/test/java/org/onap/portalapp/portal/controller/DashboardSearchResultControllerTest.java

index 0be5712..1dff604 100644 (file)
@@ -48,7 +48,6 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import org.onap.portalapp.controller.EPRestrictedBaseController;
-import org.onap.portalapp.portal.controller.DashboardSearchResultController;
 import org.onap.portalapp.portal.domain.EPUser;
 import org.onap.portalapp.portal.ecomp.model.PortalRestResponse;
 import org.onap.portalapp.portal.ecomp.model.PortalRestStatusEnum;
@@ -57,6 +56,8 @@ import org.onap.portalapp.portal.service.DashboardSearchService;
 import org.onap.portalapp.portal.transport.CommonWidget;
 import org.onap.portalapp.portal.transport.CommonWidgetMeta;
 import org.onap.portalapp.util.EPUserUtils;
+import org.onap.portalapp.validation.DataValidator;
+import org.onap.portalapp.validation.SecureString;
 import org.onap.portalsdk.core.domain.support.CollaborateList;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -71,6 +72,7 @@ import org.springframework.web.bind.annotation.RestController;
 public class DashboardSearchResultController extends EPRestrictedBaseController {
 
        private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DashboardSearchResultController.class);
+       private DataValidator dataValidator = new DataValidator();
 
        @Autowired
        private DashboardSearchService searchService;
@@ -86,7 +88,12 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
        @RequestMapping(value = "/widgetData", method = RequestMethod.GET, produces = "application/json")
        public PortalRestResponse<CommonWidgetMeta> getWidgetData(HttpServletRequest request,
                        @RequestParam String resourceType) {
-               return new PortalRestResponse<CommonWidgetMeta>(PortalRestStatusEnum.OK, "success",
+               if (resourceType !=null){
+                       SecureString secureString = new SecureString(resourceType);
+                       if (!dataValidator.isValid(secureString))
+                               return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "Provided data is invalid", null);
+               }
+               return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success",
                                searchService.getWidgetData(resourceType));
        }
 
@@ -100,9 +107,14 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
        @RequestMapping(value = "/widgetDataBulk", method = RequestMethod.POST, produces = "application/json")
        public PortalRestResponse<String> saveWidgetDataBulk(@RequestBody CommonWidgetMeta commonWidgetMeta) {
                logger.debug(EELFLoggerDelegate.debugLogger, "saveWidgetDataBulk: argument is {}", commonWidgetMeta);
-               if (commonWidgetMeta.getCategory() == null || commonWidgetMeta.getCategory().trim().equals(""))
+               if (commonWidgetMeta.getCategory() == null || commonWidgetMeta.getCategory().trim().equals("")){
                        return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, "ERROR",
                                        "Category cannot be null or empty");
+               }else {
+                       if(!dataValidator.isValid(commonWidgetMeta))
+                               return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, "ERROR",
+                                       "Category is not valid");
+               }
                // validate dates
                for (CommonWidget cw : commonWidgetMeta.getItems()) {
                        String err = validateCommonWidget(cw);
@@ -123,13 +135,18 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
        @RequestMapping(value = "/widgetData", method = RequestMethod.POST, produces = "application/json")
        public PortalRestResponse<String> saveWidgetData(@RequestBody CommonWidget commonWidget) {
                logger.debug(EELFLoggerDelegate.debugLogger, "saveWidgetData: argument is {}", commonWidget);
-               if (commonWidget.getCategory() == null || commonWidget.getCategory().trim().equals(""))
-                       return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, "ERROR",
+               if (commonWidget.getCategory() == null || commonWidget.getCategory().trim().equals("")){
+                       return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "ERROR",
                                        "Cateogry cannot be null or empty");
+               }else {
+                       if(!dataValidator.isValid(commonWidget))
+                               return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "ERROR",
+                                       "Category is not valid");
+               }
                String err = validateCommonWidget(commonWidget);
                if (err != null)
-                       return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, err, null);
-               return new PortalRestResponse<String>(PortalRestStatusEnum.OK, "success",
+                       return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, err, null);
+               return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success",
                                searchService.saveWidgetData(commonWidget));
        }
 
@@ -165,7 +182,10 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
        @RequestMapping(value = "/deleteData", method = RequestMethod.POST, produces = "application/json")
        public PortalRestResponse<String> deleteWidgetData(@RequestBody CommonWidget commonWidget) {
                logger.debug(EELFLoggerDelegate.debugLogger, "deleteWidgetData: argument is {}", commonWidget);
-               return new PortalRestResponse<String>(PortalRestStatusEnum.OK, "success",
+               if(!dataValidator.isValid(commonWidget))
+                       return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "ERROR",
+                               "Data is not valid");
+               return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success",
                                searchService.deleteWidgetData(commonWidget));
        }
 
@@ -180,16 +200,24 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
        @RequestMapping(value = "/allPortal", method = RequestMethod.GET, produces = "application/json")
        public PortalRestResponse<Map<String, List<SearchResultItem>>> searchPortal(HttpServletRequest request,
                        @RequestParam String searchString) {
+               if(searchString!=null){
+                       SecureString secureString = new SecureString(searchString);
+                       if(!dataValidator.isValid(secureString)){
+                               return new PortalRestResponse<>(PortalRestStatusEnum.ERROR,
+                                       "searchPortal: User object is invalid",
+                                       null);
+                       }
+               }
 
                EPUser user = EPUserUtils.getUserSession(request);
                try {
                        if (user == null) {
                                return new PortalRestResponse<>(PortalRestStatusEnum.ERROR,
                                                "searchPortal: User object is null? - check logs",
-                                               new HashMap<String, List<SearchResultItem>>());
+                                               new HashMap<>());
                        } else if (searchString == null || searchString.trim().length() == 0) {
                                return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "searchPortal: String string is null",
-                                               new HashMap<String, List<SearchResultItem>>());
+                                               new HashMap<>());
                        } else {
                                logger.debug(EELFLoggerDelegate.debugLogger, "searchPortal: user {}, search string '{}'",
                                                user.getLoginId(), searchString);
@@ -200,7 +228,7 @@ public class DashboardSearchResultController extends EPRestrictedBaseController
                } catch (Exception e) {
                        logger.error(EELFLoggerDelegate.errorLogger, "searchPortal failed", e);
                        return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.getMessage() + " - check logs.",
-                                       new HashMap<String, List<SearchResultItem>>());
+                                       new HashMap<>());
                }
        }
 
index 9edf99e..ff588da 100644 (file)
@@ -98,6 +98,18 @@ public class DashboardSearchResultControllerTest {
                assertEquals(ecpectedPortalRestResponse.getStatus(), actualPortalRestResponse.getStatus());
        }
 
+       @Test
+       public void getWidgetDataXSSTest() {
+               String resourceType = "\"<IMG SRC=\\\"jav\\tascript:alert('XSS');\\\">\"";
+               PortalRestResponse expectedPortalRestResponse = new PortalRestResponse<>();
+               expectedPortalRestResponse.setMessage("Provided data is invalid");
+               expectedPortalRestResponse.setStatus(PortalRestStatusEnum.ERROR);
+               Mockito.when(searchService.getWidgetData(resourceType)).thenReturn(null);
+               PortalRestResponse acutualPoratlRestResponse = dashboardSearchResultController
+                       .getWidgetData(mockedRequest, resourceType);
+               assertEquals(acutualPoratlRestResponse, expectedPortalRestResponse);
+       }
+
        @Test
        public void saveWidgetDataBulkIfCatrgoryNullTest() {
                PortalRestResponse<String> ecpectedPortalRestResponse = new PortalRestResponse<String>();
@@ -151,6 +163,82 @@ public class DashboardSearchResultControllerTest {
                assertEquals(ecpectedPortalRestResponse, actualPortalRestResponse);
        }
 
+       @Test
+       public void saveWidgetDataBulkXSSTest() {
+               PortalRestResponse<String> ecpectedPortalRestResponse = new PortalRestResponse<>();
+               ecpectedPortalRestResponse.setMessage("ERROR");
+               ecpectedPortalRestResponse.setResponse("Category is not valid");
+               ecpectedPortalRestResponse.setStatus(PortalRestStatusEnum.ERROR);
+
+               CommonWidgetMeta commonWidgetMeta = new CommonWidgetMeta();
+               commonWidgetMeta.setCategory("test");
+
+               List<CommonWidget> commonWidgetList = new ArrayList<>();
+               CommonWidget commonWidget = new CommonWidget();
+               commonWidget.setId((long) 1);
+               commonWidget.setCategory("test");
+               commonWidget.setHref("\"<IMG SRC=\\\"jav\\tascript:alert('XSS');\\\">\"");
+               commonWidget.setTitle("test_title");
+               commonWidget.setContent("test_content");
+               commonWidget.setEventDate(null);
+               commonWidget.setSortOrder(1);
+
+               commonWidgetList.add(commonWidget);
+
+               commonWidgetMeta.setItems(commonWidgetList);
+
+               Mockito.when(searchService.saveWidgetDataBulk(commonWidgetMeta)).thenReturn(null);
+
+               PortalRestResponse<String> actualPortalRestResponse = dashboardSearchResultController
+                       .saveWidgetDataBulk(commonWidgetMeta);
+               assertEquals(ecpectedPortalRestResponse, actualPortalRestResponse);
+       }
+
+       @Test
+       public void saveWidgetDataXSSTest() {
+               PortalRestResponse<String> expectedPortalRestResponse = new PortalRestResponse<>();
+               expectedPortalRestResponse.setMessage("ERROR");
+               expectedPortalRestResponse.setResponse("Category is not valid");
+               expectedPortalRestResponse.setStatus(PortalRestStatusEnum.ERROR);
+               CommonWidget commonWidget = new CommonWidget();
+               commonWidget.setId((long) 1);
+               commonWidget.setCategory("test");
+               commonWidget.setHref("\"<IMG SRC=\"jav\\tascript:alert('XSS');\">\"");
+               commonWidget.setTitle("test_title");
+               commonWidget.setContent("test_content");
+               commonWidget.setEventDate(null);
+               commonWidget.setSortOrder(1);
+
+               Mockito.when(searchService.saveWidgetData(commonWidget)).thenReturn(null);
+
+               PortalRestResponse<String> actualPortalRestResponse = dashboardSearchResultController
+                       .saveWidgetData(commonWidget);
+               assertEquals(expectedPortalRestResponse, actualPortalRestResponse);
+
+       }
+
+       @Test
+       public void deleteWidgetDataXSSTest() {
+               PortalRestResponse<String> expectedPortalRestResponse = new PortalRestResponse<>();
+               expectedPortalRestResponse.setMessage("ERROR");
+               expectedPortalRestResponse.setResponse("Data is not valid");
+               expectedPortalRestResponse.setStatus(PortalRestStatusEnum.ERROR);
+               CommonWidget commonWidget = new CommonWidget();
+               commonWidget.setId((long) 1);
+               commonWidget.setCategory("test");
+               commonWidget.setHref("test_href");
+               commonWidget.setTitle("\"<IMG SRC=\"jav\\tascript:alert('XSS');\">\"");
+               commonWidget.setContent("test_content");
+               commonWidget.setEventDate(null);
+               commonWidget.setSortOrder(1);
+               Mockito.when(searchService.deleteWidgetData(commonWidget)).thenReturn(null);
+
+               PortalRestResponse<String> actualPortalRestResponse = dashboardSearchResultController
+                       .deleteWidgetData(commonWidget);
+
+               assertEquals(expectedPortalRestResponse, actualPortalRestResponse);
+       }
+
        @Test
        public void saveWidgetDataIfCatagoryNullTest() {
                PortalRestResponse<String> ecpectedPortalRestResponse = new PortalRestResponse<String>();
@@ -339,6 +427,22 @@ public class DashboardSearchResultControllerTest {
 
        }
 
+       @Test
+       public void searchPortalXSS() {
+               EPUser user = mockUser.mockEPUser();
+               Mockito.when(EPUserUtils.getUserSession(mockedRequest)).thenReturn(user);
+               String searchString = "<script>alert(“XSS”)</script> ";
+
+               PortalRestResponse<Map<String, List<SearchResultItem>>> expectedResult = new PortalRestResponse<Map<String, List<SearchResultItem>>>();
+               expectedResult.setMessage("searchPortal: User object is invalid");
+               expectedResult.setStatus(PortalRestStatusEnum.ERROR);
+
+               PortalRestResponse<Map<String, List<SearchResultItem>>> actualResult = dashboardSearchResultController
+                       .searchPortal(mockedRequest, searchString);
+               assertEquals(actualResult, expectedResult);
+
+       }
+
        @Test
        public void searchPortalIfSearchExcptionTest() {
                EPUser user = mockUser.mockEPUser();