V-72913

Severity: Medium

Generated

2019-05-20 15:48:11.984914

Status

Passed

PostgreSQL must produce audit records of its enforcement of access restrictions associated with changes to the configuration of PostgreSQL or database(s).

NIST 800-53

STIG # Description Result
CM-5 CM-5: Access Restrictions For Change passed

Guidance

Without auditing the enforcement of access restrictions against changes to configuration, it would be difficult to identify attempted attacks and an audit trail would not be available for forensic investigation for after-the-fact actions. Enforcement actions are the methods or mechanisms used to prevent unauthorized changes to configuration settings. Enforcement action methods may be as simple as denying access to a file based on the application of file permissions (access restriction). Audit items may consist of lists of actions blocked by access restrictions or changes identified after the fact.

Check

Note: The following instructions use the PGDATA environment variable. See supplementary content APPENDIX-F for instructions on configuring PGDATA. To verify that system denies are logged when unprivileged users attempt to change database configuration, as the database administrator (shown here as “postgres”), run the following commands: $ sudo su - postgres $ psql Next, create a role with no privileges, change the current role to that user and attempt to change a configuration by running the following SQL: CREATE ROLE bob; SET ROLE bob; SET pgaudit.role=‘test’; Now check pg_log (use the latest log): $ cat ${PGDATA?}/pg_log/postgresql-Thu.log < 2016-01-28 17:57:34.092 UTC bob postgres: >ERROR: permission denied to set parameter “pgaudit.role” < 2016-01-28 17:57:34.092 UTC bob postgres: >STATEMENT: SET pgaudit.role=‘test’; If the denial is not logged, this is a finding. By default PostgreSQL configuration files are owned by the postgres user and cannot be edited by non-privileged users: $ ls -la ${PGDATA?} | grep postgresql.conf -rw——-. 1 postgres postgres 21758 Jan 22 10:27 postgresql.conf If postgresql.conf is not owned by the database owner and does not have read and write permissions for the owner, this is a finding.

Fix

Enable logging. All denials are logged by default if logging is enabled. To ensure that logging is enabled, review supplementary content APPENDIX-C for instructions on enabling logging.

Test Results

  Result
Command: `sed -nre '/2019-05-16 08:11.*LOG:\s+starting tests for V-72913/,$p' /var/vcap/sys/log/postgresql/Thu.pg_log` stdout should match /ERROR:\s+permission denied to set parameter "pgaudit.role"/ passed
Command: `sed -nre '/2019-05-16 08:11.*LOG:\s+starting tests for V-72913/,$p' /var/vcap/sys/log/postgresql/Thu.pg_log` stdout should match /STATEMENT:\s+SET ROLE inspec_v72913_role; SET pgaudit.role='test';/ passed
File /var/vcap/store/postgresql/data/postgresql.conf should be file passed
File /var/vcap/store/postgresql/data/postgresql.conf should be owned by "vcap" passed
File /var/vcap/store/postgresql/data/postgresql.conf mode should cmp == "0600" passed

Code

control "V-72913" do
  title "PostgreSQL must produce audit records of its enforcement of access
  restrictions associated with changes to the configuration of PostgreSQL or
  database(s)."
  desc  "Without auditing the enforcement of access restrictions against changes
  to configuration, it would be difficult to identify attempted attacks and an
  audit trail would not be available for forensic investigation for
  after-the-fact actions.
  Enforcement actions are the methods or mechanisms used to prevent unauthorized
  changes to configuration settings. Enforcement action methods may be as simple
  as denying access to a file based on the application of file permissions
  (access restriction). Audit items may consist of lists of actions blocked by
  access restrictions or changes identified after the fact."
  impact 0.5
  tag "severity": "medium"
  tag "gtitle": "SRG-APP-000381-DB-000361"
  tag "gid": "V-72913"
  tag "rid": "SV-87565r1_rule"
  tag "stig_id": "PGS9-00-004100"
  tag "cci": "CCI-001814"
  tag "nist": ["CM-5 (1)", "Rev_4"]
  tag "check": "Note: The following instructions use the PGDATA environment
  variable. See supplementary content APPENDIX-F for instructions on configuring
  PGDATA.
  To verify that system denies are logged when unprivileged users attempt to
  change database configuration, as the database administrator (shown here as
  \"postgres\"), run the following commands:
  $ sudo su - postgres
  $ psql
  Next, create a role with no privileges, change the current role to that user
  and attempt to change a configuration by running the following SQL:
  CREATE ROLE bob;
  SET ROLE bob;
  SET pgaudit.role='test';
  Now check pg_log (use the latest log):
  $ cat ${PGDATA?}/pg_log/postgresql-Thu.log
  < 2016-01-28 17:57:34.092 UTC bob postgres: >ERROR: permission denied to set
  parameter \"pgaudit.role\"
  < 2016-01-28 17:57:34.092 UTC bob postgres: >STATEMENT: SET pgaudit.role='test';
  If the denial is not logged, this is a finding.
  By default PostgreSQL configuration files are owned by the postgres user and
  cannot be edited by non-privileged users:
  $ ls -la ${PGDATA?} | grep postgresql.conf
  -rw-------. 1 postgres postgres 21758 Jan 22 10:27 postgresql.conf
  If postgresql.conf is not owned by the database owner and does not have read
  and write permissions for the owner, this is a finding."
  tag "fix": "Enable logging.
  All denials are logged by default if logging is enabled. To ensure that
  logging is enabled, review supplementary content APPENDIX-C for instructions
  on enabling logging."

  sql = postgres_session(PG_DBA, PG_DBA_PASSWORD, PG_HOST)
  log_directory_query = sql.query('SHOW log_directory;', [PG_DB])
  log_directory = log_directory_query.output
  current_log_command = "ls -1t #{log_directory}/*.pg_log | head -1"
  current_log = command(current_log_command).stdout.strip
  control = File.basename(__FILE__, File.extname(__FILE__))
  message = "starting tests for #{control}"
  message_sql = "DO language plpgsql $$ BEGIN "\
    "RAISE LOG '#{message}'; END $$;"
  start = Time.now.strftime('%Y-%m-%d %H:%M')
  get_logs = "sed -nre '/#{start}.*LOG:\\s+#{message}/,$p' #{current_log}"

  create_role = 'CREATE ROLE bob;'
  set_role = 'SET ROLE bob;'
  set_pgaudit_role = "SET pgaudit.role='test';"
  drop_role = 'DROP ROLE bob;'
  command = "#{set_role} #{set_pgaudit_role}"
  error = 'permission denied to set parameter "pgaudit.role"'

  sql.query(message_sql, [PG_DB])
  sql.query(create_role, [PG_DB])
  sql.query(command, [PG_DB])
  sql.query(drop_role, [PG_DB])

  describe command(get_logs) do
    its('stdout') { should match /ERROR:\s+#{error}/ }
    its('stdout') { should match /STATEMENT:\s+#{command}/ }
  end

  describe file(PG_CONF) do
    it { should be_file }
    it { should be_owned_by PG_OWNER }
    its('mode') { should cmp '0600' }
  end
end