StackStorm / StackStorm/st2

Jinja2 auto-escape disabled in spec_loader (CWE-79)

Open
#6,388 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
6.5k
Forks
787
PR merge metrics
No merged PRs in 30d

Description

Summary

Static analysis (Snyk SAST) identified that jinja2.Template is called without enabling auto-escaping in the spec loader utility, which could allow cross-site scripting (XSS) if rendered output is served in a web context.

Affected File

st2common/st2common/util/spec_loader.py (line 48)

def generate_spec(module_name, spec_file):
    spec_template = pkg_resources.resource_string(module_name, spec_file)
    if not isinstance(spec_template, str):
        spec_template = spec_template.decode()
    spec_string = jinja2.Template(spec_template).render(**ARGUMENTS)
    return spec_string

jinja2.Template() is instantiated without the autoescape parameter, which defaults to False. If the ARGUMENTS dictionary contains user-controlled values, they will be rendered without escaping.

Impact

If the generated spec output is served through the StackStorm API or web UI without additional escaping, user-controlled values in ARGUMENTS could inject HTML or JavaScript. The actual exploitability depends on how the output of generate_spec is consumed downstream.

This is a lower-severity finding if the spec templates are only used for internal API specification generation with trusted input. However, defense-in-depth principles recommend enabling auto-escaping regardless.

Recommended Fix

Use jinja2.Environment with auto-escaping enabled, or pass autoescape=True if the output is HTML. If the output is not HTML (e.g., YAML or JSON specs), use jinja2.select_autoescape to apply context-appropriate escaping:

from jinja2 import Environment, select_autoescape

env = Environment(autoescape=select_autoescape())
template = env.from_string(spec_template)
spec_string = template.render(**ARGUMENTS)

Or, if auto-escaping is genuinely not needed for this context, add an explicit comment and a # nosec annotation explaining why.

References

  • CWE-79: Improper Neutralization of Input During Web Page Generation
  • Detected by: Snyk Code (SAST)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in st2common/st2common/util/spec_loader.py at generate_spec and inspect how its generated specification output is consumed. Determine whether the templates produce HTML, YAML, or JSON before choosing context-appropriate escaping. Done means user-controlled values are safely handled, or an explicit rationale and nosec annotation documents why escaping is unnecessary.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.