npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@handlebars/allow-prototype-access

v1.0.5

Published

Revert a Handlebars-instance ^4.6.0 to the proto-accessing behavior of 4.5.3

Downloads

13,809

Readme

@handlebars/allow-prototype-access

NPM version

Revert a Handlebars-instance ^4.6.0 to the proto-accessing behavior of 4.5.3

This package allows you to create a new Handlebars instance, that behaves like version 4.5.3 and allows access to the prototype

Why?

In the past, Handlebars would allow you to access prototype methods and properties of the input object form the template.

start{{aString.trim}}end

with the input

{
    aString: '   abc    '
}

would result in the output startabcend.

Multiple security issues have come from this behaviour. Details can be found in the npm-security advisories 755, 1164, 1316, 1324 and 1325 and in the blog-article of Mahmoud Gamal.

Those issues have been fixed, but we cannot be sure that there are ways around the fixes. That's why, in handlebars@^4.6.0. access to the object prototype has been disabled completely.

Now, if you use custom classes as input to Handlebars, your code won't work anymore.

class TestClass {
  aMethod() {
    return "returnValue";
  }
}

const Handlebars = require("handlebars");
const template = Handlebars.compile("start {{aMethod}} end");
const output = template(new TestClass());

console.log(output);
Handlebars: Access has been denied to resolve the property "aMethod" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
start  end

This has now led to a number of problems for projects like typedoc, because they are using such classes as input for the template.

This package automatically adds runtime options to each template-calls, disabling the security restrictions.

When NOT to use it?

The question is: Who is writing the templates that Handlebars is executing? Is it only your developers? Is it the user?

The leak published in npm advisory 755 meant that somebody writing a template could effectively execute code inside your server. Although the disclosed exploits have been fixed, new exploits have become much more probable, now that the principle is well-known, so:

If your users are writing templates and you execute them on your server you should NOT use this package, but rather find other ways to solve the problem. I suggest you convert your class-instances to plain JavaScript objects before passing them to the template function. Every property or function you access, must be an "own property" of its parent.

class TestClass {
  aMethod() {
    return "returnValue";
  }

  asTemplateInput() {
    return {
      aMethod: this.aMethod.bind(this)
    };
  }
}

const Handlebars = require("handlebars");

const template = Handlebars.compile("{{aMethod}}");
const output = template(new TestClass().asTemplateInput());

console.log(output);

Installation

npm install @handlebars/allow-prototype-access

Usage (plain Handlebars)

The following example demonstrates how to use this module:

class TestClass {
  aMethod() {
    return "returnValue";
  }
}

const Handlebars = require('handlebars')
const {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype-access')
const insecureHandlebars = allowInsecurePrototypeAccess(Handlebars)

const template = insecureHandlebars.compile('{{aMethod}}')
const output = template(new TestClass);

console.log(output)

This will generate the following output

returnValue

Usage (express-handlebars and mongoose)

Recommended solution

The recommended solution for this constellation is not to use this package, but to use the lean()-method on Mongoose-queries. See https://mongoosejs.com/docs/tutorials/lean.html for details. This will ensure, that all properties passed to the template are "own"-properties

Alternative

express-handlebars does not allow you to specify runtime-options to pass to the template function. This package can help you disable prototype checks for you models.

Only do this, if you have full control over the templates that are executed in the server.

const express = require('express');
const Handlebars = require('handlebars')
const expressHandlebars = require('express-handlebars');
const {allowInsecurePrototypeAccess} = require('@handlebars/allow-prototype-access')

const app = express();

app.engine('handlebars', expressHandlebars({
    handlebars: allowInsecurePrototypeAccess(Handlebars)
}));
app.set('view engine', 'handlebars');
...

License

@handlebars/allow-prototype-access is published under the MIT-license.

See LICENSE.md for details.

Contributing guidelines

See CONTRIBUTING.md.