generic.html-templates.security.unquoted-attribute-var.unquoted-attribute-var
Community Favorite
semgrep
Author
76,191
Download Count*
License
Detected a unquoted template variable as an attribute. If unquoted, a malicious actor could inject custom JavaScript handlers. To fix this, add quotes around the template expression, like this: "{{ expr }}".
Run Locally
Run in CI
Defintion
rules:
- id: unquoted-attribute-var
message: 'Detected a unquoted template variable as an attribute. If unquoted, a
malicious actor could inject custom JavaScript handlers. To fix this, add
quotes around the template expression, like this: "{{ expr }}".'
metadata:
cwe:
- "CWE-79: Improper Neutralization of Input During Web Page Generation
('Cross-site Scripting')"
owasp:
- A07:2017 - Cross-Site Scripting (XSS)
- A03:2021 - Injection
references:
- https://flask.palletsprojects.com/en/1.1.x/security/#cross-site-scripting-xss
category: security
technology:
- html-templates
confidence: LOW
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Cross-Site-Scripting (XSS)
languages:
- generic
paths:
include:
- "*.html"
- "*.mustache"
- "*.hbs"
severity: WARNING
patterns:
- pattern-inside: <$TAG ...>
- pattern-not-inside: ="..."
- pattern-not-inside: ='...'
- pattern: "{{ ... }}"
fix-regex:
regex: "{{(.*?)}}"
replacement: '"{{\1}}"'
Examples
unquoted-attribute-var.html
{% extends "container.html" %}
{% block opengraph %}
<meta property="og:locale" content="en_US" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="semgrep" />
<meta property="og:description" content="content" />
<!-- ruleid: unquoted-attribute-var -->
<meta property="og:image" content={{ url_for('static', filename='picture.jpg', _external=True) }} />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="600" />
<meta property="og:image:height" content="600" />
<!-- ok -->
<meta property="not-real-only-for-testing" content="{{ safe }}" />
<!-- Google OAuth sign-in -->
<meta name="google-signin-scope" content="profile email openid">
<!-- ruleid: unquoted-attribute-var -->
<meta name="google-signin-client_id" content={{ client_id }}>
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve={{ carbonad_serve }}&placement={{ carbonad_placement }}" id="_carbonads_js"></script>
{% endblock %}
<!-- extra tests -->
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve={{carbonad_serve}}&placement={{carbonad_placement}}" id="_carbonads_js"></script>
<!-- ruleid: unquoted-attribute-var -->
<script async type="text/javascript" src= {{ link }} id="_carbonads_js"></script>
<!-- ruleid: unquoted-attribute-var -->
<script async type="text/javascript" src={{ link }} id="_carbonads_js"></script>
<!-- ruleid: unquoted-attribute-var -->
<script async type="text/javascript" src= {{ link }}
id="_carbonads_js"></script>
<script
async
type="text/javascript"
// ruleid: unquoted-attribute-var
src= {{ link }}
id="_carbonads_js">
</script>
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src=" {{ link }}" id="_carbonads_js"></script>
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src=' {{ link }}' id="_carbonads_js"></script>
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src="{{ link }}" id="_carbonads_js"></script>
<!-- ok: unquoted-attribute-var -->
<script async type="text/javascript" src="{{ link }}"
id="_carbonads_js"></script>
<!-- ok: unquoted-attribute-var -->
<div class="upper">
{{ paragraph_text }}
</div>
{% if scan_url %}
<h2>Semgrep Scan Results for <a href="{{scan_url}}"> {{scan_title}} </a></h2>
{% else %}
<h2>Semgrep Scan Results for {{scan_title}} </h2>
{% endif %}
{% for check_id, findings in findings_by_id.items() %}
<!-- ok: unquoted-attribute-var -->
<h3> rule: <a href="https://semgrep.dev/r?q={{check_id}}"> {{check_id}} </a> </h3>
<ul>
{% for finding in findings %}
<li>
{% if repo_url %}
<!-- ok: unquoted-attribute-var -->
<a href="{{repo_url}}/blob/{{commit}}/{{finding['path']}}#L{{finding['line']}}"> {{finding["path"]}}:{{finding["line"]}} </a>
{% else %}
{{finding["path"]}}:{{finding["line"]}}
{% endif %}
<p> Finding Message: {{finding["message"]}} </p>
</li>
{% endfor %}
</ul>
<hr/>
{% endfor %}
Short Link: https://sg.run/weNX