twikoo-func 1.7.11 → 1.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -35,7 +35,8 @@ const {
35
35
  getConfig,
36
36
  getConfigForAdmin,
37
37
  validate,
38
- checkCommentOwnership
38
+ checkCommentOwnership,
39
+ isValidEmail
39
40
  } = require('./utils')
40
41
  const {
41
42
  jsonParse,
@@ -679,6 +680,7 @@ async function parse (comment) {
679
680
  const isAdminUser = await isAdmin()
680
681
  const isBloggerMail = equalsMail(comment.mail, config.BLOGGER_EMAIL)
681
682
  if (isBloggerMail && !isAdminUser) throw new Error('请先登录管理面板,再使用博主身份发送评论')
683
+ if (comment.mail && !isValidEmail(comment.mail)) throw new Error('邮箱格式不合法')
682
684
  const hashMethod = config.GRAVATAR_CDN === 'cravatar.cn' ? md5 : sha256
683
685
  const commentDo = {
684
686
  uid: await getUid(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twikoo-func",
3
- "version": "1.7.11",
3
+ "version": "1.7.13",
4
4
  "description": "A simple comment system.",
5
5
  "author": "imaegoo <hello@imaegoo.com> (https://github.com/imaegoo)",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  "form-data": "^4.0.0",
25
25
  "jsdom": "^16.4.0",
26
26
  "marked": "^4.0.12",
27
- "nodemailer": "^6.4.17",
27
+ "nodemailer": "^7.0.11",
28
28
  "pushoo": "latest",
29
29
  "tencentcloud-sdk-nodejs": "^4.0.65",
30
30
  "xml2js": "^0.6.0"
package/utils/index.js CHANGED
@@ -93,7 +93,7 @@ const fn = {
93
93
  downs: downs.length,
94
94
  liked: ups.includes(uid),
95
95
  disliked: downs.includes(uid),
96
- replies: replies,
96
+ replies,
97
97
  rid: comment.rid,
98
98
  pid: comment.pid,
99
99
  ruser: fn.ruser(comment.pid, comments),
@@ -232,6 +232,17 @@ const fn = {
232
232
  isUrl (s) {
233
233
  return /^http(s)?:\/\//.test(s)
234
234
  },
235
+ isValidEmail (mail) {
236
+ if (!mail || typeof mail !== 'string') return false
237
+ const trimmed = mail.trim()
238
+ if (!trimmed) return false
239
+ // Reject emails with characters that could trigger nodemailer addressparser group parsing (CVE-2025-14874)
240
+ if (trimmed.indexOf(':') !== -1) return false
241
+ if (trimmed.indexOf(' ') !== -1) return false
242
+ if (trimmed.indexOf(';') !== -1) return false
243
+ // Basic email format validation
244
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)
245
+ },
235
246
  isQQ (mail) {
236
247
  return /^[1-9][0-9]{4,10}$/.test(mail) ||
237
248
  /^[1-9][0-9]{4,10}@qq.com$/i.test(mail)
package/utils/notify.js CHANGED
@@ -1,4 +1,4 @@
1
- const { equalsMail, getAvatar } = require('.')
1
+ const { equalsMail, getAvatar, isValidEmail } = require('.')
2
2
  const {
3
3
  getCheerio,
4
4
  getNodemailer,
@@ -115,11 +115,16 @@ const fn = {
115
115
  <p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}" target="_blank">查看回复的完整內容</a><br></p>
116
116
  </div>`
117
117
  }
118
+ const toMail = config.BLOGGER_EMAIL || config.SENDER_EMAIL
119
+ if (!isValidEmail(toMail)) {
120
+ logger.warn('博主邮箱格式不合法,跳过发送博主通知:', toMail)
121
+ return
122
+ }
118
123
  let sendResult
119
124
  try {
120
125
  sendResult = await transporter.sendMail({
121
126
  from: `"${config.SENDER_NAME}" <${config.SENDER_EMAIL}>`,
122
- to: config.BLOGGER_EMAIL || config.SENDER_EMAIL,
127
+ to: toMail,
123
128
  subject: emailSubject,
124
129
  html: emailContent
125
130
  })
@@ -234,6 +239,10 @@ const fn = {
234
239
  </div>
235
240
  </div>`
236
241
  }
242
+ if (!isValidEmail(parentComment.mail)) {
243
+ logger.warn('回复通知邮箱格式不合法,跳过发送回复通知:', parentComment.mail)
244
+ return
245
+ }
237
246
  let sendResult
238
247
  try {
239
248
  sendResult = await transporter.sendMail({
@@ -262,9 +271,14 @@ const fn = {
262
271
  // 邮件测试前清除 transporter,保证读取的是最新的配置
263
272
  transporter = null
264
273
  await fn.initMailer({ config, throwErr: true })
274
+ const toMail = event.mail || config.BLOGGER_EMAIL || config.SENDER_EMAIL
275
+ if (!isValidEmail(toMail)) {
276
+ res.message = '邮箱格式不合法'
277
+ return res
278
+ }
265
279
  const sendResult = await transporter.sendMail({
266
280
  from: config.SENDER_EMAIL,
267
- to: event.mail || config.BLOGGER_EMAIL || config.SENDER_EMAIL,
281
+ to: toMail,
268
282
  subject: 'Twikoo 邮件通知测试邮件',
269
283
  html: '如果您收到这封邮件,说明 Twikoo 邮件功能配置正确'
270
284
  })