Skip to content

Commit f9ae99e

Browse files
committed
first open-appsec support
1 parent 81a3895 commit f9ae99e

File tree

22 files changed

+440
-8
lines changed

22 files changed

+440
-8
lines changed

backend/internal/proxy-host.js

+60-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ const utils = require('../lib/utils');
44
const proxyHostModel = require('../models/proxy_host');
55
const internalHost = require('./host');
66
const internalNginx = require('./nginx');
7+
const internalNginxOpenappsec= require('./nginx-openappsec');
78
const internalAuditLog = require('./audit-log');
89
const internalCertificate = require('./certificate');
10+
const fs = require('fs');
11+
const path = require('path');
12+
const yaml = require('js-yaml');
913

1014
function omissions () {
1115
return ['is_deleted'];
@@ -48,9 +52,15 @@ const internalProxyHost = {
4852
data.owner_user_id = access.token.getUserId(1);
4953
data = internalHost.cleanSslHstsData(data);
5054

55+
let db_data = _.assign({}, data);
56+
// Remove the openappsec fields from data. they are not in the database.
57+
delete db_data.use_openappsec;
58+
delete db_data.openappsec_mode;
59+
delete db_data.minimum_confidence;
60+
5161
return proxyHostModel
5262
.query()
53-
.insertAndFetch(data)
63+
.insertAndFetch(db_data)
5464
.then(utils.omitRow(omissions()));
5565
})
5666
.then((row) => {
@@ -84,6 +94,10 @@ const internalProxyHost = {
8494
return row;
8595
});
8696
})
97+
.then(row => {
98+
internalNginxOpenappsec.generateConfig(access, row, data)
99+
return row;
100+
})
87101
.then((row) => {
88102
// Audit log
89103
data.meta = _.assign({}, data.meta || {}, row.meta);
@@ -159,6 +173,11 @@ const internalProxyHost = {
159173
return row;
160174
}
161175
})
176+
.then(row => {
177+
internalNginxOpenappsec.generateConfig(access, row, data);
178+
// internalNginxOpenappsec.updateConfig(row, data)
179+
return row;
180+
})
162181
.then((row) => {
163182
// Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here.
164183
data = _.assign({}, {
@@ -167,6 +186,11 @@ const internalProxyHost = {
167186

168187
data = internalHost.cleanSslHstsData(data, row);
169188

189+
// Remove the openappsec fields from data. they are not in the database
190+
delete data.use_openappsec;
191+
delete data.openappsec_mode;
192+
delete data.minimum_confidence;
193+
170194
return proxyHostModel
171195
.query()
172196
.where({id: data.id})
@@ -247,6 +271,22 @@ const internalProxyHost = {
247271
if (typeof data.omit !== 'undefined' && data.omit !== null) {
248272
row = _.omit(row, data.omit);
249273
}
274+
return row;
275+
})
276+
.then((row) => {
277+
// add openappsec fields to row
278+
try {
279+
const configFilePath = internalNginxOpenappsec.getConfigFilePath(access);
280+
const openappsecConfig = yaml.load(fs.readFileSync(configFilePath, 'utf8'));
281+
let result = internalNginxOpenappsec.getOpenappsecFields(openappsecConfig, row.id);
282+
row.use_openappsec = result.use_openappsec;
283+
row.openappsec_mode = result.mode;
284+
row.minimum_confidence = result.minimum_confidence;
285+
}
286+
catch (e) {
287+
console.log("Error reading openappsec config file: " + e);
288+
}
289+
250290
return row;
251291
});
252292
},
@@ -274,6 +314,10 @@ const internalProxyHost = {
274314
.patch({
275315
is_deleted: 1
276316
})
317+
.then(() => {
318+
// Delete openappsec config
319+
internalNginxOpenappsec.deleteConfig(access, row);
320+
})
277321
.then(() => {
278322
// Delete Nginx Config
279323
return internalNginx.deleteConfig('proxy_host', row)
@@ -430,6 +474,21 @@ const internalProxyHost = {
430474
return query.then(utils.omitRows(omissions()));
431475
})
432476
.then((rows) => {
477+
// add openappsec fields to rows
478+
try {
479+
const configFilePath = internalNginxOpenappsec.getConfigFilePath(access);
480+
const openappsecConfig = yaml.load(fs.readFileSync(configFilePath, 'utf8'));
481+
rows.map(function (row, idx) {
482+
let result = internalNginxOpenappsec.getOpenappsecFields(openappsecConfig, row.id);
483+
rows[idx].use_openappsec = result.use_openappsec;
484+
rows[idx].openappsec_mode = result.mode;
485+
rows[idx].minimum_confidence = result.minimum_confidence;
486+
});
487+
}
488+
catch (e) {
489+
console.log("Error reading openappsec config file: " + e);
490+
}
491+
433492
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
434493
return internalHost.cleanAllRowsCertificateMeta(rows);
435494
}

backend/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"express": "^4.17.3",
1414
"express-fileupload": "^1.1.9",
1515
"gravatar": "^1.8.0",
16+
"js-yaml": "^4.1.0",
1617
"json-schema-ref-parser": "^8.0.0",
1718
"jsonwebtoken": "^9.0.0",
1819
"knex": "2.4.2",

backend/routes/api/main.js

+2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ router.use('/schema', require('./schema'));
2929
router.use('/tokens', require('./tokens'));
3030
router.use('/users', require('./users'));
3131
router.use('/audit-log', require('./audit-log'));
32+
router.use('/openappsec-log', require('./openappsec-log'));
3233
router.use('/reports', require('./reports'));
3334
router.use('/settings', require('./settings'));
35+
router.use('/openappsec-settings', require('./openappsec-settings'));
3436
router.use('/nginx/proxy-hosts', require('./nginx/proxy_hosts'));
3537
router.use('/nginx/redirection-hosts', require('./nginx/redirection_hosts'));
3638
router.use('/nginx/dead-hosts', require('./nginx/dead_hosts'));

backend/schema/definitions.json

+17
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@
137137
}
138138
]
139139
},
140+
"openappsec_mode": {
141+
"description": "openappsec_mode ID",
142+
"type": "string",
143+
"minLength": 1,
144+
"maxLength": 255
145+
},
146+
"minimum_confidence": {
147+
"description": "minimum_confidence ID",
148+
"type": "string",
149+
"minLength": 1,
150+
"maxLength": 255
151+
},
140152
"access_list_id": {
141153
"description": "Access List ID",
142154
"example": 1234,
@@ -231,6 +243,11 @@
231243
"example": true,
232244
"type": "boolean"
233245
},
246+
"use_openappsec": {
247+
"description": "Use openappsec",
248+
"example": true,
249+
"type": "boolean"
250+
},
234251
"caching_enabled": {
235252
"description": "Should we cache assets",
236253
"example": true,

backend/schema/endpoints/proxy-hosts.json

+45
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@
5050
"block_exploits": {
5151
"$ref": "../definitions.json#/definitions/block_exploits"
5252
},
53+
"use_openappsec": {
54+
"$ref": "../definitions.json#/definitions/use_openappsec"
55+
},
56+
"openappsec_mode": {
57+
"$ref": "../definitions.json#/definitions/openappsec_mode"
58+
},
59+
"minimum_confidence": {
60+
"$ref": "../definitions.json#/definitions/minimum_confidence"
61+
},
5362
"caching_enabled": {
5463
"$ref": "../definitions.json#/definitions/caching_enabled"
5564
},
@@ -104,6 +113,15 @@
104113
},
105114
"advanced_config": {
106115
"type": "string"
116+
},
117+
"use_openappsec": {
118+
"type": "boolean"
119+
},
120+
"openappsec_mode": {
121+
"type": "string"
122+
},
123+
"minimum_confidence": {
124+
"type": "string"
107125
}
108126
}
109127
}
@@ -149,6 +167,15 @@
149167
"block_exploits": {
150168
"$ref": "#/definitions/block_exploits"
151169
},
170+
"use_openappsec": {
171+
"$ref": "#/definitions/use_openappsec"
172+
},
173+
"openappsec_mode": {
174+
"$ref": "#/definitions/openappsec_mode"
175+
},
176+
"minimum_confidence": {
177+
"$ref": "#/definitions/minimum_confidence"
178+
},
152179
"caching_enabled": {
153180
"$ref": "#/definitions/caching_enabled"
154181
},
@@ -239,6 +266,15 @@
239266
"block_exploits": {
240267
"$ref": "#/definitions/block_exploits"
241268
},
269+
"use_openappsec": {
270+
"$ref": "#/definitions/use_openappsec"
271+
},
272+
"openappsec_mode": {
273+
"$ref": "#/definitions/openappsec_mode"
274+
},
275+
"minimum_confidence": {
276+
"$ref": "#/definitions/minimum_confidence"
277+
},
242278
"caching_enabled": {
243279
"$ref": "#/definitions/caching_enabled"
244280
},
@@ -312,6 +348,15 @@
312348
"block_exploits": {
313349
"$ref": "#/definitions/block_exploits"
314350
},
351+
"use_openappsec": {
352+
"$ref": "#/definitions/use_openappsec"
353+
},
354+
"openappsec_mode": {
355+
"$ref": "#/definitions/openappsec_mode"
356+
},
357+
"minimum_confidence": {
358+
"$ref": "#/definitions/minimum_confidence"
359+
},
315360
"caching_enabled": {
316361
"$ref": "#/definitions/caching_enabled"
317362
},

docker/docker-compose.dev.yml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ services:
3333
volumes:
3434
- npm_data:/data
3535
- le_data:/etc/letsencrypt
36+
- ../localconfig:/ext/appsec
3637
- ../backend:/app
3738
- ../frontend:/app/frontend
3839
- ../global:/app/global

frontend/html/partials/header.ejs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<meta name="msapplication-TileColor" content="#333333">
2222
<meta name="msapplication-config" content="/images/favicons/browserconfig.xml">
2323
<meta name="theme-color" content="#ffffff">
24+
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@600&display=swap" rel="stylesheet">
2425
<link href="/css/main.css?v=<%= version %>" rel="stylesheet">
2526
</head>
2627
<body>

frontend/js/app/api.js

+28
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,17 @@ module.exports = {
716716
}
717717
},
718718

719+
OpenappsecLog: {
720+
/**
721+
* @param {Array} [expand]
722+
* @param {String} [query]
723+
* @returns {Promise}
724+
*/
725+
getAll: function (expand, query) {
726+
return getAllObjects('openappsec-log', expand, query);
727+
}
728+
},
729+
719730
Reports: {
720731

721732
/**
@@ -753,5 +764,22 @@ module.exports = {
753764
delete data.id;
754765
return fetch('put', 'settings/' + id, data);
755766
}
767+
},
768+
769+
OpenAppsecSettings: {
770+
/**
771+
* @returns {Promise}
772+
*/
773+
get: function () {
774+
return fetch('get', 'openappsec-settings');
775+
},
776+
777+
/**
778+
* @param {Object} data
779+
* @returns {Promise}
780+
*/
781+
save: function (data) {
782+
return fetch('put', 'openappsec-settings', data);
756783
}
784+
},
757785
};

frontend/js/app/controller.js

+28
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,34 @@ module.exports = {
407407
}
408408
},
409409

410+
/**
411+
* openappsec Log
412+
*/
413+
showOpenappsecLog: function () {
414+
let controller = this;
415+
if (Cache.User.isAdmin()) {
416+
require(['./main', './openappsec-log/main'], (App, View) => {
417+
controller.navigate('/openappsec-log');
418+
App.UI.showAppContent(new View());
419+
});
420+
} else {
421+
this.showDashboard();
422+
}
423+
},
424+
425+
/**
426+
* openappsec Log Metadata
427+
*
428+
* @param model
429+
*/
430+
showOpenappsecMeta: function (model) {
431+
if (Cache.User.isAdmin()) {
432+
require(['./main', './openappsec-log/meta'], function (App, View) {
433+
App.UI.showModalDialog(new View({model: model}));
434+
});
435+
}
436+
},
437+
410438
/**
411439
* Settings
412440
*/

frontend/js/app/nginx/proxy/form.ejs

+35
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
</label>
7373
</div>
7474
</div>
75+
7576
<div class="col-sm-12 col-md-12">
7677
<div class="form-group">
7778
<label class="custom-switch">
@@ -90,6 +91,40 @@
9091
</select>
9192
</div>
9293
</div>
94+
95+
<div class="col-sm-12 col-md-12">
96+
<hr class="my-3">
97+
98+
<div class="form-group">
99+
<label class="custom-switch">
100+
<input type="checkbox" class="custom-switch-input" name="use_openappsec" value="1"<%- use_openappsec ? ' checked' : '' %>>
101+
<span class="custom-switch-indicator"></span>
102+
<span class="custom-switch-description font-weight-bold">open-appsec</span>
103+
</label>
104+
</div>
105+
</div>
106+
107+
<div class="col-sm-12 col-md-12">
108+
<div class="form-group row">
109+
<label class="col-sm-6 col-form-label <%- use_openappsec ? '' : ' text-muted' %>">Enforcement Mode</label>
110+
<select name="openappsec_mode" class="col-sm-4 form-control custom-select" placeholder="Please Select" <%- use_openappsec ? '' : ' disabled' %>>
111+
<option value="detect-learn" <%- openappsec_mode === 'detect-learn' ? 'selected' : '' %>>Detect-Learn</option>
112+
<option value="prevent-learn" <%- openappsec_mode === 'prevent-learn' ? 'selected' : '' %>>Prevent-Learn</option>
113+
</select>
114+
</div>
115+
</div>
116+
117+
<div class="col-sm-12 col-md-12">
118+
<div class="form-group row">
119+
<label class="col-sm-6 col-form-label <%- use_openappsec ? '' : ' text-muted' %>">Minimum confidence for prevent</label>
120+
<select name="minimum_confidence" class="col-sm-4 form-control custom-select" placeholder="Please Select" <%- use_openappsec ? '' : ' disabled' %>>
121+
<option value="critical" <%- minimum_confidence === 'critical' ? 'selected' : '' %>>Critical</option>
122+
<option value="high" <%- minimum_confidence === 'high' ? 'selected' : '' %>>High</option>
123+
<option value="medium" <%- minimum_confidence === 'medium' ? 'selected' : '' %>>Medium</option>
124+
</select>
125+
</div>
126+
</div>
127+
93128
</div>
94129
</div>
95130

0 commit comments

Comments
 (0)