diff --git a/CHANGELOG.md b/CHANGELOG.md index 069134d2..da10b367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. ## [v3.13.1] +### Added + +- New filters in request `GET /sca/:agent_id/checks/:policy_id`: + * `reason`: Filters the SCA checks by 'reason' field ([#492](https://github.com/wazuh/wazuh-api/issues/492)). + * `status`: Filters the SCA checks by 'status' field ([#492](https://github.com/wazuh/wazuh-api/issues/492)). + * `command`: Filters the SCA checks by 'command' field ([#492](https://github.com/wazuh/wazuh-api/issues/492)). + + ## [v3.13.0] ### Added diff --git a/controllers/security_configuration_assessment.js b/controllers/security_configuration_assessment.js index 17cde9fc..f86aac41 100755 --- a/controllers/security_configuration_assessment.js +++ b/controllers/security_configuration_assessment.js @@ -61,6 +61,9 @@ router.get('/:agent_id', cache(), function(req, res) { * @apiParam {Number} [limit=500] Maximum number of elements to return. * @apiParam {String} [sort] Sorts the collection by a field or fields (separated by comma). Use +/- at the beginning to list in ascending or descending order. * @apiParam {String} [search] Looks for elements with the specified string. + * @apiParam {String} [command] Looks for elements with the specified command. + * @apiParam {String} [status] Looks for elements with the specified status. + * @apiParam {String} [reason] Looks for elements with the specified reason. * * @apiDescription Returns the sca checks of an agent. * @@ -69,11 +72,12 @@ router.get('/:agent_id', cache(), function(req, res) { * */ router.get('/:agent_id/checks/:policy_id', cache(), function(req, res) { - query_checks = {'title': 'alphanumeric_param', 'description': 'alphanumeric_param', - 'rationale': 'alphanumeric_param', 'remediation': 'alphanumeric_param', + query_checks = {'title': 'symbols_alphanumeric_param', 'description': 'symbols_alphanumeric_param', + 'rationale': 'symbols_alphanumeric_param', 'remediation': 'symbols_alphanumeric_param', 'file': 'paths', 'process': 'alphanumeric_param', 'directory': 'paths', 'registry': 'alphanumeric_param', 'references': 'encoded_uri', - 'result': 'alphanumeric_param', 'condition': 'alphanumeric_param' + 'result': 'alphanumeric_param', 'condition': 'alphanumeric_param', 'command': 'alphanumeric_param', + 'status': 'alphanumeric_param', 'reason': 'symbols_alphanumeric_param' }; templates.array_request("/sca/:agent_id/checks/:policy_id", req, res, "sca", diff --git a/helpers/input_validation.js b/helpers/input_validation.js index c10c0fd8..1b9a5505 100755 --- a/helpers/input_validation.js +++ b/helpers/input_validation.js @@ -47,6 +47,10 @@ exports.alphanumeric_param = function(param) { return input_val(param, /^[a-zA-Z0-9_,\-\.\+\s\:]+$/); } +exports.symbols_alphanumeric_param = function(param) { + return input_val(param, /^[a-zA-Z0-9_,<>!\-.+\s:\/()'"|=]+$/); +} + exports.sort_param = function(param) { return input_val(param, /^[a-zA-Z0-9_\-\,\s\+\.]+$/); // + is translated as \s } diff --git a/test/test_sca.js b/test/test_sca.js index e6ad0d60..313d358d 100644 --- a/test/test_sca.js +++ b/test/test_sca.js @@ -408,6 +408,47 @@ describe('SecurityConfigurationAssessment', function() { }); }); + it('Filters: title', function(done) { + request(common.url) + .get("/sca/000/checks/cis_debian9_L2?&title=Ensure%20events%20that%20modify%20the%20system%27s%20Mandatory%20Access%20Controls%20are%20collected%20%28SELinux%29&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.above(0); + res.body.data.items.should.be.instanceof(Array); + res.body.data.items[0].should.have.properties(sca_check_fields); + + done(); + }); + + }); + + it('Filters: incomplete title', function(done) { + request(common.url) + .get("/sca/000/checks/cis_debian9_L2?title=Ensure%20events%20that&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.equal(0); + res.body.data.items.should.be.instanceof(Array); + + done(); + }); + + }); + it('Filters: description', function(done) { request(common.url) .get("/sca/000/checks/unix_audit?description=Turn%20on%20the%20auditd%20daemon%20to%20record%20system%20events.&limit=1") @@ -429,6 +470,27 @@ describe('SecurityConfigurationAssessment', function() { }); + it('Filters: rationale', function(done) { + request(common.url) + .get("/sca/000/checks/cis_debian9_L2?rationale=In%20high%20security%20contexts%2C%20the%20risk%20of%20detecting%20unauthorized%20access%20or%20nonrepudiation%20exceeds%20the%20benefit%20of%20the%20system%27s%20availability.&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.above(0); + res.body.data.items.should.be.instanceof(Array); + res.body.data.items[0].should.have.properties(sca_check_fields); + + done(); + }); + + }); + it('Filters: remediation', function(done) { request(common.url) .get("/sca/000/checks/unix_audit?remediation=Change%20the%20Port%20option%20value%20in%20the%20sshd_config%20file.&limit=1") @@ -513,6 +575,69 @@ describe('SecurityConfigurationAssessment', function() { }); + it('Filters: command', function(done) { + request(common.url) + .get("/sca/000/checks/unix_audit?command=systemctl%20is-enabled%20auditd&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.above(0); + res.body.data.items.should.be.instanceof(Array); + res.body.data.items[0].should.have.properties(sca_check_fields); + + done(); + }); + + }); + + it('Filters: status', function(done) { + request(common.url) + .get("/sca/000/checks/unix_audit?status=Not%20applicable&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.above(0); + res.body.data.items.should.be.instanceof(Array); + res.body.data.items[0].should.have.properties(sca_check_fields); + + done(); + }); + + }); + + it('Filters: reason', function(done) { + request(common.url) + .get("/sca/000/checks/cis_debian9_L2?reason=Could%20not%20open%20file%20%27%2Fetc%2Fdefault%2Fgrub%27&limit=1") + .auth(common.credentials.user, common.credentials.password) + .expect("Content-type",/json/) + .expect(200) + .end(function(err,res){ + if (err) return done(err); + + res.body.should.have.properties(['error', 'data']); + + res.body.error.should.equal(0); + res.body.data.totalItems.should.be.above(0); + res.body.data.items.should.be.instanceof(Array); + res.body.data.items[0].should.have.properties(sca_check_fields); + + done(); + }); + + }); + it('Filters: condition', function(done) { request(common.url) .get("/sca/000/checks/unix_audit?condition=all&limit=1")