taoqf / node-html-parser

A very fast HTML parser, generating a simplified DOM, with basic element query support.
MIT License
1.11k stars 107 forks source link

Prototype pollution #129

Closed Baker68 closed 2 years ago

Baker68 commented 3 years ago
// `<div id="test" ><a href="https://www.google.com" __proto__="polluted=true>test</a></div>`;
const test = `<div id="test" __proto__="true><a href="https://www.google.com" __proto__="polluted=true">test</a></div>`;
const documentRoot = parse(test, {
  lowerCaseTagName: true, 
  comment: false,
  blockTextElements: {
    script: false,
    noscript: false,
    style: true,
  },
});
const childElement = documentRoot.querySelector(`#test`);
const rootElement = <HTMLElement>(<unknown>childElement.childNodes[0]);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
console.log('attributes.polluted = ', rootElement.attributes.polluted);
// output : 
//         attributes.polluted =  true"

I`m don't think it can lead to a remote code execution, but I think that you should prevent this.

Other examples :

const test = `<div id="test" __proto__="true><a href="https://www.google.com" __proto__="toString()=global.process.exit)>test</a></div>`;
console.log('attributes = ', rootElement.attributes);
// attributes =  {
  href: 'https://www.google.com',
  toString: '',
  global: '',
  process: '',
  exit: ''
}
const test = `<div id="test" __proto__="true><a href="https://www.google.com" __proto__="__proto__.href=http://www.example.com/>test</a></div>`;
console.log('attributes = ', rootElement.attributes);
// attributes =  { href: 'http://www.example.com' }
taoqf commented 3 years ago

Thanks for your report. I wish I could prevent this, but actually I realize I cann't. This issue is same as https://github.com/taoqf/node-html-parser/issues/51 . it's not due to the attribute__proto__ but = in attribute value.

nonara commented 3 years ago

This is a different issue, I think. Just requires checking if attribute name === '__proto__' and rejecting it

nonara commented 2 years ago

Corrected in v5