Comments (3)
@bhamon Hi,
Currently, the Decode function has a minimum requirement that the value being passed match the following criteria.
- Be an instance of Object.prototype
- Not be an instance of a class constructor
const obj1 = { foo: new Date().toISOString() }
console.log(Value.Check(ArgsSchema, obj1))
console.log(Value.Decode(ArgsSchema, obj1))
const obj2 = Object.create(null) // not a Object.prototype
obj2.foo = new Date().toISOString()
console.log(Value.Check(ArgsSchema, obj2))
console.log(Value.Decode(ArgsSchema, obj2))
const obj3: any = new Map() // Object.constructor.name !== 'Object'
obj3.foo = new Date().toISOString()
console.log(Value.Check(ArgsSchema, obj3))
console.log(Value.Decode(ArgsSchema, obj3))
// { foo: 2024-05-08T03:51:07.532Z }
// true
// [Object: null prototype] { foo: '2024-05-08T03:51:07.541Z' }
// true
// Map(0) { foo: '2024-05-08T03:51:07.542Z' }
The "no class constructor" criteria is mostly there as TB cannot be assured it can reconstruct a class instance with interior members (noting internal private class members cannot be cloned). The Object.prototype requirement is mostly there to ensure properties are enumerable.
Do you think Decode should support the Object.create(null) case? Could the graphql-js instance be patched to be made compatible with the current critiera?
Let me know your thoughts.
S
from typebox.
Do you think Decode should support the Object.create(null) case?
I think such support would be nice as I think there are good reasons to use null prototypes with data someone might want to use with typebox.
I like to explicitly use null prototypes when dealing with data typed like Records to avoid various issues like the risk of false positives if someone uses "in" (ex: "toString" in {}
is true).
Doing this also can avoid risk of prototype pollution attacks. Imagine code trying to merge two deep object hierarchies while one explicitly has an own value under a key __proto__
, and the other code incorrectly tests for such a value using "in", resulting in merging the data from on object's __proto__
object into Object.prototype. Using a null prototype fixes this risk, which is a common source of real security issues.
MDN's page on Object calls out both this record/map like use-case and the risk of prototype pollution I mentioned above.
Thus I think it there are good reasons to use object with null prototypes, especially with record style data (where user data is used as keys), which is something that typebox has excellent support for. Therefore it seems like it would be nice for typebox to support null prototypes.
While I do use typebox and null prototype objects in the same project, I haven't actually used them together and hit this issue, but I reasonably could have, and would have been surprised that it didn't just work.
Also as this is my first post here, thanks for your work on TypeBox: I have both found it very useful as a library, but also very informative as something to learn from while working on my own typescript based strongly typed schema system.
from typebox.
@CraigMacomber Hi,
I like to explicitly use null prototypes when dealing with data typed like Records to avoid various issues like the risk of false positives if someone uses "in" (ex: "toString" in {} is true). ........ Doing this also can avoid risk of prototype pollution attacks. Imagine code trying to merge two deep object hierarchies while one explicitly has an own value under a key proto, and the other code incorrectly tests for such a value using "in", resulting in merging the data from on object's proto object into Object.prototype. Using a null prototype fixes this risk, which is a common source of real security issues.
Thanks for the detailed write up + rationale. This seems reasonable to me, and when looking at the OP's original use case, I guess it is somewhat surprising TB wasn't able to decode (or encode) in this scenario (the OPs use case is very reasonable). I do think TB was being overly strict in terms of it's definition of what could be reasonably decoded. As such, I've just pushed an update on 0.32.30 to extend it's definition to support objects with null prototypes.
Also as this is my first post here, thanks for your work on TypeBox: I have both found it very useful as a library, but also very informative as something to learn from while working on my own typescript based strongly typed schema system.
Ah thanks :)
@bhamon Hi,
As noted above, I've pushed an update to fix this on 0.32.30. Will close up this issue for now, but if you do run into any problems, feel free to ping on this thread.
All the best
S
from typebox.
Related Issues (20)
- UUID not accpeted as string HOT 2
- How to import just Decode? HOT 4
- How to check if a schema conforms? HOT 2
- email validation doesn't work? HOT 2
- `Value.Cast` casts to wrong schema when called with union of `Refs` HOT 1
- Support for `definitions`? HOT 1
- Cannot reference a recursive type HOT 7
- Cannot use .map() inside Union with Literal HOT 2
- Nested `Type.Intersect` Errors
- Incorrect inferred type for the empty object `Type.Object({})`. HOT 3
- `unevaluatedProperties` failed verification when combined with `Type.Intersect` and `Type.Union` HOT 2
- Types for both CJS and ESM cause ambiguity and prevent correct type resolution. HOT 7
- unique id for schemas generated with Type.Object() HOT 5
- Custom paths for custom validation errors
- Composite Union type does not work HOT 2
- Type.Recursive does not work with Type.Transform for StaticDecode
- Issue regarding nested objects when using Value.Default HOT 4
- Enum type inferred as never when using Type.Mapped() HOT 2
- Should `IsValueType` guard consider `Date`?
- ESNext target HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typebox.