diff options
author | vasraz <vasyl.razinkov@est.tech> | 2022-10-14 13:35:39 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-10-18 08:27:16 +0000 |
commit | ddb9d5a7637b382be9ac7a96ad023a983c41c342 (patch) | |
tree | 4e551d6ce4348aed56f42b021bbe4fcfccc3cd15 /catalog-be | |
parent | ccab3629426bdc6a87ca6102db3fdb23d4419b3e (diff) |
Fix security risk 'Improper Input Validation'
Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech>
Change-Id: I6a52148aec3b567db43ec57109214e52d106f73c
Issue-ID: SDC-4189
Diffstat (limited to 'catalog-be')
12 files changed, 160 insertions, 12 deletions
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 532ee3ecac..75f8904519 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2411,7 +2411,7 @@ errors: # %1 - property name code: 400, message: 'Error: Invalid Content. %1 has invalid format.', - messageId: "SVC4723" + messageId: "SVC4731" } #---------SVC4734------------------------------ # %1 - list of validation errors @@ -2822,6 +2822,13 @@ errors: message: "Capability '%1' not found in '%2' '%3'." messageId: "SVC4186" + #---------SVC4001------------------------------ + NOT_PERMITTED_SPECIAL_CHARS: { + code: 406, + message: 'Error: HTML elements not permitted in field values.', + messageId: "SVC4001" + } + # %1 - The data type Uid DATA_TYPE_NOT_FOUND: code: 404 diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb index 5706a16553..9a2437c2c1 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb @@ -1293,5 +1293,8 @@ externalCsarStore: #This configuration specifies the delimiter used to differentiate instance name and count componentInstanceCounterDelimiter: " " +# Comma separated list of excluded URLs by the DataValidatorFilter +dataValidatorFilterExcludedUrls: "/healthCheck,/followed,/authorize" + #Space separated list of permitted ancestors permittedAncestors: <%= @permittedAncestors %> diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ByActionStatusComponentException.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ByActionStatusComponentException.java index e973fe4bf3..bd0e6bb20c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ByActionStatusComponentException.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ByActionStatusComponentException.java @@ -20,12 +20,14 @@ package org.openecomp.sdc.be.components.impl.exceptions; import java.util.Arrays; +import lombok.Getter; import org.openecomp.sdc.be.components.impl.ResponseFormatManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.exception.ResponseFormat; public class ByActionStatusComponentException extends ComponentException { + @Getter private final ActionStatus actionStatus; private final String[] params; @@ -35,10 +37,6 @@ public class ByActionStatusComponentException extends ComponentException { this.params = params.clone(); } - public ActionStatus getActionStatus() { - return actionStatus; - } - public String[] getParams() { return params.clone(); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeRestrictionAccessFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeRestrictionAccessFilter.java index e40dfe408f..0e8f9452be 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeRestrictionAccessFilter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeRestrictionAccessFilter.java @@ -33,7 +33,7 @@ import org.springframework.stereotype.Component; @Component("beRestrictionAccessFilter") public class BeRestrictionAccessFilter extends RestrictionAccessFilter { - private static final Logger log = Logger.getLogger(RestrictionAccessFilter.class.getName()); + private static final Logger log = Logger.getLogger(BeRestrictionAccessFilter.class.getName()); public BeRestrictionAccessFilter(FilterConfiguration configuration, ThreadLocalUtils threadLocalUtils, PortalClient portalClient) { super(configuration, threadLocalUtils, portalClient); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/DataValidatorFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/DataValidatorFilter.java new file mode 100644 index 0000000000..2cdbf93d48 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/DataValidatorFilter.java @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.filters; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.common.filters.DataValidatorFilterAbstract; +import org.openecomp.sdc.common.util.DataValidator; +import org.openecomp.sdc.exception.NotAllowedSpecialCharsException; + +/** + * Implement DataValidatorFilter for back-end. + * Extends {@link DataValidatorFilterAbstract} + */ +public class DataValidatorFilter extends DataValidatorFilterAbstract { + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + try { + super.doFilter(request, response, chain); + } catch (NotAllowedSpecialCharsException e) { + throw new ByActionStatusComponentException(ActionStatus.NOT_PERMITTED_SPECIAL_CHARS); + } + } + + @Override + protected List<String> getDataValidatorFilterExcludedUrls() { + final String dataValidatorFilterExcludedUrls = ConfigurationManager.getConfigurationManager().getConfiguration() + .getDataValidatorFilterExcludedUrls(); + if (StringUtils.isNotBlank(dataValidatorFilterExcludedUrls)) { + return Arrays.asList(dataValidatorFilterExcludedUrls.split(",")); + } + return new ArrayList<>(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/GatewayFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/GatewayFilter.java index c5f0881caa..b675ec9a6e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/GatewayFilter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/GatewayFilter.java @@ -44,7 +44,7 @@ import org.springframework.stereotype.Component; @Component("gatewayFilter") public class GatewayFilter implements Filter { - private static final Logger log = Logger.getLogger(BeServletFilter.class); + private static final Logger log = Logger.getLogger(GatewayFilter.class); private Configuration.CookieConfig authCookieConf; private Configuration config; @Autowired diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java index 7bec5d5f09..7c9101df82 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java @@ -321,10 +321,8 @@ public class BeGenericServlet extends BasicServlet { protected String propertyToJson(Map.Entry<String, PropertyDefinition> property) { JSONObject root = new JSONObject(); - String propertyName = property.getKey(); PropertyDefinition propertyDefinition = property.getValue(); - JSONObject propertyDefinitionO = getPropertyDefinitionJSONObject(propertyDefinition); - root.put(propertyName, propertyDefinitionO); + root.put(property.getKey(), getPropertyDefinitionJSONObject(propertyDefinition)); propertyDefinition.getType(); return root.toString(); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/StorageExceptionMapper.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/StorageExceptionMapper.java index 18e5a15497..f89a1348db 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/StorageExceptionMapper.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/exception/StorageExceptionMapper.java @@ -35,7 +35,7 @@ import org.springframework.stereotype.Component; @Provider public class StorageExceptionMapper implements ExceptionMapper<StorageException> { - private static final Logger log = Logger.getLogger(DefaultExceptionMapper.class); + private static final Logger log = Logger.getLogger(StorageExceptionMapper.class); private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private final ComponentsUtils componentsUtils; diff --git a/catalog-be/src/main/resources/config/configuration.yaml b/catalog-be/src/main/resources/config/configuration.yaml index c34d6742a1..820034eca2 100644 --- a/catalog-be/src/main/resources/config/configuration.yaml +++ b/catalog-be/src/main/resources/config/configuration.yaml @@ -930,3 +930,6 @@ directives: #Space separated list of permitted ancestors permittedAncestors: "" + +# Comma separated list of excluded URLs by the DataValidatorFilter +dataValidatorFilterExcludedUrls: "/healthCheck,/followed,/authorize" diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 0081525647..0830dda7b4 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2411,7 +2411,7 @@ errors: # %1 - property name code: 400, message: 'Error: Invalid Content. %1 has invalid format.', - messageId: "SVC4723" + messageId: "SVC4731" } #---------SVC4734------------------------------ # %1 - list of validation errors @@ -2822,6 +2822,13 @@ errors: message: "Capability '%1' not found in '%2' '%3'." messageId: "SVC4186" + #---------SVC4001------------------------------ + NOT_PERMITTED_SPECIAL_CHARS: { + code: 406, + message: 'Error: HTML elements not permitted in field values.', + messageId: "SVC4001" + } + # %1 - The data type Uid DATA_TYPE_NOT_FOUND: code: 404 diff --git a/catalog-be/src/main/webapp/WEB-INF/web.xml b/catalog-be/src/main/webapp/WEB-INF/web.xml index 7cbfd1a920..9761b38043 100644 --- a/catalog-be/src/main/webapp/WEB-INF/web.xml +++ b/catalog-be/src/main/webapp/WEB-INF/web.xml @@ -20,6 +20,7 @@ org.glassfish.jersey.media.multipart.MultiPartFeature, org.openecomp.sdc.be.filters.BasicAuthenticationFilter, org.openecomp.sdc.be.filters.BeServletFilter, + org.openecomp.sdc.be.filters.DataValidatorFilter, org.openecomp.sdc.be.filters.ComponentsAvailabilityFilter, org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature, org.openecomp.sdc.be.servlets.exception.DefaultExceptionMapper, @@ -59,6 +60,7 @@ <param-value> org.glassfish.jersey.media.multipart.MultiPartFeature, org.openecomp.sdc.be.filters.BeServletFilter, + org.openecomp.sdc.be.filters.DataValidatorFilter, org.openecomp.sdc.be.filters.ComponentsAvailabilityFilter, org.openecomp.sdc.be.servlets.exception.DefaultExceptionMapper, org.openecomp.sdc.be.servlets.exception.ComponentExceptionMapper, @@ -149,6 +151,18 @@ <url-pattern>/sdc/*</url-pattern> </filter-mapping> + <filter> + <filter-name>dataValidatorFilter</filter-name> + <filter-class> + org.openecomp.sdc.be.filters.DataValidatorFilter + </filter-class> + </filter> + <filter-mapping> + <filter-name>dataValidatorFilter</filter-name> + <url-pattern>/sdc2/rest/*</url-pattern> + <url-pattern>/sdc/*</url-pattern> + </filter-mapping> + <error-page> <exception-type>java.lang.RuntimeException</exception-type> <location>/sdc2/rest/v1/catalog/handleException/</location> diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/utils/DataValidatorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/utils/DataValidatorTest.java new file mode 100644 index 0000000000..8804e49b4b --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/utils/DataValidatorTest.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2022 Nordix Foundation. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.servlets.utils; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.util.DataValidator; +import org.openecomp.sdc.common.util.SecureString; + +@ExtendWith(MockitoExtension.class) +class DataValidatorTest { + + @InjectMocks + private DataValidator dataValidator; + + @Test + void isValidSecureString() { + final SecureString secureString = new SecureString("<script>alert(“XSS”);</script>"); + assertFalse(dataValidator.isValid(secureString)); + } + + @Test + void isValidEPUser() { + final User user = new User(); + user.setEmail("“><script>alert(“XSS”)</script>"); + user.setUserId("<IMG SRC=”javascript:alert(‘XSS’);”>"); + user.setFirstName("<IMG SRC=javascript:alert(‘XSS’)> "); + assertFalse(dataValidator.isValid(user)); + } + +} |