posthtml-expressions icon indicating copy to clipboard operation
posthtml-expressions copied to clipboard

Template injection vulnerability when using variables inside conditionals

Open felipeptcho opened this issue 1 year ago • 0 comments

Some of my variables come from user input. The user should be free to type any character, including the delimiters. But if they type expressions like "{{2*3}}", this can lead to template injection if we use those variables inside conditionals.

Example:

posthtml(expressions({ locals: { variable: '{{2*3}}' } })).process(`
  Here it works: {{variable}}
  <p>Here it works too: {{variable}}</p>

  <if condition="true">
    Here it doesn't work: {{variable}}
  </if>

  This is not documented and probably should only allow HTML characters: {{{variable}}}
`).then((result) => console.log(result.html))

Result:

  Here it works: {{2*3}}
  <p>Here it works too: {{2*3}}</p>
  
    Here it doesn't work: 6
  
  This is not documented and probably should only allow HTML characters: 6

According to my investigation, it seems that the content inside conditionals is being parsed twice by the walk() function.

  • So in the first pass: {{variable}} -> {{2*3}}
  • And in the next pass: {{2*3}} -> 6

felipeptcho avatar Apr 26 '23 00:04 felipeptcho