Marshmallow: fields.Boolean should accept only json booleans

Created on 3 Aug 2018  ·  4Comments  ·  Source: marshmallow-code/marshmallow

I don't see a point to allow fields.Boolean to accept values like 'F', 'f', '0', 0, 0.0 and etc. as valid ones. Why such decision was made?

feedback welcome

Most helpful comment

Having an expressive API is convenient, but one of the core concepts of usable security is that the easiest option should be the secure option. When considering how marshmallow is used to guard applications against untrusted data, unexpected behavior can lead to vulnerabilities. This part of the API is an example of convenience being easier than strictness, which means security is degraded by default. Marshmallow can be convenient _and_ secure, but I think it needs to be secure _then_ convenient.

All 4 comments

A lot of the fields in marshmallow do not strictly validate the type and attempt to coax the value to the field type for convenience. Boolean supports stricter use cases by allowing you to specify the exact values to allow for True and False using the truthy and falsy arguments.

https://marshmallow.readthedocs.io/en/3.0/api_reference.html#marshmallow.fields.Boolean

I have mentioned in a discussion before (can't find a link to it) that this kind of behavior represents an opinion and is not necessarily expected behavior for a validation library.

I think the primitive fields should have strict type enforcement and specialized fields should be used to explicitly parse a value from one type to another. We could still offer convenient field types, but their names should communicate the complexity that comes with the convenience. Something like BooleanAny = Union(Boolean, BooleanString, BooleanNumber).

JSON is only one of many possible formats we can use. I have a code that works with .ini files and uses Marshmallow for validation, I need this functionality.

Having an expressive API is convenient, but one of the core concepts of usable security is that the easiest option should be the secure option. When considering how marshmallow is used to guard applications against untrusted data, unexpected behavior can lead to vulnerabilities. This part of the API is an example of convenience being easier than strictness, which means security is degraded by default. Marshmallow can be convenient _and_ secure, but I think it needs to be secure _then_ convenient.

I was also surprised to learn that Boolean allowed a wide range of values by default. Given it's a validation library, I thought it would be more limiting by default. Perhaps there could be a strict=True option like Integer? In which it only validates against JSON and truthy={"true", True} and falsy={"false", False}?

Or perhaps there could be additional built in sets, for example marshmallow.fields.Boolean.truthyJSON = {"true"}.

I could also get behind additional Boolean types like BooleanString, BooleanNumber, etc, and being explicit that way.

Was this page helpful?
0 / 5 - 0 ratings