Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

esbuild@0.20.1 prototype setting when bundling json containing a __proto__ key #3700

Closed
lucacasonato opened this issue Mar 14, 2024 · 6 comments

Comments

@lucacasonato
Copy link
Contributor

const DATA = `{
  "hello": "world",
  "__proto__": {
    "sky": "universe"
  }
}
`;

import * as esbuild0_20_0 from "npm:esbuild@0.20.0";
console.log(esbuild0_20_0.version);
const res0_20_0 = await esbuild0_20_0.build({
  stdin: {
    contents: DATA,
    loader: "json",
  },
  format: "esm",
  write: false,
  absWorkingDir: Deno.cwd(),
});
console.log(res0_20_0.outputFiles[0].text);

import * as esbuild0_20_1 from "npm:esbuild@0.20.1";
console.log(esbuild0_20_1.version);
const res0_20_1 = await esbuild0_20_1.build({
  stdin: {
    contents: DATA,
    loader: "json",
  },
  format: "esm",
  write: false,
  absWorkingDir: Deno.cwd(),
});
console.log(res0_20_1.outputFiles[0].text);
>>> deno run -A test.ts
0.20.0
var hello = "world";
var __proto__ = {
  sky: "universe"
};
var stdin_default = {
  hello,
  __proto__
};
export {
  __proto__,
  stdin_default as default,
  hello
};

0.20.1
var hello = "world";
var __proto__ = {
  sky: "universe"
};
var stdin_default = {
  hello,
  __proto__: __proto__
};
export {
  __proto__,
  stdin_default as default,
  hello
};

In the 0.20.1 output, the __proto__ field of the JSON is incorrectly written as __proto__: __proto__. This sets the prototype of stdin_default rather than a __proto__ key, like was happening in 0.20.0 and below.

This may be a security issue if users bundle untrusted JSON files into their code (but probably not that bad).

@lucacasonato lucacasonato changed the title esbuild@0.20.1 prototype pollution when bundling json containing a __proto__ key esbuild@0.20.1 prototype setting when bundling json containing a __proto__ key Mar 14, 2024
@lucacasonato
Copy link
Contributor Author

Was broken by ac36537. Discovered through tests in https://github.com/lucacasonato/esbuild_deno_loader

@evanw
Copy link
Owner

evanw commented Mar 14, 2024

Hmm, I think this perhaps never really worked. Version 0.20.0 can generate incorrect output as well. Thanks for the report! I'll fix this in the next release.

@evanw evanw closed this as completed in 4780075 Mar 14, 2024
@lucacasonato
Copy link
Contributor Author

Thanks @evanw for the quick fix!

@hai-x
Copy link

hai-x commented Dec 26, 2024

Sorry, I want to ask a question here. Is there some relevant spec indicated that we need compute property key in some case such as __proto__? Just for curiosity. I found that it behaves differently in es5 and es6.

@evanw
Copy link
Owner

evanw commented Dec 26, 2024

I believe the relevant part of the JavaScript specification is here:

PropertyDefinition : PropertyName : AssignmentExpression

  1. Let propKey be ? Evaluation of PropertyName.
  2. If this PropertyDefinition is contained within a Script that is being evaluated for JSON.parse (see step 7 of JSON.parse), then
    a. Let isProtoSetter be false.
  3. Else if propKey is "__proto__" and IsComputedPropertyKey of PropertyName is false, then
    a. Let isProtoSetter be true.
  4. Else,
    a. Let isProtoSetter be false.

@hai-x
Copy link

hai-x commented Dec 27, 2024

I believe the relevant part of the JavaScript specification is here:

PropertyDefinition : PropertyName : AssignmentExpression

  1. Let propKey be ? Evaluation of PropertyName.
  2. If this PropertyDefinition is contained within a Script that is being evaluated for JSON.parse (see step 7 of JSON.parse), then
    a. Let isProtoSetter be false.
  3. Else if propKey is "proto" and IsComputedPropertyKey of PropertyName is false, then
    a. Let isProtoSetter be true.
  4. Else,
    a. Let isProtoSetter be false.

Got it. Thank u.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants