Validation for entity's additionalInfo
This commit is contained in:
		
							parent
							
								
									6a75cd076f
								
							
						
					
					
						commit
						e7995fb02c
					
				@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 | 
				
			|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
					import com.fasterxml.jackson.databind.ObjectMapper;
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.UUIDBased;
 | 
					import org.thingsboard.server.common.data.id.UUIDBased;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.validation.NoXss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.ByteArrayInputStream;
 | 
					import java.io.ByteArrayInputStream;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@ -36,6 +37,7 @@ import java.util.function.Consumer;
 | 
				
			|||||||
public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> extends SearchTextBased<I> implements HasAdditionalInfo {
 | 
					public abstract class SearchTextBasedWithAdditionalInfo<I extends UUIDBased> extends SearchTextBased<I> implements HasAdditionalInfo {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static final ObjectMapper mapper = new ObjectMapper();
 | 
					    public static final ObjectMapper mapper = new ObjectMapper();
 | 
				
			||||||
 | 
					    @NoXss
 | 
				
			||||||
    private transient JsonNode additionalInfo;
 | 
					    private transient JsonNode additionalInfo;
 | 
				
			||||||
    @JsonIgnore
 | 
					    @JsonIgnore
 | 
				
			||||||
    private byte[] additionalInfoBytes;
 | 
					    private byte[] additionalInfoBytes;
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
package org.thingsboard.server.dao.service;
 | 
					package org.thingsboard.server.dao.service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.databind.JsonNode;
 | 
				
			||||||
import lombok.extern.slf4j.Slf4j;
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.owasp.validator.html.AntiSamy;
 | 
					import org.owasp.validator.html.AntiSamy;
 | 
				
			||||||
import org.owasp.validator.html.Policy;
 | 
					import org.owasp.validator.html.Policy;
 | 
				
			||||||
@ -48,12 +49,18 @@ public class NoXssValidator implements ConstraintValidator<NoXss, Object> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
 | 
					    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
 | 
				
			||||||
        if (!(value instanceof String) || ((String) value).isEmpty()) {
 | 
					        String stringValue;
 | 
				
			||||||
 | 
					        if (value instanceof CharSequence || value instanceof JsonNode) {
 | 
				
			||||||
 | 
					            stringValue = value.toString();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (stringValue.isEmpty()) {
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            return xssChecker.scan((String) value, xssPolicy).getNumberOfErrors() == 0;
 | 
					            return xssChecker.scan(stringValue, xssPolicy).getNumberOfErrors() == 0;
 | 
				
			||||||
        } catch (ScanException | PolicyException e) {
 | 
					        } catch (ScanException | PolicyException e) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,23 +15,16 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
package org.thingsboard.server.dao.service;
 | 
					package org.thingsboard.server.dao.service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.junit.jupiter.api.BeforeAll;
 | 
					import com.fasterxml.jackson.databind.node.TextNode;
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
import org.junit.jupiter.params.ParameterizedTest;
 | 
					import org.junit.jupiter.params.ParameterizedTest;
 | 
				
			||||||
import org.junit.jupiter.params.provider.ValueSource;
 | 
					import org.junit.jupiter.params.provider.ValueSource;
 | 
				
			||||||
 | 
					import org.thingsboard.common.util.JacksonUtil;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.asset.Asset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.validation.ConstraintValidatorContext;
 | 
					import static org.assertj.core.api.Assertions.assertThatThrownBy;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
 | 
					 | 
				
			||||||
import static org.mockito.Mockito.mock;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class NoXssValidatorTest {
 | 
					public class NoXssValidatorTest {
 | 
				
			||||||
    private static NoXssValidator validator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @BeforeAll
 | 
					 | 
				
			||||||
    public static void beforeAll() {
 | 
					 | 
				
			||||||
        validator = new NoXssValidator();
 | 
					 | 
				
			||||||
        validator.initialize(null);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ParameterizedTest
 | 
					    @ParameterizedTest
 | 
				
			||||||
    @ValueSource(strings = {
 | 
					    @ValueSource(strings = {
 | 
				
			||||||
@ -44,9 +37,25 @@ public class NoXssValidatorTest {
 | 
				
			|||||||
            "   <img src= \"http://site.com/\"  >  ",
 | 
					            "   <img src= \"http://site.com/\"  >  ",
 | 
				
			||||||
            "123 <input type=text value=a onfocus=alert(1337) AUTOFOCUS>bebe"
 | 
					            "123 <input type=text value=a onfocus=alert(1337) AUTOFOCUS>bebe"
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    public void testIsNotValid(String stringWithXss) {
 | 
					    public void givenEntityWithMaliciousPropertyValue_thenReturnValidationError(String maliciousString) {
 | 
				
			||||||
        boolean isValid = validator.isValid(stringWithXss, mock(ConstraintValidatorContext.class));
 | 
					        Asset invalidAsset = new Asset();
 | 
				
			||||||
        assertFalse(isValid);
 | 
					        invalidAsset.setName(maliciousString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThatThrownBy(() -> {
 | 
				
			||||||
 | 
					            ConstraintValidator.validateFields(invalidAsset);
 | 
				
			||||||
 | 
					        }).hasMessageContaining("field value is malformed");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenEntityWithMaliciousValueInAdditionalInfo_thenReturnValidationError() {
 | 
				
			||||||
 | 
					        Asset invalidAsset = new Asset();
 | 
				
			||||||
 | 
					        String maliciousValue = "qwerty<script>alert(document.cookie)</script>qwerty";
 | 
				
			||||||
 | 
					        invalidAsset.setAdditionalInfo(JacksonUtil.newObjectNode()
 | 
				
			||||||
 | 
					                .set("description", new TextNode(maliciousValue)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThatThrownBy(() -> {
 | 
				
			||||||
 | 
					            ConstraintValidator.validateFields(invalidAsset);
 | 
				
			||||||
 | 
					        }).hasMessageContaining("field value is malformed");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user