diff --git a/python/ql/src/experimental/semmle/python/frameworks/Sendgrid.qll b/python/ql/src/experimental/semmle/python/frameworks/Sendgrid.qll index b8d7ed66aeb..17484c968ec 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Sendgrid.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Sendgrid.qll @@ -122,7 +122,6 @@ private module Sendgrid { ) or exists(KeyValuePair content, Dict generalDict, KeyValuePair typePair, KeyValuePair valuePair | - // find L33 content.getKey().(Str_).getS() = "content" and content.getValue().(List).getAnElt() = generalDict and // declare KeyValuePairs keys and values diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py index a051af71d02..4df6369110f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/django_mail.py @@ -1,6 +1,3 @@ -# https://data-flair.training/blogs/django-send-email/ -# Using flask for RFS and django.core.mail as email library - from flask import request, Flask from django.core.mail import send_mail, mail_admins, mail_managers @@ -9,15 +6,18 @@ app = Flask(__name__) @app.route("/send") def send(): """ + The Django.core.mail#send_mail function source code can be found in the link below: https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L38 - Apparently there's no html_message in send_mass_mail: https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64 + send_mass_mail does not provide html_message as an argument to it's function. See the link below for more info: + https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64 """ send_mail("Subject", "plain-text body", "from@example.com", ["to@example.com"], html_message=request.args("html")) @app.route("/internal") def internal(): """ + The Django.core.mail#mail_admins and Django.core.mail#mail_managers functions source code can be found in the link below: https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L90-L121 """ mail_admins("Subject", "plain-text body", html_message=request.args("html")) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py index c5de32c6f94..e8bdcc93634 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/flask_mail.py @@ -1,6 +1,3 @@ -# https://pythonhosted.org/Flask-Mail/ -# https://github.com/mattupstate/flask-mail/blob/1709c70d839a7cc7b1f7eeb97333b71cd420fe32/flask_mail.py#L239 - from flask import request, Flask from flask_mail import Mail, Message @@ -17,6 +14,7 @@ def send(): # The message can contain a body and/or HTML: msg.body = "plain-text body" + # The email's HTML can be set via msg.html or as an initialize argument when creating a Message object. msg.html = request.args["html"] mail.send(msg) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py index 75c11f38159..8c2424c765f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_mail.py @@ -1,5 +1,3 @@ -# https://www.twilio.com/blog/how-to-send-emails-in-python-with-sendgrid - from flask import request, Flask from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail, Email, To, Content, MimeType @@ -24,7 +22,6 @@ def send_post(): subject = "Sending with SendGrid is Fun" content = Content("text/html", request.args["html_content"]) - # https://github.com/sendgrid/sendgrid-python/blob/cf0924c35c37bbec8e5ca39e963a55f54f0eec11/sendgrid/helpers/mail/mime_type.py#L1 content = Content(MimeType.html, request.args["html_content"]) mail = Mail(from_email, to_email, subject, content) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py index ef9c6edfca8..fd0627c612c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/sendgrid_via_mail_send_post_request_body_bad.py @@ -1,5 +1,4 @@ # This tests that the developer doesn't pass tainted user data into the mail.send.post() method in the SendGrid library. -# source :https://github.com/sendgrid/sendgrid-python import sendgrid import os @@ -7,135 +6,32 @@ import os sg = sendgrid.SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) data = { - "asm": { - "group_id": 1, - "groups_to_display": [ - 1, - 2, - 3 - ] - }, - "attachments": [ - { - "content": "[BASE64 encoded content block here]", - "content_id": "ii_139db99fdb5c3704", - "disposition": "inline", - "filename": "file1.jpg", - "name": "file1", - "type": "jpg" - } - ], - "batch_id": "[YOUR BATCH ID GOES HERE]", - "categories": [ - "category1", - "category2" - ], "content": [ { "type": "text/html", "value": "

Hello, world!

" } ], - "custom_args": { - "New Argument 1": "New Value 1", - "activationAttempt": "1", - "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]" - }, "from": { "email": "sam.smith@example.com", "name": "Sam Smith" }, "headers": {}, - "ip_pool_name": "[YOUR POOL NAME GOES HERE]", "mail_settings": { - "bcc": { - "email": "ben.doe@example.com", - "enable": True - }, - "bypass_list_management": { - "enable": True - }, "footer": { "enable": True, "html": "

Thanks
The SendGrid Team

", "text": "Thanks,/n The SendGrid Team" }, - "sandbox_mode": { - "enable": False - }, - "spam_check": { - "enable": True, - "post_to_url": "http://example.com/compliance", - "threshold": 3 - } }, - "personalizations": [ - { - "bcc": [ - { - "email": "sam.doe@example.com", - "name": "Sam Doe" - } - ], - "cc": [ - { - "email": "jane.doe@example.com", - "name": "Jane Doe" - } - ], - "custom_args": { - "New Argument 1": "New Value 1", - "activationAttempt": "1", - "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]" - }, - "headers": { - "X-Accept-Language": "en", - "X-Mailer": "MyApp" - }, - "send_at": 1409348513, - "subject": "Hello, World!", - "substitutions": { - "id": "substitutions", - "type": "object" - }, - "to": [ - { - "email": "john.doe@example.com", - "name": "John Doe" - } - ] - } - ], "reply_to": { "email": "sam.smith@example.com", "name": "Sam Smith" }, - "sections": { - "section": { - ":sectionName1": "section 1 text", - ":sectionName2": "section 2 text" - } - }, "send_at": 1409348513, "subject": "Hello, World!", "template_id": "[YOUR TEMPLATE ID GOES HERE]", "tracking_settings": { - "click_tracking": { - "enable": True, - "enable_text": True - }, - "ganalytics": { - "enable": True, - "utm_campaign": "[NAME OF YOUR REFERRER SOURCE]", - "utm_content": "[USE THIS SPACE TO DIFFERENTIATE YOUR EMAIL FROM ADS]", - "utm_medium": "[NAME OF YOUR MARKETING MEDIUM e.g. email]", - "utm_name": "[NAME OF YOUR CAMPAIGN]", - "utm_term": "[IDENTIFY PAID KEYWORDS HERE]" - }, - "open_tracking": { - "enable": True, - "substitution_tag": "%opentrack" - }, "subscription_tracking": { "enable": True, "html": "If you would like to unsubscribe and stop receiving these emails <% clickhere %>.", diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py index 7bd243bdd5e..f9cec87c45f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_subparts.py @@ -1,6 +1,4 @@ # This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart initializer via the subparts parameter. - -# source꞉ https꞉//www.programcreek.com/python/example/53141/email.MIMEMultipart.MIMEMultipart from flask import Flask, request import json import smtplib, ssl @@ -11,9 +9,8 @@ app = Flask(__name__) @app.route("/") def email_person(): - sender_email = "my@gmail.com" - receiver_email = "your@gmail.com" - password = input("Type your password and press enter:") + sender_email = "sender@gmail.com" + receiver_email = "receiver@example.com" name = request.args['search'] # Create the plain-text and HTML version of your message @@ -33,7 +30,7 @@ def email_person(): context = ssl.create_default_context() server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context); - server.login(sender_email, password) + server.login(sender_email, "SERVER_PASSWORD") server.sendmail( sender_email, receiver_email, message.as_string() ) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py index af6de1dda5e..48a228b0bc6 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/smtplib_bad_via_attach.py @@ -1,5 +1,4 @@ # This test checks that the developer doesn't pass a MIMEText instance to a MIMEMultipart message. -# source꞉ https꞉//realpython.com/python-send-email/ from flask import Flask, request import json import smtplib, ssl @@ -10,9 +9,8 @@ app = Flask(__name__) @app.route("/") def email_person(): - sender_email = "my@gmail.com" - receiver_email = "your@gmail.com" - password = input("Type your password and press enter:") + sender_email = "sender@gmail.com" + receiver_email = "receiver@example.com" message = MIMEMultipart("alternative") message["Subject"] = "multipart test" @@ -22,7 +20,7 @@ def email_person(): name = request.args['name'] # Create the plain-text and HTML version of your message text = "hello there" - html = f"hello {name}" # here is the exploit. passing vulnerable data into the html portion of the email + html = f"hello {name}" # Turn these into plain/html MIMEText objects part1 = MIMEText(text, "plain") @@ -37,7 +35,7 @@ def email_person(): context = ssl.create_default_context() server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) - server.login(sender_email, password) + server.login(sender_email, "SERVER_PASSWORD") server.sendmail( sender_email, receiver_email, message.as_string() )