diff --git a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java index 5e2be64c61b..1970fb12716 100644 --- a/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java +++ b/commons/commons-security/src/main/java/fr/gouv/vitamui/common/security/SanityChecker.java @@ -65,10 +65,11 @@ public class SanityChecker { private static final String INVALID_CRITERIA = "Criteria failed when sanitizing, it may contains insecure data : "; private static final String JSON_IS_NOT_VALID_FROM_SANITIZE_CHECK = "Json is not valid from Sanitize check"; - private static final int DEFAULT_LIMIT_PARAMETER_SIZE = 5000; - private static final int DEFAULT_LIMIT_FIELD_SIZE = 10000000; - private static final int DEFAULT_LIMIT_JSON_SIZE = 16000000; - private static final long DEFAULT_LIMIT_FILE_SIZE = 8000000000L; + private static final int DEFAULT_LIMIT_PARAMETER_SIZE = 5_000; + private static final int DEFAULT_LIMIT_FIELD_SIZE = 10_000_000; + private static final int DEFAULT_LIMIT_JSON_SIZE = 16_000_000; + private static final long DEFAULT_LIMIT_FILE_SIZE = 8_000_000_000L; + private static final int DEFAULT_LIMIT_FIELD_NUMBER = 100_000; public static final String HTTP_PARAMETER_VALUE = "HTTPParameterValue"; @@ -83,6 +84,10 @@ public class SanityChecker { * max size of Json or Xml value field */ private static int limitFieldSize = DEFAULT_LIMIT_FIELD_SIZE; + /** + * max number of Json fields + */ + private static int limitFieldNumber = DEFAULT_LIMIT_FIELD_NUMBER; /** * max size of parameter value field (low) */ @@ -423,7 +428,8 @@ public static void checkJsonSanity(JsonNode json) throws InvalidParseOperationEx } } else { final Iterator> fields = json.fields(); - while (fields.hasNext()) { + int i = 0; + while (i++ < limitFieldNumber && fields.hasNext()) { final Map.Entry entry = fields.next(); final String key = entry.getKey(); if (isValidParameter(key)) { @@ -451,6 +457,11 @@ public static void checkJsonSanity(JsonNode json) throws InvalidParseOperationEx validateJSONField(value); } } + if (fields.hasNext()) { + throw new PreconditionFailedException( + String.format("Invalid JSON. Too many fields (>%s)", limitFieldNumber) + ); + } } } @@ -506,4 +517,18 @@ public static int getLimitParamSize() { public static void setLimitParamSize(int limitParamSize) { SanityChecker.limitParamSize = limitParamSize; } + + /** + * @return the limit number of fields of a Json + */ + public static int getLimitFieldNumber() { + return limitFieldNumber; + } + + /** + * @param limitFieldNumber the limit number of fields of a Json + */ + public static void setLimitFieldNumber(int limitFieldNumber) { + SanityChecker.limitFieldNumber = limitFieldNumber; + } } diff --git a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java index abd70113c6c..673d3999e8f 100644 --- a/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java +++ b/commons/commons-security/src/test/java/fr/gouv/vitamui/commons/security/SanityCheckerTest.java @@ -61,6 +61,17 @@ public void givenJsonWhenValueIsTooBigORContainXMLTag() assertThatCode(() -> SanityChecker.checkJsonSanity(json)).isInstanceOf(PreconditionFailedException.class); } + @Test + public void givenJsonWhenFieldNumberIsTooBig() throws InvalidParseOperationException, PreconditionFailedException { + final int initialLimitFieldNumber = SanityChecker.getLimitFieldNumber(); + final JsonNode json = JsonHandler.getFromString("{\"1\":1,\"2\":2,\"3\":3,\"4\":4,\"5\":5}"); + SanityChecker.setLimitFieldNumber(5); + assertThatCode(() -> SanityChecker.checkJsonSanity(json)).doesNotThrowAnyException(); + SanityChecker.setLimitFieldNumber(4); + assertThatCode(() -> SanityChecker.checkJsonSanity(json)).isInstanceOf(PreconditionFailedException.class); + SanityChecker.setLimitFieldNumber(initialLimitFieldNumber); + } + @Test public void givenJsonWhenValueIsTooBigORContainXMLTagUsingAll() throws InvalidParseOperationException, IOException { final File file = PropertiesUtils.findFile(TEST_BAD_JSON);