python.django.security.injection.email.xss-send-mail-html-message.xss-send-mail-html-message
Verifed by r2c
Community Favorite
semgrep
Author
99,207
Download Count*
License
Found request data in 'send_mail(...)' that uses 'html_message'. 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-send-mail-html-message
message: Found request data in 'send_mail(...)' that uses 'html_message'. 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(...):
...
- pattern-either:
- pattern: django.core.mail.send_mail(..., html_message=request.$W.get(...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.send_mail(..., html_message=$DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W.get(...)
...
django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR.format(..., $DATA, ...)
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.send_mail(..., html_message=$STR % $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR % $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W.get(...)
...
django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
django.core.mail.send_mail(..., html_message=$STR + $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR + $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: $A = django.core.mail.send_mail(..., html_message=request.$W.get(...),
...)
- pattern: return django.core.mail.send_mail(...,
html_message=request.$W.get(...), ...)
- pattern: django.core.mail.send_mail(..., html_message=request.$W(...), ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.send_mail(..., html_message=$DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W(...)
...
django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR.format(..., $DATA, ...)
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.send_mail(..., html_message=$STR % $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR % $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W(...)
...
django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
django.core.mail.send_mail(..., html_message=$STR + $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR + $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: $A = django.core.mail.send_mail(..., html_message=request.$W(...), ...)
- pattern: return django.core.mail.send_mail(..., html_message=request.$W(...),
...)
- pattern: django.core.mail.send_mail(..., html_message=request.$W[...], ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.send_mail(..., html_message=$DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W[...]
...
django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR.format(..., $DATA, ...)
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.send_mail(..., html_message=$STR % $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR % $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W[...]
...
django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
django.core.mail.send_mail(..., html_message=$STR + $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR + $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: $A = django.core.mail.send_mail(..., html_message=request.$W[...], ...)
- pattern: return django.core.mail.send_mail(..., html_message=request.$W[...],
...)
- pattern: django.core.mail.send_mail(..., html_message=request.$W, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.send_mail(..., html_message=$DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W
...
django.core.mail.send_mail(..., html_message=$STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR.format(..., $DATA, ...)
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.send_mail(..., html_message=$STR % $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR % $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: >
$DATA = request.$W
...
django.core.mail.send_mail(..., html_message=f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W
...
$INTERM = f"...{$DATA}..."
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: |
$DATA = request.$W
...
django.core.mail.send_mail(..., html_message=$STR + $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR + $DATA
...
django.core.mail.send_mail(..., html_message=$INTERM, ...)
- pattern: $A = django.core.mail.send_mail(..., html_message=request.$W, ...)
- pattern: return django.core.mail.send_mail(..., html_message=request.$W, ...)
Examples
xss-send-mail-html-message.py
import logging as logger
import traceback
from django.contrib.auth.models import User
from django.conf import settings
from django.core.mail import send_mail
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")
body = request.POST.get("body")
# ruleid: xss-send-mail-html-message
body_html = request.POST.get("body_html")
sender = settings.EMAIL_SENDER
send_mail(
subject,
body,
sender,
[settings.EMAIL],
bcc=users,
html_message=body_html
)
else:
return render(request, "error404.html")
else:
return render(request, "error404.html")
def send_an_email(request):
subject = request.POST.get("subject")
# ok: xss-send-mail-html-message
body= request.POST.get("body")
sender = "blah@blah.com"
send_mail(
subject,
body,
sender,
[settings.EMAIL],
)
Short Link: https://sg.run/Avx8