Skip to content

fix(security): enable Jinja2 autoescape to prevent XSS in gepa sample#5526

Closed
k4w-wak wants to merge 1 commit into
google:mainfrom
k4w-wak:fix/jinja2-xss-autoescape
Closed

fix(security): enable Jinja2 autoescape to prevent XSS in gepa sample#5526
k4w-wak wants to merge 1 commit into
google:mainfrom
k4w-wak:fix/jinja2-xss-autoescape

Conversation

@k4w-wak

@k4w-wak k4w-wak commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Security Fix: XSS via Jinja2 Template Injection (CWE-79)

Vulnerability

contributing/samples/gepa/rater_lib.py instantiates jinja2.Environment() without autoescape=True. The companion template rubric_validation_template.txt renders {{user_input}} and {{model_response}} without escaping.

Impact

Since ADK is Google's official framework for building AI agents, developers copy/adapt this sample code into production web applications. Unescaped user-controlled input in Jinja2 templates enables:

  • Cross-Site Scripting (XSS) — Arbitrary JavaScript execution in browsers
  • Session Hijacking — Steal cookies/tokens if rendered in web context
  • Phishing — Inject fake login forms

Proof of Concept

# user_input: <script>alert("XSS")</script>
# Renders as: <main_prompt><script>alert("XSS")</script></main_prompt>

# model_response: <img src=x onerror=alert("XSS from model")>
# Renders as: <responses><img src=x onerror=alert("XSS from model")></responses>

Changes

  1. rater_lib.py:170jinja2.Environment()jinja2.Environment(autoescape=True)
  2. rubric_validation_template.txt:158{{user_input}}{{user_input|e}}
  3. rubric_validation_template.txt:163{{model_response}}{{model_response|e}}

Defense in depth: autoescape=True provides baseline protection, explicit |e filters ensure escaping even if autoescape is later disabled.

References

@google-cla

google-cla Bot commented Apr 28, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@k4w-wak

k4w-wak commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

I have signed the Google CLA. Please re-check.

@k4w-wak k4w-wak force-pushed the fix/jinja2-xss-autoescape branch 2 times, most recently from 7a9cb7f to d203843 Compare April 28, 2026 20:15
@rohityan rohityan self-assigned this Apr 30, 2026
@rohityan rohityan requested a review from Jacksunwei May 8, 2026 23:10
@rohityan rohityan added the needs review [Status] The PR/issue is awaiting review from the maintainer label May 8, 2026
@rohityan

rohityan commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Hi @k4w1992-lgtm , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Your PR has been received by the team and is currently under review. We will provide feedback as soon as we have an update to share.

@rohityan

rohityan commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Hi @Jacksunwei , can you please review this.

@DeanChensj DeanChensj assigned DeanChensj and unassigned rohityan Jun 12, 2026
CWE-79 (Cross-Site Scripting)

The gepa rater_lib.py instantiated jinja2.Environment() without autoescape=True,
allowing user_input and model_response to be rendered as raw HTML.

This fix:
- Enable autoescape=True in jinja2.Environment()
- Add explicit |e filters to {{user_input}} and {{model_response}} as defense-in-depth
@DeanChensj DeanChensj force-pushed the fix/jinja2-xss-autoescape branch from b103803 to b5b6d3e Compare June 12, 2026 22:29
copybara-service Bot pushed a commit that referenced this pull request Jul 6, 2026
Merge #5526

## Security Fix: XSS via Jinja2 Template Injection (CWE-79)

### Vulnerability
`contributing/samples/gepa/rater_lib.py` instantiates `jinja2.Environment()` **without** `autoescape=True`. The companion template `rubric_validation_template.txt` renders `{{user_input}}` and `{{model_response}}` without escaping.

### Impact
Since ADK is Google's official framework for building AI agents, developers copy/adapt this sample code into production web applications. Unescaped user-controlled input in Jinja2 templates enables:

- **Cross-Site Scripting (XSS)** — Arbitrary JavaScript execution in browsers
- **Session Hijacking** — Steal cookies/tokens if rendered in web context
- **Phishing** — Inject fake login forms

### Proof of Concept
```python
# user_input: <script>alert("XSS")</script>
# Renders as: <main_prompt><script>alert("XSS")</script></main_prompt>

# model_response: <img src=x onerror=alert("XSS from model")>
# Renders as: <responses><img src=x onerror=alert("XSS from model")></responses>
```

### Changes
1. **rater_lib.py:170** — `jinja2.Environment()` → `jinja2.Environment(autoescape=True)`
2. **rubric_validation_template.txt:158** — `{{user_input}}` → `{{user_input|e}}`
3. **rubric_validation_template.txt:163** — `{{model_response}}` → `{{model_response|e}}`

Defense in depth: `autoescape=True` provides baseline protection, explicit `|e` filters ensure escaping even if autoescape is later disabled.

### References
- CWE-79: Cross-site Scripting (XSS)
- OWASP A7:2017 — Cross-site Scripting
- Jinja2 docs: https://jinja.palletsprojects.com/en/3.1.x/api/#autoescaping

Co-authored-by: Shangjie Chen <deanchen@google.com>
COPYBARA_INTEGRATE_REVIEW=#5526 from k4w-wak:fix/jinja2-xss-autoescape b5b6d3e
PiperOrigin-RevId: 943549514
@adk-bot

adk-bot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Thank you @k4w-wak for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit a721c1e.

Closing this PR as the changes are now in the main branch.

@adk-bot adk-bot added the merged [Status] This PR is merged label Jul 6, 2026
@adk-bot adk-bot closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged [Status] This PR is merged needs review [Status] The PR/issue is awaiting review from the maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants