generic.html-templates.security.var-in-href.var-in-href
Community Favorite

Author
76,191
Download Count*
License
Detected a template variable used in an anchor tag with the 'href' attribute. This allows a malicious actor to input the 'javascript:' URI and is subject to cross- site scripting (XSS) attacks. If using Flask, use 'url_for()' to safely generate a URL. If using Django, use the 'url' filter to safely generate a URL. If using Mustache, use a URL encoding library, or prepend a slash '/' to the variable for relative links (href="/{{link}}"
). You may also consider setting the Content Security Policy (CSP) header.
Run Locally
Run in CI
Defintion
rules:
- id: var-in-href
message: Detected a template variable used in an anchor tag with the 'href'
attribute. This allows a malicious actor to input the 'javascript:' URI
and is subject to cross- site scripting (XSS) attacks. If using Flask, use
'url_for()' to safely generate a URL. If using Django, use the 'url'
filter to safely generate a URL. If using Mustache, use a URL encoding
library, or prepend a slash '/' to the variable for relative links
(`href="/{{link}}"`). You may also consider setting the Content Security
Policy (CSP) header.
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#:~:text=javascript:%20URI
- https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#url
- https://github.com/pugjs/pug/issues/2952
- https://content-security-policy.com/
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]
languages:
- generic
paths:
include:
- "*.html"
- "*.mustache"
- "*.hbs"
severity: WARNING
patterns:
- pattern-inside: <a ...>
- pattern-either:
- pattern: href = {{ ... }}
- pattern: href = "{{ ... }}"
- pattern: href = '{{ ... }}'
- pattern-not-inside: href = {{ url_for(...) ... }}
- pattern-not-inside: href = "{{ url_for(...) ... }}"
- pattern-not-inside: href = '{{ url_for(...) ... }}'
- pattern-not-inside: href = "/{{ ... }}"
- pattern-not-inside: href = '/{{ ... }}'
Examples
var-in-href.html
<!-- FLASK TESTS -->
<h4>From: {{ from_email }}</h4>
<h4>To:
{% for recipient in recipients %}
{{ recipient }}
{% endfor %}
</h4>
<h4>Subject: {{subject}}</h4>
<div class="email" style="display: block;">
{{ message }}
</div>
<div class="email-text" style="display: none;">
<pre>{{ body }}</pre>
<!-- ruleid: var-in-href -->
<a href='{{ link }}'>{{ link_text }}</a>
<!-- ruleid: var-in-href -->
<a href = '{{ link }}' >{{ link_text }}</a>
<!-- ruleid: var-in-href -->
<a href = "{{ link }}" >{{ link_text }}</a>
<a
// ruleid: var-in-href
href = "{{ link }}"
>
{{ link_text }}
</a>
<!-- ok: var-in-href -->
<a href="{{ url_for('index') }}">{{ link_text }}</a>
<!-- ok: var-in-href -->
<a href="https://example.com/">{{ link_text }}</a>
<!-- ok: var-in-href -->
<a href="https://example.com/{{ link_path }}">{{ link_text }}</a>
</div>
<hr>
<!-- DJANGO TESTS -->
<h4>From: {{ from_email }}</h4>
<h4>To:
{% for recipient in recipients %}
{{ recipient }}
{% endfor %}
</h4>
<h4>Subject: {{subject}}</h4>
<div class="email" style="display: block;">
{{ message }}
</div>
<div class="email-text" style="display: none;">
<pre>{{ body }}</pre>
<!-- ruleid: var-in-href -->
<a href='{{ link }}'>{{ link_text }}</a>
<!-- ruleid: var-in-href -->
<a href = '{{ link }}' >{{ link_text }}</a>
<!-- ok: var-in-href -->
<a href="{% url 'login' %}">{{ link_text }}</a>
<!-- ok: var-in-href -->
<a href="https://example.com/">{{ link_text }}</a>
</div>
<hr>
var-in-href.mustache
<!-- cf. https://github.com/caiomartini/mustache-demo/blob/97b9200ebd2d27953febff23e6718aa1aa9ee44d/demo-mustache.html -->
<!DOCTYPE HTML>
<html>
<head>
<title>Demo Mustache.JS</title>
<meta charset="utf-8">
<link rel="stylesheet" href="node_modules\bootstrap\dist\css\bootstrap.min.css">
<script type="text/javascript" src="node_modules\jquery\dist\jquery.min.js"></script>
<script type="text/javascript" src="node_modules\bootstrap\dist\js\bootstrap.min.js"></script>
<script type="text/javascript" src="node_modules\mustache\mustache.min.js"></script>
<script type="text/javascript" src="demo-mustache.js"></script>
</head>
<body onload="carregarDemo();">
<div class="content">
<div id="mustache-header"></div>
<div id="mustache-cards"></div>
</div>
<!-- ok: var-in-href -->
<p class="navbar-text navbar-right">Singed in as: <a href=/profile>{{ val }}</a></p>
</body>
<script id="template-header" type="x-tmpl-mustache">
<div class="jumbotron text-center">
<h1 class="display-4">Oi, meu nome é {{autor.nome}} {{autor.sobrenome}}!</h1>
<p class="lead">Isso é apenas uma demonstração de como utilizar o Mustache.JS</p>
<!-- ruleid: var-in-href -->
<a href="{{ link }}" class="text-center">Click me</a>
<!-- ok: var-in-href -->
<a href="/{{ link }}" class="text-center">Click me</a>
</div>
</script>
<script id="template-cards" type="x-tmpl-mustache">
<div class="text-center">
<h2>Apresentando o time da <b>{{time.nome}}</b></h2>
<h6>Predio {{time.predio}}</h6>
</div>
{{#time}}
<div class="container" style="margin-top: 30px;">
<div class="row">
{{#squads}}
<div class="col-sm-6">
<div class="card">
<div class="card-header text-center">
<b>{{nome}}</b>
</div>
<div class="card-body">
{{! Partial de tabela de membros do Squad }}
{{> template-table}}
</div>
</div>
</div>
{{/squads}}
</div>
</div>
{{/time}}
</script>
</html>
Short Link: https://sg.run/x1kP