Search code examples
javascriptnode.jsdust.js

dust.js are random user uploaded templates secure to execute server side?


I want to allow my users to upload their own dust templates.

Right now I compile and store them in a database. I then load them from the database and execute them as needed.

My platform server side is node.js.

Could a user insert malicious data in a template that would arm my running node.js process? Infinite loops? Code Injection?

Thanks


Solution

  • It is not possible for a user-generated template to contain anything evil or harmful; the template will simply not compile in most cases. Templates always compile to safe, Dust-generated strings.

    However, if you allow users to provide their own data to pass to the templates, there could be a risk. Dust runs any functions it finds in the render context and you could write unescaped HTML like this:

    {
      "foo": function(chunk) {
        return chunk.write("<script src='evil'>");
      }
    }
    

    So a user could insert a script tag somewhere and introduce an XSS.

    If you render templates server-side, Dust runs the rendering process as part of the main event loop, so a context function has access to anything in scope at that time...

    {
      "foo": function(chunk) {
        console.log("I'm writing to the server console!");
        dust.log("Spammin' ur logz", "ERROR");
        chunk.write("I'm stealing ur keyz: " + SECRET_API_KEY);
        database.eraseAllTheThings({ howMany: "all of them", yaRly: true });
      }
    }
    

    To protect against this, it's best to use the vm module to isolate the render from your main Node script when you allow users to provide their own data. You could also run the render in a separate process. Or you could force the data to be JSON-only.

    A template by itself cannot be harmful, compiled or uncompiled. The only possible attack would be to provide a template of extreme size (hundreds of MB) and just DoS your server.

    If you provided helpers that were written poorly, your helpers could hang indefinitely if provided with the correct template invocation:

    {@loop from=1 to=999999999999999999999999999999999999999999999}{/loop}
    

    The solution to this is to run the render in a separate process with a timeout.

    tl;dr templates only, vanilla Dust, you're safe.