From 86a141dbda6fe716f1c75f3c3ebc42a6ec3c3da3 Mon Sep 17 00:00:00 2001 From: JungYunji Date: Thu, 24 Jul 2025 13:49:55 +0900 Subject: [PATCH 1/3] [Autofic] Create package.json and CI workflow --- .github/workflows/pr_notify.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/pr_notify.yml diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml new file mode 100644 index 0000000..2b34036 --- /dev/null +++ b/.github/workflows/pr_notify.yml @@ -0,0 +1,20 @@ +name: PR Notifier + +on: + pull_request: + types: [opened, reopened, closed] + +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Notify Discord + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + run: | + curl -H "Content-Type: application/json" -d '{"content": "🔔 Pull Request [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }}) by ${{ github.event.pull_request.user.login }} - ${{ github.event.action }}"}' $DISCORD_WEBHOOK_URL + - name: Notify Slack + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + run: | + curl -H "Content-Type: application/json" -d '{"text": ":bell: Pull Request <${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}> by ${{ github.event.pull_request.user.login }} - ${{ github.event.action }}"}' $SLACK_WEBHOOK_URL From 9b074b014538ec9a9fc93f929f1034c3049617fd Mon Sep 17 00:00:00 2001 From: JungYunji Date: Thu, 24 Jul 2025 13:50:03 +0900 Subject: [PATCH 2/3] [Autofic] 5 malicious code detected!! --- example/jokeChatServer.js | 2 ++ src/FBLocalChatRoutes.js | 13 ++++++-- src/index.js | 62 +++++++++++++++++++++------------------ 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/example/jokeChatServer.js b/example/jokeChatServer.js index 6e284e4..b3e0534 100644 --- a/example/jokeChatServer.js +++ b/example/jokeChatServer.js @@ -2,6 +2,7 @@ const Bot = require('../build'); const express = require('express'); const bodyParser = require('body-parser') const Promise = require('bluebird'); +const helmet = require('helmet'); const JOKE = "Did you know photons had mass? I didn't even know they were Catholic."; const RiddleImageUrl ="http://tinyurl.com/he9tsph"; @@ -164,6 +165,7 @@ function makeServer() { }); const app = express(); + app.use(helmet()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); diff --git a/src/FBLocalChatRoutes.js b/src/FBLocalChatRoutes.js index 139d663..a56a2a4 100644 --- a/src/FBLocalChatRoutes.js +++ b/src/FBLocalChatRoutes.js @@ -8,6 +8,8 @@ import invariant from 'invariant'; import fs from 'fs'; import dot from 'dot'; import path from 'path'; +import rateLimit from 'express-rate-limit'; // Import rate limiting middleware +import sanitizeHtml from 'sanitize-html'; // Import a library to sanitize HTML const FBLocalChatRoutes = (router: Router, Bot: Object): Router => { router.get('/localChat/getMessages', (req, res) => { @@ -102,7 +104,13 @@ const FBLocalChatRoutes = (router: Router, Bot: Object): Router => { res.sendStatus(200); }); - router.get('/localChat/*', (req, res) => { + // Apply rate limiting to the endpoint + const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100 // limit each IP to 100 requests per windowMs + }); + + router.get('/localChat/*', limiter, (req, res) => { const dir = path.join(path.dirname(__filename), '..', 'localChatWeb'); var filePath = req.url.replace('/localChat', ''); if (filePath !== '/') { @@ -119,7 +127,8 @@ const FBLocalChatRoutes = (router: Router, Bot: Object): Router => { return; } var tempFn = dot.template(data); - res.send(tempFn({baseURL})); + // Sanitize the input to prevent XSS + res.send(tempFn({baseURL: sanitizeHtml(baseURL)})); }); }); diff --git a/src/index.js b/src/index.js index 28f1524..4d92cd4 100644 --- a/src/index.js +++ b/src/index.js @@ -79,7 +79,9 @@ class Bot extends EventEmitter { }); router.post('/', (req, res) => { - this.handleMessage(req.body); + if (typeof req.body === 'object' && req.body !== null) { + this.handleMessage(req.body); + } res.sendStatus(200); }); @@ -108,34 +110,38 @@ class Bot extends EventEmitter { return; } - data.entry.forEach((entry) => { - entry.messaging.forEach((event) => { - // handle messages - if (event.message) { - // Since a message containing a quick_reply can also contain text - // and attachment, check for quick_reply first - if (event.message.quick_reply) { - this.emit('quick_reply', event); - return; - } - if (event.message.text) { - this.emit('text', event); - } else if (event.message.attachments) { - this.emit('attachments', event); - } - } - - // handle postback - if (event.postback && event.postback.payload) { - this.emit('postback', event); + if (Array.isArray(data.entry)) { + data.entry.forEach((entry) => { + if (entry.messaging && Array.isArray(entry.messaging)) { + entry.messaging.forEach((event) => { + // handle messages + if (event.message) { + // Since a message containing a quick_reply can also contain text + // and attachment, check for quick_reply first + if (event.message.quick_reply) { + this.emit('quick_reply', event); + return; + } + if (event.message.text) { + this.emit('text', event); + } else if (event.message.attachments) { + this.emit('attachments', event); + } + } + + // handle postback + if (event.postback && event.postback.payload) { + this.emit('postback', event); + } + // Handle authentication + if (event.optin && event.optin.ref) { + this.emit('optin', event); + } + // TODO: handle message delivery + }); } - // Handle authentication - if (event.optin && event.optin.ref) { - this.emit('optin', event); - } - // TODO: handle message delivery - }) - }); + }); + } } /** From 50f201fa874b489efe6805f6b394118da09b0a23 Mon Sep 17 00:00:00 2001 From: JungYunji Date: Thu, 24 Jul 2025 13:50:32 +0900 Subject: [PATCH 3/3] chore: remove CI workflow before upstream PR --- .github/workflows/pr_notify.yml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 .github/workflows/pr_notify.yml diff --git a/.github/workflows/pr_notify.yml b/.github/workflows/pr_notify.yml deleted file mode 100644 index 2b34036..0000000 --- a/.github/workflows/pr_notify.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: PR Notifier - -on: - pull_request: - types: [opened, reopened, closed] - -jobs: - notify: - runs-on: ubuntu-latest - steps: - - name: Notify Discord - env: - DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} - run: | - curl -H "Content-Type: application/json" -d '{"content": "🔔 Pull Request [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }}) by ${{ github.event.pull_request.user.login }} - ${{ github.event.action }}"}' $DISCORD_WEBHOOK_URL - - name: Notify Slack - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - run: | - curl -H "Content-Type: application/json" -d '{"text": ":bell: Pull Request <${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}> by ${{ github.event.pull_request.user.login }} - ${{ github.event.action }}"}' $SLACK_WEBHOOK_URL