From ce84a865f15a09df5e8e1599a7bd1069f76d740f Mon Sep 17 00:00:00 2001 From: Rami Winestock Date: Wed, 13 Dec 2023 21:51:43 +0200 Subject: [PATCH] Notify policy updates to open-appsec container. UI labels in log. --- backend/internal/nginx-openappsec.js | 69 ++++++++++++++++++- backend/internal/openappsec-log.js | 1 - backend/internal/proxy-host.js | 29 +++++--- backend/lib/constants.js | 4 ++ .../js/app/openappsec-log/list-all/item.ejs | 31 ++------- .../js/app/openappsec-log/list-all/main.ejs | 2 +- .../js/app/openappsec-log/list-all/main.js | 11 --- .../openappsec-log/list-important/item.ejs | 29 +------- .../openappsec-log/list-important/main.ejs | 2 +- .../app/openappsec-log/list-important/main.js | 1 - .../list-notifications/item.ejs | 24 +------ .../openappsec-log/list-notifications/main.js | 1 - frontend/js/app/openappsec-log/main.js | 18 ----- 13 files changed, 102 insertions(+), 120 deletions(-) diff --git a/backend/internal/nginx-openappsec.js b/backend/internal/nginx-openappsec.js index a8806156..1520fbd2 100755 --- a/backend/internal/nginx-openappsec.js +++ b/backend/internal/nginx-openappsec.js @@ -1,3 +1,6 @@ +const util = require('util'); +const execPromise = util.promisify(require('child_process').exec); +const { exec } = require('child_process'); const _ = require('lodash'); const fs = require('fs'); const logger = require('../logger').nginx; @@ -100,7 +103,24 @@ const internalNginxOpenappsec = { (err) => { logger.error('Error generating openappsec config:', err); return Promise.reject(err); + }) + .then(() => { + // Return the notifyPolicyUpdate promise chain + // notify openappsec to apply the policy + return internalNginxOpenappsec.notifyPolicyUpdate().catch((errorMessage) => { + console.error('Error:', errorMessage); + const errorMessageForUI = `Error: Policy couldn’t be applied, open-appsec-agent container is not responding. + Check if open-appec-agent container is running, then apply open-appsec Configuration + again by clicking here: +
Settings -> open-appsec Advanced -> Save Settings`; + + return Promise.reject(new Error(errorMessageForUI)); }); + }) + .catch((err) => { + logger.error('Error generating openappsec config:', err); + throw err; // Propagate the error to the caller + }); }, /** @@ -122,9 +142,22 @@ const internalNginxOpenappsec = { internalNginxOpenappsec.removeMatchingNodes(openappsecConfig, pattern); fs.writeFileSync(configFilePath, yaml.dump(openappsecConfig)); }) - .catch(err => { + .then(() => { + // Return the notifyPolicyUpdate promise chain + // notify openappsec to apply the policy + return internalNginxOpenappsec.notifyPolicyUpdate().catch((errorMessage) => { + console.error('---Error:', errorMessage); + const errorMessageForUI = `Error: Policy couldn’t be applied, open-appsec-agent container is not responding. + Check if open-appec-agent container is running, then apply open-appsec Configuration + again by clicking here: +
Settings -> open-appsec Advanced -> Save Settings`; + + return Promise.reject(new Error(errorMessageForUI)); + }); + }) + .catch((err) => { logger.error('Error deleting openappsec config:', err); - return Promise.reject(err); + throw err; // Propagate the error to the caller }); }, @@ -180,6 +213,38 @@ const internalNginxOpenappsec = { } }, + notifyPolicyUpdate: async function() { + if (!constants.USE_NOTIFY_POLICY) { + console.log('USE_NOTIFY_POLICY is false'); + return; + } + let ports = constants.PORTS; + console.log(`Notifying openappsec to apply the policy on ports ${ports}`); + let lastError = null; + + for (let port of ports) { + try { + const command = `curl -s -o /dev/null -w "%{http_code}" ${constants.HOSTURL}:${port}/openappsec/apply-policy`; + console.log(`command: ${command}`); + let { stdout } = await execPromise(command); + if (stdout === '200') { + console.log(`Policy applied successfully on port ${port}`); + return; + } else { + console.log(`Policy Unexpected response code: ${stdout}`); + lastError = new Error(`Unexpected response code: ${stdout}`); + } + } catch (error) { + console.log(`Error notifying openappsec to apply the policy on port ${port}: ${error.message}`); + lastError = error; + } + } + + if (lastError) { + throw lastError; + } + }, + /** * Recursively removes nodes from a JavaScript object based on a pattern. * diff --git a/backend/internal/openappsec-log.js b/backend/internal/openappsec-log.js index 74a23adc..dfdf19e5 100755 --- a/backend/internal/openappsec-log.js +++ b/backend/internal/openappsec-log.js @@ -100,7 +100,6 @@ const internalOpenappsecLog = { .then(async () => { const directoryPath = APPSEC_LOG_DIR; let totalDataLines = await this.countTotalLines(directoryPath); - console.log("totalLineCount: " + totalDataLines); const files = await fs.promises.readdir(directoryPath); const logFiles = files.filter(file => path.extname(file).startsWith('.log')); diff --git a/backend/internal/proxy-host.js b/backend/internal/proxy-host.js index a83413ca..f75607a4 100644 --- a/backend/internal/proxy-host.js +++ b/backend/internal/proxy-host.js @@ -95,9 +95,14 @@ const internalProxyHost = { }); }) .then(row => { - internalNginxOpenappsec.generateConfig(access, row, data) - return row; - }) + return internalNginxOpenappsec.generateConfig(access, row, data) + .then(() => { + return row; + }) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then((row) => { // Audit log data.meta = _.assign({}, data.meta || {}, row.meta); @@ -174,10 +179,14 @@ const internalProxyHost = { } }) .then(row => { - internalNginxOpenappsec.generateConfig(access, row, data); - // internalNginxOpenappsec.updateConfig(row, data) - return row; - }) + return internalNginxOpenappsec.generateConfig(access, row, data) + .then(() => { + return row; + }) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then((row) => { // Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here. data = _.assign({}, { @@ -316,7 +325,11 @@ const internalProxyHost = { }) .then(() => { // Delete openappsec config - internalNginxOpenappsec.deleteConfig(access, row); + return internalNginxOpenappsec.deleteConfig(access, row) + .catch((err) => { + throw new error.ConfigurationError(err.message); + }); + }) .then(() => { // Delete Nginx Config diff --git a/backend/lib/constants.js b/backend/lib/constants.js index d41a6343..7b961865 100755 --- a/backend/lib/constants.js +++ b/backend/lib/constants.js @@ -2,4 +2,8 @@ module.exports = { APPSEC_CONFIG_FILE_NAME: 'local_policy.yaml', APPSEC_EXT_DIR: '/ext/appsec', APPSEC_LOG_DIR: '/ext/appsec-logs', + USE_NOTIFY_POLICY: true, + PORTS: [7777, 7778], + HOSTURL: 'http://127.0.0.1', + POLICY_PATH: '/etc/cp/conf/local_policy.yaml', }; \ No newline at end of file diff --git a/frontend/js/app/openappsec-log/list-all/item.ejs b/frontend/js/app/openappsec-log/list-all/item.ejs index ecc0214c..087ea989 100644 --- a/frontend/js/app/openappsec-log/list-all/item.ejs +++ b/frontend/js/app/openappsec-log/list-all/item.ejs @@ -1,29 +1,6 @@ - - <%- formatDbDate(eventTime, 'D-M-YYYY, H:mm') %> - - -
- <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
- +<%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> +<%- eventSeverity %> <%- assetName %> <%- securityAction %> <%- waapIncidentType %> @@ -34,10 +11,10 @@ <%- httpMethod %> <%- httpResponseCode %> <%- httpUriPath %> -<%- protectionName %> +<%- eventTopic %> <%- matchedLocation %> <%- matchedParameter %> <%- matchedSample %> open - + \ No newline at end of file diff --git a/frontend/js/app/openappsec-log/list-all/main.ejs b/frontend/js/app/openappsec-log/list-all/main.ejs index 184cddd4..07ad186c 100644 --- a/frontend/js/app/openappsec-log/list-all/main.ejs +++ b/frontend/js/app/openappsec-log/list-all/main.ejs @@ -11,7 +11,7 @@ HTTP Method HTTP Response Code HTTP URI Path - Protection Name + Event Topic Matched Location Matched Parameter Matched Sample diff --git a/frontend/js/app/openappsec-log/list-all/main.js b/frontend/js/app/openappsec-log/list-all/main.js index 777d2db7..55b8bcde 100644 --- a/frontend/js/app/openappsec-log/list-all/main.js +++ b/frontend/js/app/openappsec-log/list-all/main.js @@ -8,7 +8,6 @@ let TableBody = Mn.CollectionView.extend({ initialize: function (options) { this.options = new Backbone.Model(options); - console.log("options: ", options); // this.page = options.page; // this.perPage = options.perPage; this.updatePage(); @@ -20,22 +19,12 @@ let TableBody = Mn.CollectionView.extend({ let page = this.page || 1; let models; if (this.perPage && this.page) { - console.log('updatePage2'); models = this.collection.models.slice((page - 1) * perPage, page * perPage); } else { - console.log('updatePage3'); - models = this.collection.models; } this.collection.reset(models); } - - // updatePage: function () { - // let perPage = this.perPage || this.collection.length; - // let page = this.page || 1; - // let models = this.collection.models.slice((page - 1) * perPage, page * perPage); - // this.collection.reset(models); - // } }); module.exports = Mn.View.extend({ diff --git a/frontend/js/app/openappsec-log/list-important/item.ejs b/frontend/js/app/openappsec-log/list-important/item.ejs index 5537babb..a6f8b3a1 100644 --- a/frontend/js/app/openappsec-log/list-important/item.ejs +++ b/frontend/js/app/openappsec-log/list-important/item.ejs @@ -1,29 +1,6 @@ - - <%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> - - -
- <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
- +<%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> +<%- eventSeverity %> <%- assetName %> <%- securityAction %> <%- waapIncidentType %> @@ -34,7 +11,7 @@ <%- httpMethod %> <%- httpResponseCode %> <%- httpUriPath %> -<%- protectionName %> +<%- eventTopic %> <%- matchedLocation %> <%- matchedParameter %> <%- matchedSample %> diff --git a/frontend/js/app/openappsec-log/list-important/main.ejs b/frontend/js/app/openappsec-log/list-important/main.ejs index 184cddd4..07ad186c 100644 --- a/frontend/js/app/openappsec-log/list-important/main.ejs +++ b/frontend/js/app/openappsec-log/list-important/main.ejs @@ -11,7 +11,7 @@ HTTP Method HTTP Response Code HTTP URI Path - Protection Name + Event Topic Matched Location Matched Parameter Matched Sample diff --git a/frontend/js/app/openappsec-log/list-important/main.js b/frontend/js/app/openappsec-log/list-important/main.js index 0c90551b..a7ef3281 100644 --- a/frontend/js/app/openappsec-log/list-important/main.js +++ b/frontend/js/app/openappsec-log/list-important/main.js @@ -15,7 +15,6 @@ let TableBody = Mn.CollectionView.extend({ }, updatePage: function () { - console.log('updatePage'); let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); this.collection.reset(models); } diff --git a/frontend/js/app/openappsec-log/list-notifications/item.ejs b/frontend/js/app/openappsec-log/list-notifications/item.ejs index e901a23e..86457f26 100644 --- a/frontend/js/app/openappsec-log/list-notifications/item.ejs +++ b/frontend/js/app/openappsec-log/list-notifications/item.ejs @@ -1,27 +1,5 @@ - <%- formatDbDate(eventTime, 'D-M-YY, H:mm') %> - -
- <% var sevirityClass = 'bg-success'; - switch (eventSeverity) { - case 'Critical': - sevirityClass = 'bg-danger'; - break; - case 'Warning': - sevirityClass = 'bg-warning'; - break; - case 'Info': - sevirityClass = 'bg-success'; - //sevirityClass = 'bg-info'; - break; - case 'Debug': - sevirityClass = 'bg-success'; - break; - } - %> - <%- eventSeverity %> -
- +<%- eventSeverity %> <%- eventPriority %> <%- eventTopic %> <%- eventName %> diff --git a/frontend/js/app/openappsec-log/list-notifications/main.js b/frontend/js/app/openappsec-log/list-notifications/main.js index 0c90551b..a7ef3281 100644 --- a/frontend/js/app/openappsec-log/list-notifications/main.js +++ b/frontend/js/app/openappsec-log/list-notifications/main.js @@ -15,7 +15,6 @@ let TableBody = Mn.CollectionView.extend({ }, updatePage: function () { - console.log('updatePage'); let models = this.collection.models.slice((this.page - 1) * this.perPage, this.page * this.perPage); this.collection.reset(models); } diff --git a/frontend/js/app/openappsec-log/main.js b/frontend/js/app/openappsec-log/main.js index 8f2ecad6..cb992877 100755 --- a/frontend/js/app/openappsec-log/main.js +++ b/frontend/js/app/openappsec-log/main.js @@ -182,24 +182,6 @@ module.exports = Mn.View.extend({ onTabClick: function(event) { event.preventDefault(); const selectedTab = event.target.id; - - console.log("selectedTab: ", selectedTab); - - // let ListView; - // switch (selectedTab) { - // case 'tab1': - // ListView = ListViewTab1; - // break; - // case 'tab2': - // ListView = ListViewTab2; - // break; - // case 'tab3': - // ListView = ListViewTab3; - // break; - // default: - // ListView = ListViewTab1; - // } - let view = this; let query = this.ui.query.val() || '';