mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Polish flask_mail tests and code
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# https://pythonhosted.org/Flask-Mail/
|
||||
# https://github.com/mattupstate/flask-mail/blob/1709c70d839a7cc7b1f7eeb97333b71cd420fe32/flask_mail.py#L239
|
||||
|
||||
# tmp: this test cover RFS to any part of the message, but can be shortened to a specific part (body&html) once we decide the objective of the query.
|
||||
from flask_mail import Mail, Message
|
||||
|
||||
app = Flask(__name__)
|
||||
mail = Mail(app)
|
||||
|
||||
@app.route("/send")
|
||||
def send():
|
||||
msg = Message(subject=request.args["subject"],
|
||||
sender=request.args["sender"],
|
||||
recipients=list(request.args["recipient"]),
|
||||
body=request.args["body"],
|
||||
html=request.args["html"])
|
||||
|
||||
# The message can contain a body and/or HTML:
|
||||
msg.body = "test"
|
||||
msg.html = "<b>test</b>"
|
||||
|
||||
mail.send(msg)
|
||||
|
||||
@app.route("/connect")
|
||||
def connect():
|
||||
"""
|
||||
Minimal example to test mail.connect() usage
|
||||
"""
|
||||
with mail.connect() as conn:
|
||||
msg = Message(subject=request.args["subject"],
|
||||
sender=request.args["sender"],
|
||||
recipients=list(request.args["recipient"]),
|
||||
body=request.args["html"])
|
||||
conn.send(msg)
|
||||
@@ -4,3 +4,4 @@
|
||||
|
||||
private import experimental.semmle.python.frameworks.Stdlib
|
||||
private import experimental.semmle.python.frameworks.LDAP
|
||||
private import experimental.semmle.python.frameworks.Flask
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `flask` PyPI package.
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import experimental.semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
private module Flask {
|
||||
private API::Node flaskMail() { result = API::moduleImport("flask_mail") }
|
||||
|
||||
private API::Node flaskMailInstance() { result = flaskMail().getMember("Mail").getReturn() }
|
||||
|
||||
private DataFlow::CallCfgNode flaskMessageCall() {
|
||||
result = flaskMail().getMember("Message").getACall()
|
||||
}
|
||||
|
||||
private class FlaskMail extends DataFlow::CallCfgNode, EmailSender {
|
||||
/** A message variable to avoid multiple results in case consequential results are needed */
|
||||
DataFlow::CallCfgNode message;
|
||||
|
||||
FlaskMail() {
|
||||
this =
|
||||
[flaskMailInstance(), flaskMailInstance().getMember("connect").getReturn()]
|
||||
.getMember("send")
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getPlainTextBody() {
|
||||
result in [flaskMessageCall().getArg(2), flaskMessageCall().getArgByName("body")]
|
||||
or
|
||||
exists(DataFlow::AttrWrite bodyWrite |
|
||||
bodyWrite.getObject().getALocalSource() = flaskMessageCall() and
|
||||
bodyWrite.getAttributeName() = "body" and
|
||||
result = bodyWrite.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getHtmlBody() {
|
||||
result in [flaskMessageCall().getArg(3), flaskMessageCall().getArgByName("html")]
|
||||
or
|
||||
exists(DataFlow::AttrWrite bodyWrite |
|
||||
bodyWrite.getObject().getALocalSource() = flaskMessageCall() and
|
||||
bodyWrite.getAttributeName() = "html" and
|
||||
result = bodyWrite.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getTo() {
|
||||
result in [flaskMessageCall().getArg(1), flaskMessageCall().getArgByName("recipients")]
|
||||
or
|
||||
exists(DataFlow::AttrWrite bodyWrite |
|
||||
bodyWrite.getObject().getALocalSource() = flaskMessageCall() and
|
||||
bodyWrite.getAttributeName() = "recipients" and
|
||||
result = bodyWrite.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getFrom() {
|
||||
result in [flaskMessageCall().getArg(5), flaskMessageCall().getArgByName("sender")]
|
||||
or
|
||||
exists(DataFlow::AttrWrite bodyWrite |
|
||||
bodyWrite.getObject().getALocalSource() = flaskMessageCall() and
|
||||
bodyWrite.getAttributeName() = "sender" and
|
||||
result = bodyWrite.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getSubject() {
|
||||
result in [flaskMessageCall().getArg(0), flaskMessageCall().getArgByName("subject")]
|
||||
or
|
||||
exists(DataFlow::AttrWrite bodyWrite |
|
||||
bodyWrite.getObject().getALocalSource() = flaskMessageCall() and
|
||||
bodyWrite.getAttributeName() = "subject" and
|
||||
result = bodyWrite.getValue()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user