CONTRAST: SMTP Injection from "param" Parameter on "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bryanateoan opened this issue · comments
Vulnerability ID: Q1KB-C5AQ-T8S0-X360
Application Name: AgentMessageGeneratorJava
Vulnerability Link: http://localhost:19080/Contrast/static/ng/index.html#/d7b17129-9c95-44dc-875a-bf9c069873a4/applications/d255f236-37ea-4ad3-9a9f-07892483f73c/vulns/Q1KB-C5AQ-T8S0-X360
What Happened?
We tracked the following data from "param" Parameter:
GET aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?param=safe
...which was accessed within the following code:
com.contrastsecurity.javax.mail.Server#lambda$adaptMessenger$7(), line 129
...and ended up in the SMTP message:
safe
What's the risk?
As is shown, the user controls a piece of the outgoing SMTP message. Depending on the piece of the message the untrusted user can control, it's possible that the functionality can be abused. By controlling the destination fields, subject or body, they can possibly repurpose the email for phishing purposes. By controlling headers directly, they can create malicious attachments, re-route the message, or other undesirable behavior.
Recommendation
As discussed in the summary, this vulnerability can be used to controls part of the outgoing email or inject attachments.
Contrast will report this issue as long as any part of the email is user-controlled. Use indirect references, or static/trusted data to supply all the fields and headers of an SMTP message.
Here's an unsafe example of letting the user control the e-mail user input in a SMTP header:
String subject = request.getParameter("subject");
Message msg = new MimeMessage(session);
msg.setSubject(subject);
By using an indirect reference, we can allow the user to control the subject, without allowing them to supply an arbitrary value:
String subject = null;
String subjectId = request.getParameter("subject");
Message msg = new MimeMessage(session);
if("SUB1".equals(subjectId)) {
subject = "Your friend wants to send you a video!";
} else if("SUB2".equals(subjectId)) {
subject = "Your friend wants to send you an image!";
} else if("SUB3".equals(subjectId)) {
subject = "Your friend wants to send you a message!";
}
msg.setSubject(subject);
First Event
Stack:
org.glassfish.grizzly.http.server.Request.getParameter(Request.java:1124)
com.contrastsecurity.grizzly.SinkHandler.service(SinkHandler.java:26)
org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
java.lang.Thread.run(Thread.java:748)
Last Event
Stack:
javax.mail.internet.MimeMessage.setText(MimeMessage.java:1597)
com.contrastsecurity.javax.mail.Server.lambda$adaptMessenger$7(Server.java:129)
com.contrastsecurity.grizzly.SinkHandler.service(SinkHandler.java:27)
org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
java.lang.Thread.run(Thread.java:748)
HTTP Request
GET http://localhost:32773aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?param=safe HTTP/1.1
Contrast-Mq-Name: queue-000-PartTests.it_test_set_text_sink-contrastsecurity-docker.jfrog.io/contrast/javax-mail:rev1
Host: localhost:32773
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.9.1