From 54fc9cb30181e7a98090564dc3d323b181835617 Mon Sep 17 00:00:00 2001 From: yjchoe818 Date: Thu, 24 Jul 2025 00:17:08 +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 000000000..2b34036d0 --- /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 218410dbfcfed44b2578e7179d768d9955fe2bfc Mon Sep 17 00:00:00 2001 From: yjchoe818 Date: Thu, 24 Jul 2025 00:17:10 +0900 Subject: [PATCH 2/3] [Autofic] 4 malicious code detected!! --- lib/modules/login.js | 10 +++++++++- lib/modules/pcap.js | 12 +++++++++--- lib/opensoc-ui.js | 23 ++++++++++++++++++----- test/session-test.js | 2 +- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/modules/login.js b/lib/modules/login.js index 57994d889..8510b1472 100644 --- a/lib/modules/login.js +++ b/lib/modules/login.js @@ -2,6 +2,14 @@ exports = module.exports = function(app, config) { var _ = require('lodash'); var passport = require('passport'); var ldapauth = require('passport-ldapauth'); + var rateLimit = require('express-rate-limit'); + + // Rate limiter for login attempts + const loginLimiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100, // limit each IP to 100 requests per windowMs + message: "Too many login attempts from this IP, please try again after 15 minutes" + }); // LDAP integration passport.use(new ldapauth.Strategy({ @@ -61,7 +69,7 @@ exports = module.exports = function(app, config) { res.render('login', { flash: req.flash() }); }); - app.post('/login', passport.authenticate('ldapauth', { + app.post('/login', loginLimiter, passport.authenticate('ldapauth', { successRedirect: '/', failureRedirect: '/login', failureFlash: true diff --git a/lib/modules/pcap.js b/lib/modules/pcap.js index b22921341..9d0fe501e 100644 --- a/lib/modules/pcap.js +++ b/lib/modules/pcap.js @@ -28,22 +28,28 @@ function readRawBytes(size, transit) { return buffer; } - exports = module.exports = function(app, config) { var _ = require('lodash'); var fs = require('fs'); var spawn = require('child_process').spawn; var querystring = require('querystring'); var XmlStream = require('xml-stream'); + var rateLimit = require('express-rate-limit'); + + // Rate limiting middleware + const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, // 15 minutes + max: 100 // limit each IP to 100 requests per windowMs + }); // Mock pcap service for use in development if (config.pcap.mock) { - app.get('/sample/pcap/:command', function(req, res) { + app.get('/sample/pcap/:command', limiter, function(req, res) { res.sendFile('/vagrant/seed/opensoc.pcap'); }); } - app.get('/pcap/:command', function(req, res) { + app.get('/pcap/:command', limiter, function(req, res) { if (config.auth && (!req.user || !req.user.permissions.pcap)) { res.send(403, 'Forbidden!'); return; diff --git a/lib/opensoc-ui.js b/lib/opensoc-ui.js index 532c31410..d7eb1b374 100644 --- a/lib/opensoc-ui.js +++ b/lib/opensoc-ui.js @@ -1,5 +1,7 @@ var _ = require('lodash'); var http = require('http'); +var https = require('https'); +var fs = require('fs'); var path = require('path'); var express = require('express'); @@ -10,6 +12,8 @@ var flash = require('connect-flash'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var cookieSession = require('cookie-session'); +var csurf = require('csurf'); +var helmet = require('helmet'); var passport = require('passport'); var ldapauth = require('passport-ldapauth'); @@ -24,13 +28,19 @@ var app = express(); app.set('view engine', 'jade'); app.set('views', path.join(__dirname, 'views/')); +// Use Helmet to secure Express apps by setting various HTTP headers +app.use(helmet()); + // Cookie middleware app.use(connect.logger('dev')); app.use(flash()); app.use(cookieParser()); app.use(cookieSession({ secret: config.secret, - cookie: {maxAge: 1 * 24 * 60 * 60 * 1000} // 1-day sessions + cookie: { + maxAge: 1 * 24 * 60 * 60 * 1000, // 1-day sessions + secure: true // Ensure cookies are only sent over HTTPS + } })); if (config.auth) { @@ -42,7 +52,7 @@ app.use("/__es", esProxy(config)); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); - +app.use(csurf()); // Add CSRF protection // Setup routes if (config.auth) { @@ -51,7 +61,6 @@ if (config.auth) { pcap(app, config); - app.get('/config.js', function (req, res) { if (config.auth && !req.user) { res.send(403, 'Forbidden!'); @@ -67,8 +76,12 @@ app.use(connect.static(path.join(__dirname, config.static))); // Start server if (process.env.NODE_ENV != 'TEST') { console.log('Starting server on port', config.port, '...'); - var server = http.createServer(app); + var serverOptions = { + key: fs.readFileSync('path/to/your/private-key.pem'), + cert: fs.readFileSync('path/to/your/certificate.pem') + }; + var server = https.createServer(serverOptions, app); server.listen(config.port, config.host); } -exports.app = app; +exports.app = app; \ No newline at end of file diff --git a/test/session-test.js b/test/session-test.js index 9fe619410..c4693e0a0 100644 --- a/test/session-test.js +++ b/test/session-test.js @@ -22,7 +22,7 @@ if (!process.env.IN_TRAVIS) { it('logs in', function (done) { session. post('/login'). - send({ email: 'joesmith@opensoc.dev', password: 'opensoc' }). + send({ email: process.env.TEST_EMAIL, password: process.env.TEST_PASSWORD }). end(function (err, res) { // redirects to home assert.equal(res.header['location'], '/'); From 6ec18673ef2d58987f36c771c60743931eca3675 Mon Sep 17 00:00:00 2001 From: yjchoe818 Date: Thu, 24 Jul 2025 00:17:30 +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 2b34036d0..000000000 --- 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