diff --git a/SplunkAppForWazuh/appserver/controllers/api.py b/SplunkAppForWazuh/appserver/controllers/api.py index 691b6c93b..34f609ddd 100644 --- a/SplunkAppForWazuh/appserver/controllers/api.py +++ b/SplunkAppForWazuh/appserver/controllers/api.py @@ -12,7 +12,6 @@ Find more information about this on the LICENSE file. """ - import jsonbak import requestsbak import csv @@ -22,8 +21,7 @@ from db import database from log import log from splunk.clilib import cli_common as cli - - +from requirements import pci_requirements,gdpr_requirements class api(controllers.BaseController): @@ -43,6 +41,23 @@ def __init__(self): except Exception as e: self.logger.error("Error in API module constructor: %s" % (e)) + def get_credentials(self,the_id): + try: + api = self.db.get(the_id) + if api: + opt_username = api[0]["userapi"] + opt_password = api[0]["passapi"] + opt_base_url = api[0]["url"] + opt_base_port = api[0]["portapi"] + url = opt_base_url + ":" + opt_base_port + auth = requestsbak.auth.HTTPBasicAuth(opt_username, opt_password) + verify = False + return url, auth, verify + else: + raise Exception('API not found') + except Exception as e: + raise e + def getSelfAdminStanza(self): """Get the configuration from a stanza. """ @@ -117,9 +132,6 @@ def format_output(self, arr): except Exception as e: raise e - # /custom/SplunkAppForWazuh/api/node - # This will perform an HTTP request to Wazuh API - # It will return the full API response with including its error codes @expose_page(must_login=False, methods=['POST']) def request(self, **kwargs): """Make requests to the Wazuh API as a proxy backend. @@ -144,45 +156,37 @@ def request(self, **kwargs): method = kwargs['method'] del kwargs['method'] the_id = kwargs['id'] - api = self.db.get(the_id) - if api: - opt_username = api[0]["userapi"] - opt_password = api[0]["passapi"] - opt_base_url = api[0]["url"] - opt_base_port = api[0]["portapi"] - opt_endpoint = kwargs["endpoint"] - del kwargs['id'] - del kwargs['endpoint'] - url = opt_base_url + ":" + opt_base_port - auth = requestsbak.auth.HTTPBasicAuth(opt_username, opt_password) - verify = False - if method == 'GET': - request = self.session.get( - url + opt_endpoint, params=kwargs, auth=auth, - verify=verify).json() - if method == 'POST': - if 'origin' in kwargs: - if kwargs['origin'] == 'xmleditor': - headers = {'Content-Type': 'application/xml'} - elif kwargs['origin'] == 'json': - headers = {'Content-Type': 'application/json'} - elif kwargs['origin'] == 'raw': - headers = {'Content-Type': 'application/octet-stream'} - kwargs = str(kwargs['content']) - request = self.session.post(url + opt_endpoint, data=kwargs, auth=auth,verify=verify, headers=headers).json() - else: - request = self.session.post( - url + opt_endpoint, data=kwargs, auth=auth, - verify=verify).json() - if method == 'PUT': - request = self.session.put( - url + opt_endpoint, data=kwargs, auth=auth, - verify=verify).json() - if method == 'DELETE': - request = self.session.delete( + url,auth,verify = self.get_credentials(the_id) + opt_endpoint = kwargs["endpoint"] + del kwargs['id'] + del kwargs['endpoint'] + if method == 'GET': + request = self.session.get( + url + opt_endpoint, params=kwargs, auth=auth, + verify=verify).json() + if method == 'POST': + if 'origin' in kwargs: + if kwargs['origin'] == 'xmleditor': + headers = {'Content-Type': 'application/xml'} + elif kwargs['origin'] == 'json': + headers = {'Content-Type': 'application/json'} + elif kwargs['origin'] == 'raw': + headers = {'Content-Type': 'application/octet-stream'} + kwargs = str(kwargs['content']) + request = self.session.post(url + opt_endpoint, data=kwargs, auth=auth,verify=verify, headers=headers).json() + else: + request = self.session.post( url + opt_endpoint, data=kwargs, auth=auth, verify=verify).json() - result = jsonbak.dumps(request) + if method == 'PUT': + request = self.session.put( + url + opt_endpoint, data=kwargs, auth=auth, + verify=verify).json() + if method == 'DELETE': + request = self.session.delete( + url + opt_endpoint, data=kwargs, auth=auth, + verify=verify).json() + result = jsonbak.dumps(request) except Exception as e: self.logger.error("Error making API request: %s" % (e)) return jsonbak.dumps({'error': str(e)}) @@ -197,7 +201,6 @@ def autocomplete(self, **kwargs): return jsonbak.dumps({'error': str(e)}) return parsed_json - # POST /api/csv : Generates a CSV file with the returned data from API @expose_page(must_login=False, methods=['POST']) def csv(self, **kwargs): @@ -289,3 +292,75 @@ def csv(self, **kwargs): self.logger.error("Error in CSV generation!: %s" % (str(e))) return jsonbak.dumps({"error": str(e)}) return csv_result + + @expose_page(must_login=False, methods=['GET']) + def pci(self, **kwargs): + try: + if not 'requirement' in kwargs: + raise Exception('Missing requirement.') + pci_description = '' + requirement = kwargs['requirement'] + if requirement == 'all': + if not 'id' in kwargs: + return jsonbak.dumps(pci_requirements.pci) + the_id = kwargs['id'] + url,auth,verify = self.get_credentials(the_id) + opt_endpoint = '/rules/pci' + request = self.session.get( + url + opt_endpoint, params=kwargs, auth=auth, + verify=verify).json() + if request['error'] != 0: + return jsonbak.dumps({'error':request['error']}) + data = request['data']['items'] + result = {} + for item in data: + result[item] = pci_requirements.pci[item] + return jsonbak.dumps(result) + else: + if not requirement in pci_requirements.pci: + return jsonbak.dumps({'error':'Requirement not found.'}) + pci_description = pci_requirements.pci[requirement] + result = {} + result['pci'] = {} + result['pci']['requirement'] = requirement + result['pci']['description'] = pci_description + return jsonbak.dumps(result) + except Exception as e: + self.logger.error("Error getting PCI-DSS requirements: %s" % (str(e))) + return jsonbak.dumps({"error": str(e)}) + + @expose_page(must_login=False, methods=['GET']) + def gdpr(self, **kwargs): + try: + if not 'requirement' in kwargs: + raise Exception('Missing requirement.') + pci_description = '' + requirement = kwargs['requirement'] + if requirement == 'all': + if not 'id' in kwargs: + return jsonbak.dumps(gdpr_requirements.gdpr) + the_id = kwargs['id'] + url,auth,verify = self.get_credentials(the_id) + opt_endpoint = '/rules/gdpr' + request = self.session.get( + url + opt_endpoint, params=kwargs, auth=auth, + verify=verify).json() + if request['error'] != 0: + return jsonbak.dumps({'error':request['error']}) + data = request['data']['items'] + result = {} + for item in data: + result[item] = gdpr_requirements.gdpr[item] + return jsonbak.dumps(result) + else: + if not requirement in gdpr_requirements.gdpr: + return jsonbak.dumps({'error':'Requirement not found.'}) + pci_description = gdpr_requirements.gdpr[requirement] + result = {} + result['gdpr'] = {} + result['gdpr']['requirement'] = requirement + result['gdpr']['description'] = pci_description + return jsonbak.dumps(result) + except Exception as e: + self.logger.error("Error getting PCI-DSS requirements: %s" % (str(e))) + return jsonbak.dumps({"error": str(e)}) \ No newline at end of file diff --git a/SplunkAppForWazuh/appserver/static/js/config/routes/agents-states.js b/SplunkAppForWazuh/appserver/static/js/config/routes/agents-states.js index 3f2db030f..f2680c430 100644 --- a/SplunkAppForWazuh/appserver/static/js/config/routes/agents-states.js +++ b/SplunkAppForWazuh/appserver/static/js/config/routes/agents-states.js @@ -1,10 +1,10 @@ -define(['../module'], function(module) { +define(['../module'], function (module) { 'use strict' module.config([ '$stateProvider', 'BASE_URL', - function($stateProvider, BASE_URL) { + function ($stateProvider, BASE_URL) { $stateProvider // agents @@ -40,14 +40,14 @@ define(['../module'], function(module) { select: 'version' }), responseStatus && - responseStatus.data && - responseStatus.data.data && - responseStatus.data.data.enabled === 'yes' && - responseStatus.data.data.running === 'yes' + responseStatus.data && + responseStatus.data.data && + responseStatus.data.data.enabled === 'yes' && + responseStatus.data.data.running === 'yes' ? $requestService.apiReq('/agents/stats/distinct', { - fields: 'node_name', - select: 'node_name' - }) + fields: 'node_name', + select: 'node_name' + }) : Promise.resolve(false), $requestService.apiReq('/agents/groups', {}) ]) @@ -525,6 +525,23 @@ define(['../module'], function(module) { $state.go('agents') } } + ], + gdprTabs: [ + '$requestService', + '$state', + async ($requestService, $state) => { + try { + const gdprTabs = [] + const data = await $requestService.httpReq('GET', '/api/gdpr?requirement=all') + if (!data) return [] + for (const key in data.data) { + gdprTabs.push({ title: key, content: data.data[key] }) + } + return gdprTabs + } catch (err) { + $state.go('settings.api') + } + } ] } }) @@ -599,7 +616,25 @@ define(['../module'], function(module) { $state.go('agents') } } + ], + pciTabs: [ + '$requestService', + '$state', + async ($requestService, $state) => { + try { + const pciTabs = [] + const data = await $requestService.httpReq('GET', '/api/pci?requirement=all') + if (!data) return [] + for (const key in data.data) { + pciTabs.push({ title: key, content: data.data[key] }) + } + return pciTabs + } catch (err) { + $state.go('settings.api') + } + } ] + } }) diff --git a/SplunkAppForWazuh/appserver/static/js/config/routes/overview-states.js b/SplunkAppForWazuh/appserver/static/js/config/routes/overview-states.js index 2e71823bb..d9fc8b6c1 100644 --- a/SplunkAppForWazuh/appserver/static/js/config/routes/overview-states.js +++ b/SplunkAppForWazuh/appserver/static/js/config/routes/overview-states.js @@ -161,7 +161,26 @@ define(['../module'], function(module) { onEnter: $navigationService => { $navigationService.storeRoute('ow-pci') }, - controller: 'overviewPciCtrl' + controller: 'overviewPciCtrl', + resolve: { + pciTabs: [ + '$requestService', + '$state', + async ($requestService, $state) => { + try { + const pciTabs = [] + const data = await $requestService.httpReq('GET','/api/pci?requirement=all') + if (!data) return [] + for (const key in data.data) { + pciTabs.push({ title: key, content: data.data[key] }) + } + return pciTabs + } catch (err) { + $state.go('settings.api') + } + } + ] + } }) // Overview - GDPR .state('ow-gdpr', { @@ -171,8 +190,28 @@ define(['../module'], function(module) { onEnter: $navigationService => { $navigationService.storeRoute('ow-gdpr') }, - controller: 'overviewGdprCtrl' + controller: 'overviewGdprCtrl', + resolve: { + gdprTabs: [ + '$requestService', + '$state', + async ($requestService, $state) => { + try { + const gdprTabs = [] + const data = await $requestService.httpReq('GET','/api/gdpr?requirement=all') + if (!data) return [] + for (const key in data.data) { + gdprTabs.push({ title: key, content: data.data[key] }) + } + return gdprTabs + } catch (err) { + $state.go('settings.api') + } + } + ] + } }) + // Overview - Vulnerabilities .state('ow-vul', { templateUrl: diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agents-gdpr.html b/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agents-gdpr.html index bf4fd3b78..1c12c4981 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agents-gdpr.html +++ b/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agents-gdpr.html @@ -34,12 +34,12 @@
- +
- GDPR Requirement: {{tab.rule}} + GDPR Requirement: {{tab.title}}
-
{{tab.description}}
+
{{tab.content}}
diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agentsGdprCtrl.js b/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agentsGdprCtrl.js index 8e51ef8e1..bf3e3249e 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agentsGdprCtrl.js +++ b/SplunkAppForWazuh/appserver/static/js/controllers/agents/gdpr/agentsGdprCtrl.js @@ -34,7 +34,8 @@ define([ $scope, $state, agent, - $reportingService + $reportingService, + gdprTabs ) { this.scope = $scope this.state = $state @@ -77,9 +78,7 @@ define([ $urlTokenModel.handleValueChange(this.dropdownInstance) } }) - - this.scope.gdprTabs = false - + this.scope.gdprTabs = (gdprTabs) ? gdprTabs : false this.scope.$on('deletedFilter', () => { this.launchSearches() }) @@ -104,7 +103,7 @@ define([ 'groupsVizz', `${ this.filters - } sourcetype=wazuh rule.gdpr{}="$gdpr$" | stats count by rule.groups`, + } sourcetype=wazuh rule.gdpr{}="$gdpr$" | stats count by rule.groups{}`, 'groupsVizz', this.scope ), diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agents-pci.html b/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agents-pci.html index a7c51740d..c751367c5 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agents-pci.html +++ b/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agents-pci.html @@ -37,12 +37,12 @@
- +
- PCI-DSS Requirement: {{tab.rule}} + PCI-DSS Requirement: {{tab.title}}
-
{{tab.description}}
+
{{tab.content}}
diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agentsPciCtrl.js b/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agentsPciCtrl.js index 1a02d55dc..9c144a42c 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agentsPciCtrl.js +++ b/SplunkAppForWazuh/appserver/static/js/controllers/agents/pcidss/agentsPciCtrl.js @@ -33,13 +33,15 @@ define([ $state, $currentDataService, agent, - $reportingService + $reportingService, + pciTabs ) { this.state = $state this.reportingService = $reportingService this.tableResults = {} this.currentDataService = $currentDataService this.scope = $scope + this.scope.pciTabs = (pciTabs) ? pciTabs : false this.urlTokenModel = $urlTokenModel this.timePicker = new TimePicker( '#timePicker', diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overview-gdpr.html b/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overview-gdpr.html index a6870b248..6e20bdba5 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overview-gdpr.html +++ b/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overview-gdpr.html @@ -26,13 +26,13 @@
- - + +
- GDPR Requirement: {{tab.rule}} + GDPR Requirement: {{tab.title}}
-
{{tab.description}}
+
{{tab.content}}
diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overviewGdprCtrl.js b/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overviewGdprCtrl.js index d7bcd0bb2..33c5a1379 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overviewGdprCtrl.js +++ b/SplunkAppForWazuh/appserver/static/js/controllers/overview/gdpr/overviewGdprCtrl.js @@ -20,7 +20,8 @@ define([ $scope, $currentDataService, $state, - $reportingService + $reportingService, + gdprTabs ) { this.scope = $scope this.state = $state @@ -28,6 +29,7 @@ define([ this.reportingService = $reportingService this.tableResults = {} this.filters = this.getFilters() + this.scope.gdprTabs = (gdprTabs) ? gdprTabs : false this.scope.$on('deletedFilter', () => { this.launchSearches() }) @@ -74,7 +76,7 @@ define([ 'groupsViz', `${ this.filters - } sourcetype=wazuh rule.gdpr{}="$gdpr$" | stats count by rule.groups`, + } sourcetype=wazuh rule.gdpr{}="$gdpr$" | stats count by rule.groups{}`, 'groupsViz', this.scope ), diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overview-pci.html b/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overview-pci.html index e9ad1c1d2..413f2cd38 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overview-pci.html +++ b/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overview-pci.html @@ -27,12 +27,12 @@
- +
- PCI-DSS Requirement: {{tab.rule}} + PCI-DSS Requirement: {{tab.title}}
-
{{tab.description}}
+
{{tab.content}}
diff --git a/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overviewPciCtrl.js b/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overviewPciCtrl.js index 09e497b69..637a7ec63 100644 --- a/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overviewPciCtrl.js +++ b/SplunkAppForWazuh/appserver/static/js/controllers/overview/pci/overviewPciCtrl.js @@ -31,10 +31,12 @@ define([ $scope, $currentDataService, $state, - $reportingService + $reportingService, + pciTabs ) { this.scope = $scope this.state = $state + this.scope.pciTabs = (pciTabs) ? pciTabs : false this.reportingService = $reportingService this.tableResults = {} this.getFilters = $currentDataService.getSerializedFilters diff --git a/SplunkAppForWazuh/bin/requirements/__init__.py b/SplunkAppForWazuh/bin/requirements/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/SplunkAppForWazuh/bin/requirements/gdpr_requirements.py b/SplunkAppForWazuh/bin/requirements/gdpr_requirements.py new file mode 100644 index 000000000..79ef24d31 --- /dev/null +++ b/SplunkAppForWazuh/bin/requirements/gdpr_requirements.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +Wazuh app - GDPR requirements module. + +Copyright (C) 2015-2019 Wazuh, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Find more information about this on the LICENSE file. +""" + +gdpr = { + 'II_5.1.f': + 'Ensure the ongoing confidentiality, integrity, availability and resilience of processing systems and services, verifying its modifications, accesses, locations and guarantee the safety of them.
File sharing protection and file sharing technologies that meet the requirements of data protection.', + 'III_14.2.c': ' Restrict the processing of personal data temporarily.', + 'III_17': ' Permanently erase personal information of a subject.', + 'IV_24.2': + 'Be able to demonstrate compliance with the GDPR by complying with data protection policies.', + 'IV_28': + ' Ensure data protection during processing, through technical and organizational measures.', + 'IV_30.1.g': + 'It is necessary to keep all processing activities documented, to carry out an inventory of data from beginning to end and an audit, in order to know all the places where personal and sensitive data are located, processed, stored or transmitted.', + 'IV_32.1.c': + 'Data Loss Prevention (DLP) capabilities to examine data flows and identify personal data that is not subject to adequate safeguards or authorizations. DLP tools can block or quarantine such data flows. Classify current data appropriately to determine specific categories of data that will be subject to the GDPR.', + 'IV_32.2': + 'Account management tools that closely monitor actions taken by standard administrators and users who use standard or privileged account credentials are required to control access to data. ', + 'IV_33': + ' Notify the supervisory authority of a violation of the data in 72 hours and in certain cases, the injured parties.', + 'IV_35.1': + 'Perform a data protection impact evaluation for high risk processes. Implement appropriate technical measures to safeguard the rights and freedoms of data subjects, informed by an assessment of the risks to these rights and freedoms.', + 'IV_35.7.d': + 'Capabilities for identification, blocking and forensic investigation of data breaches by malicious actors, through compromised credentials, unauthorized network access, persistent threats and verification of the correct operation of all components.
Network perimeter and endpoint security tools to prevent unauthorized access to the network, prevent the entry of unwanted data types and malicious threats. Anti-malware and anti-ransomware to prevent malware and ransomware threats from entering your devices.
A behavioral analysis that uses machine intelligence to identify people who do anomalous things on the network, in order to give early visibility and alert employees who start to become corrupt.' +} diff --git a/SplunkAppForWazuh/bin/requirements/pci_requirements.py b/SplunkAppForWazuh/bin/requirements/pci_requirements.py new file mode 100644 index 000000000..a72a03fdb --- /dev/null +++ b/SplunkAppForWazuh/bin/requirements/pci_requirements.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +""" +Wazuh app - GDPR requirements module. + +Copyright (C) 2015-2019 Wazuh, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Find more information about this on the LICENSE file. +""" + +pci = { + '1.1.1': + 'A formal process for approving and testing all network connections and changes to the firewall and router configurations', + '1.3.4': + 'Do not allow unauthorized outbound traffic from the cardholder data environment to the Internet.', + '1.4': + 'Install personal firewall software or equivalent functionality on any portable computing devices (including company and/or employee-owned) that connect to the Internet when outside the network (for example, laptops used by employees), and which are also used to access the CDE. Firewall (or equivalent) configurations include:
  • Specific configuration settings are defined.
  • Personal firewall (or equivalent functionality) is actively running.
  • Personal firewall (or equivalent functionality) is not alterable by users of the portable computing devices.
', + '2.2': + 'Develop configuration standards for all system components. Assure that these standards address all known security vulnerabilities and are consistent with industry accepted system hardening standards (CIS, ISO, SANS, NIST).', + '2.2.2': + 'Enable only necessary services, protocols, daemons, etc., as required for the function of the system. ', + '2.2.3': + 'Implement additional security features for any required services, protocols, or daemons that are considered to be insecure', + '2.2.4': 'Configure system security parameters to prevent misuse.', + '4.1': + 'Use strong cryptography and security protocols (for example, SSL/TLS, IPSEC, SSH, etc.) to safeguard sensitive cardholder data during transmission over open, public networks, including the following:
  • Only trusted keys and certificates are accepted.
  • The protocol in use only supports secure versions or configurations.
  • The encryption strength is appropriate for the encryption methodology in use
', + '5.1': + 'Deploy anti-virus software on all systems commonly affected by malicious software (particularly personal computers and servers).', + '5.2': + 'Ensure that all anti-virus mechanisms are maintained as follows:
  • Are kept current
  • Perform periodic scans
  • Generate audit logs which are retained per PCI DSS Requirement 10.7.
', + '6.2': + 'Ensure that all system components and software are protected from known vulnerabilities by installing applicable vendor-supplied security patches. Install critical security patches within one month of release.', + '6.5': + 'Address common coding vulnerabilities in software development processes as follows:
  • Train developers in secure coding techniques, including how to avoid common coding vulnerabilities, and understanding how sensitive data is handled in memory.
  • Develop applications based on secure coding guidelines
', + '6.5.1': + 'Injection flaws, particularly SQL injection. Also consider OS Command Injection, LDAP and XPath injection flaws as well as other injection flaws.', + '6.5.2': 'Buffer overflows', + '6.5.5': 'Improper error handling', + '6.5.7': 'Cross-site scripting (XSS)', + '6.5.8': + 'Improper access control (such an insecure direct object references, failure to restrict URL access, directory traversal, and failure to restrict user access to functions).', + '6.5.10': 'Broken authentication and session management.', + '6.6': + 'For public-facing web applications, address new threats and vulnerabilities on an ongoing basis and ensure these applications are protected against known attacks by either of the following methods:
  • Reviewing public-facing web applications via manual or automated application vulnerability security assessment tools or methods, at least annually and after any changes
  • Installing an automated technical solution that detects and prevents web-based attacks (for example, a web-application firewall) in front of public-facing web applications, to continually check all traffic.
', + '8.1.2': + 'Control addition, deletion, and modification of user IDs, credentials, and other identifier objects.', + '8.1.4': 'Remove/disable inactive user accounts within 90 days.', + '8.1.5': + 'Manage IDs used by third parties to access, support, or maintain system components via remote access as follows:
  • Enabled only during the time period needed and disabled when not in use.
  • Monitored when in use.
', + '8.1.6': + 'Limit repeated access attempts by locking out the user ID after not more than six attempts.', + '8.1.8': + 'If a session has been idle for more than 15 minutes, require the user to reauthenticate to re-activate the terminal or session.', + '8.2.4': 'Change user passwords/passphrases at least once every 90 days.', + '8.5.1': + 'Additional requirement for service providers: Service providers with remote access to customer premises (for example, for support of POS systems or servers) must use a unique authentication credential (such as a password/phrase) for each customer.', + '8.7': + 'All access to any database containing cardholder data (including access by applications, administrators, and all other users) is restricted as follows:
  • All user access to, user queries of, and user actions on databases are through programmatic methods.
  • Only database administrators have the ability to directly access or query databases.
  • Application IDs for database applications can only be used by the applications (and not by individual users or other non-application processes).
', + '10.1': + 'Implement audit trails to link all access to system components to each individual user.', + '10.2.1': 'All individual user accesses to cardholder data', + '10.2.2': + 'All actions taken by any individual with root or administrative privileges.', + '10.2.4': 'Invalid logical access attempts', + '10.2.5': + 'Use of and changes to identification and authentication mechanisms including but not limited to creation of new accounts and elevation of privileges and all changes, additions, or deletions to accounts with root or administrative privileges.', + '10.2.6': 'Initialization, stopping, or pausing of the audit logs', + '10.2.7': 'Creation and deletion of system level objects', + '10.5.2': 'Protect audit trail files from unauthorized modifications', + '10.5.5': + 'Use file integrity monitoring or change detection software on logs to ensure that existing log data cannot be changed without generating alerts (although new data being added should not cause an alert).', + '10.4': + 'Using time-synchronization technology, synchronize all critical system clocks and times and ensure that the following is implemented for acquiring, distributing, and storing time.', + '10.6': + 'Review logs and security events for all system components to identify anomalies or suspicious activity', + '10.6.1': + 'Review the following at least daily:
  • All security events
  • Logs of all system components that store, process, or transmit CHD and/or SAD, or that could
  • impact the security of CHD and/or SAD
  • Logs of all critical system components
  • Logs of all servers and system components that perform security functions (for example, firewalls, intrusion detection systems/intrusion prevention systems (IDS/IPS), authentication servers, ecommerce redirection servers, etc.)
', + '11.4': + 'Use intrusion detection and/or intrusion prevention techniques to detect and/or prevent intrusions into the network.
Monitor all traffic at the perimeter of the cardholder data environment as well as at critical points in the cardholder data environment, and alert personnel to suspected compromises. Keep all intrusion detection and prevention engines, baselines, and signatures up to date.', + '11.5': + 'Deploy a change detection mechanism (for example, file integrity monitoring tools) to alert personnel to unauthorizeumodification of critical system files, configuration files, or content files; and configure the software to perform critical file comparisons at least weekly.' +} \ No newline at end of file