Skip to content

Commit f7775f3

Browse files
committed
JS: Add EmailClients lib
1 parent c36e7f0 commit f7775f3

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

javascript/ql/src/javascript.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import semmle.javascript.Constants
1313
import semmle.javascript.DataFlow
1414
import semmle.javascript.DefUse
1515
import semmle.javascript.DOM
16+
import semmle.javascript.EmailClients
1617
import semmle.javascript.Errors
1718
import semmle.javascript.ES2015Modules
1819
import semmle.javascript.Expr
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import javascript
2+
3+
/**
4+
* An operation that sends an email.
5+
*/
6+
abstract class EmailSender extends DataFlow::DefaultSourceNode {
7+
/**
8+
* Gets a data flow node holding the plaintext version of the email body.
9+
*/
10+
abstract DataFlow::Node getPlainTextBody();
11+
12+
/**
13+
* Gets a data flow node holding the HTML body of the email.
14+
*/
15+
abstract DataFlow::Node getHtmlBody();
16+
17+
/**
18+
* Gets a data flow node holding the address of the email recipient(s).
19+
*/
20+
abstract DataFlow::Node getTo();
21+
22+
/**
23+
* Gets a data flow node holding the address of the email sender.
24+
*/
25+
abstract DataFlow::Node getFrom();
26+
27+
/**
28+
* Gets a data flow node holding the email subject.
29+
*/
30+
abstract DataFlow::Node getSubject();
31+
32+
/**
33+
* Gets a data flow node that refers to the HTML body or plaintext body of the email.
34+
*/
35+
DataFlow::Node getABody() {
36+
result = getPlainTextBody() or
37+
result = getHtmlBody()
38+
}
39+
}
40+
41+
/**
42+
* An email-sending call based on the `nodemailer` package.
43+
*/
44+
private class NodemailerEmailSender extends EmailSender, DataFlow::MethodCallNode {
45+
NodemailerEmailSender() {
46+
this = DataFlow::moduleMember("nodemailer", "createTransport").getACall().getAMethodCall("sendMail")
47+
}
48+
49+
override DataFlow::Node getPlainTextBody() {
50+
result = getOptionArgument(0, "text")
51+
}
52+
53+
override DataFlow::Node getHtmlBody() {
54+
result = getOptionArgument(0, "html")
55+
}
56+
57+
override DataFlow::Node getTo() {
58+
result = getOptionArgument(0, "to")
59+
}
60+
61+
override DataFlow::Node getFrom() {
62+
result = getOptionArgument(0, "from")
63+
}
64+
65+
override DataFlow::Node getSubject() {
66+
result = getOptionArgument(0, "subject")
67+
}
68+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| tst.js:17:2:19:3 | transpo ... ');\\n\\t}) | tst.js:11:12:11:31 | 'sender@example.com' | tst.js:12:10:12:55 | 'receiv ... le.com' | tst.js:13:15:13:28 | 'Some subject' | tst.js:14:12:14:15 | 'Hi' | tst.js:15:12:15:22 | '<b>Hi</b>' |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from EmailSender send
4+
select send, send.getFrom(), send.getTo(), send.getSubject(), send.getPlainTextBody(), send.getHtmlBody()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
let nodemailer = require('nodemailer');
2+
let config = require('./account-config');
3+
4+
function sendMessage() {
5+
let transporter = nodemailer.createTransport({
6+
host: config.host,
7+
port: config.host,
8+
auth: config.auth
9+
});
10+
let mailOptions = {
11+
from: 'sender@example.com',
12+
to: 'receiver1@example.com, receiver2@example.com',
13+
subject: 'Some subject',
14+
text: 'Hi',
15+
html: '<b>Hi</b>'
16+
};
17+
transporter.sendMail(mailOptions, (error, info) => {
18+
console.log('Message sent');
19+
});
20+
}

0 commit comments

Comments
 (0)