Skip to content

Reviver function upon import? #5

@ghost

Description

Could it be possible to use a reviver function upon importing the JSON module?

Maybe another option, in line with the assertions proposal; ex:

const json = await import("./data.json", { assert: { type: "json" }, reviver() { ... } });

The author may want the reviver to be called before the object is placed into the import graph. So that all imports may now yield the revived object for efficiency and performance.

But at that point, it could very well be debated that the author ought to be using a normal ECMAScript/Wasm export:

export default JSON.parse(
    await fetch(
        "./data.json", {
            mode: "cors"
        }
    ), () => { ... }
);

But, paired with @devsnek's suggestion about using a reviver function in the record/tuple proposal, this could be the key to resolving all of the immutability/mutability debates (#1, #2, #3, etc), possibly pleasing the average developer's expectations, while still providing the extra (small) step to make sure that interested developers don't shoot themselves in the foot by using an immutable object instead.

But I do believe that not freezing them or making them immutable becomes a security vulnerability.

For example, a web page author has a large, server-generated JSON module that is needed only upon the user interacting with a specific part of the page.

JSON module contents:

[ "foo", "bar", "quz" ]

They don't want to import it unless it's necessary due to both, server-side and client-side performance and resource costs, so they choose to lazily import it using a dynamic import call, only once the user has interacted with the page.

Example ECMAScript:

async function onClick (clickEvent) {
    const serverData = await import( "./serverData.json" );

    const firstCharacter = serverData[0][0];
}

But, before it was ever imported by the author's code, another module had imported it and modified it:

import serverData from "./serverData.json";

serverData[0] = new Proxy(
    {}, {
        get: do_something_obscurely_malicous_with_attempted_key_access
    },
    ...
);

It could probably be exploited by malicious actors.

But, even if they had accessed it, parsing it into a Tuple first would've thrown a TypeError, as proxies cannot be inside of a tuple/record, safely preventing whatever the malicious actor planned on doing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions