python.django.security.injection.email.xss-html-email-body.xss-html-email-body
Verifed by r2c
Community Favorite
semgrep
Author
99,207
Download Count*
License
Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS.
Run Locally
Run in CI
Defintion
rules:
- id: xss-html-email-body
message: Found request data in an EmailMessage that is set to use HTML. This is
dangerous because HTML emails are susceptible to XSS. An attacker could
inject data into this HTML email, causing XSS.
metadata:
cwe:
- "CWE-74: Improper Neutralization of Special Elements in Output Used by
a Downstream Component ('Injection')"
owasp:
- A03:2021 - Injection
references:
- https://www.damonkohler.com/2008/12/email-injection.html
category: security
technology:
- django
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Other
languages:
- python
severity: WARNING
patterns:
- pattern-inside: |
def $FUNC(...):
...
$EMAIL.content_subtype = "html"
...
- pattern-either:
- pattern: django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.EmailMessage($SUBJ, $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $B.$C(..., $DATA, ...)
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR % $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...)
- pattern: return django.core.mail.EmailMessage($SUBJ, request.$W.get(...), ...)
- pattern: django.core.mail.EmailMessage($SUBJ, request.$W(...), ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.EmailMessage($SUBJ, $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $B.$C(..., $DATA, ...)
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR % $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W(...), ...)
- pattern: return django.core.mail.EmailMessage($SUBJ, request.$W(...), ...)
- pattern: django.core.mail.EmailMessage($SUBJ, request.$W[...], ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.EmailMessage($SUBJ, $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $B.$C(..., $DATA, ...)
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR % $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W[...], ...)
- pattern: return django.core.mail.EmailMessage($SUBJ, request.$W[...], ...)
- pattern: django.core.mail.EmailMessage($SUBJ, request.$W, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.EmailMessage($SUBJ, $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.EmailMessage($SUBJ, $B.$C(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $B.$C(..., $DATA, ...)
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.EmailMessage($SUBJ, $STR % $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR % $DATA
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.EmailMessage($SUBJ, f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.EmailMessage($SUBJ, $INTERM, ...)
- pattern: $A = django.core.mail.EmailMessage($SUBJ, request.$W, ...)
- pattern: return django.core.mail.EmailMessage($SUBJ, request.$W, ...)
Examples
xss-html-email-body.py
import logging as logger
import traceback
from django.contrib.auth.models import User
from django.conf import settings
from django.core.mail import EmailMessage
from django.shortcuts import render
from smtplib import SMTPException
def notify_users_about_challenge(request):
"""
Email New Challenge Details to Users
"""
if request.user.is_authenticated() and request.user.is_superuser:
if request.method == "GET":
template_name = "notification_email_data.html"
return render(request, template_name)
elif request.method == "POST":
users = User.objects.exclude(email__exact="").values_list(
"email", flat=True
)
subject = request.POST.get("subject")
# ruleid: xss-html-email-body
body_html = request.POST.get("body")
sender = settings.EMAIL_SENDER
email = EmailMessage(
subject,
body_html,
sender,
[settings.EMAIL],
bcc=users,
)
email.content_subtype = "html"
try:
email.send()
return render(
request,
"notification_email_conformation.html",
{"message": "All the emails are sent successfully!"},
)
except SMTPException:
logger.exception(traceback.format_exc())
return render(
request, "notification_email_data.html", {"errors": 1}
)
else:
return render(request, "error404.html")
else:
return render(request, "error404.html")
def send_an_email(request):
subject = request.POST.get("subject")
# ok: xss-html-email-body
body_html = request.POST.get("body")
sender = "blah@blah.com"
email = EmailMessage(
subject,
body_html,
sender,
[settings.EMAIL],
)
try:
email.send()
return render(
request,
"notification_email_conformation.html",
{"message": "All the emails are sent successfully!"},
)
except SMTPException:
logger.exception(traceback.format_exc())
return render(
request, "notification_email_data.html", {"errors": 1}
)
Short Link: https://sg.run/RoBe