JSON Schemas can be vulnerable to DoS attacks in case if slow validation steps are performed without proper restrictions.
In that case, the attacker can purposely spam the validator with JSON data which would slow the validation logic down significantly and cause a DoS.
Such slow steps are, for example:
pattern
validation for complex patterns (e.g. those that could contain ReDoS),patternProperties
for the same reason aspattern
,format
if format validation is slow (which shouldn't be true for build-in formats).uniqueItems
validation for arrays
There are exceptions:
pattern
/format
/patternProperties
are fine if the regex they contain are definitely not vulnerable to ReDoSpattern
/format
should be fine if the string length is limited to a small enough numberpatternProperties
should be fine if combined withpropertyNames
limiting the property names lengths to a small enough numberuniqueItems
items should be fine ifmaxItems
is limited to a small enough numberuniqueItems
items should be fine it the array includes only primitive values
See e.g. ajv meta-schema for reference on schema pre-validation approach.
Drawbacks of that approach (apart of shared limitations):
- Does not follow refs, i.e.:
- All schemas referenced from the top-level one should be checked separately.
- Subschemas placed anywhere but
definitions
might be not checked.
- Overall, it might miss other parts of schemas that are actually used, as complexity/slowness checks are decoupled from actual code generation -- that could give both false positives and false negatives.
This library supports performing basic complexity checks similar to what the above-mentioned ajv meta-schema does, but closely integrated with code generation.
Restriciting the length of input
safe-regex
package is not a sufficient check for regular expressions, as it has both known
false negatives and false positives.
There isn't a 100% reliable RegExp pattern check against ReDoS, but consulting this list could be helful, e.g. RegexStaticAnalysis.
This library expects format
functions to perform own length checks,
and allows regular expressions with less than two repetition groups.
By default, complexity checks are disabled unless in strong mode.
They could be enabled via the complexityChecks: true
option.
Note that this won't protect against:
-
Exponential patterns which can get out of hand very fast even on short strings.
E.g.
/^(a*)*b$/
is freezing for several seconds even on input with length30
. -
Too large numbers being passed as string or array maximum length.
E.g. a quadratic ReDoS like
/^a*a*$/
can be mitigated with two-digit length restrictions, but settingmaxLength
to e.g.80000
won't make the situation much better. -
Slow formats impelemnted via functions.
Formats implemented via functions are not validated at all and are supposed to be safe. Slow functions won't be catched and
maxLength
requirement does not apply to functions.
Complexity checks don't guarantee that the schema is safe against DoS, they just help to notice potential problems which could lead to DoS vulnerabilities.