V-73039

Severity: Medium

Generated

2019-05-20 15:48:11.984914

Status

Passed

PostgreSQL must protect its audit features from unauthorized access.

NIST 800-53

STIG # Description Result
AU-9 AU-9: Protection Of Audit Information passed

Guidance

Protecting audit data also includes identifying and protecting the tools used to view and manipulate log data.

Depending upon the log format and application, system and application log tools may provide the only means to manipulate and manage application and system log data. It is, therefore, imperative that access to audit tools be controlled and protected from unauthorized access.

Applications providing tools to interface with audit data will leverage user permissions and roles identifying the user accessing the tools and the corresponding rights the user enjoys in order make access decisions regarding the access to audit tools.

Audit tools include, but are not limited to, OS-provided audit tools, vendor-provided audit tools, and open source audit tools needed to successfully view and manipulate audit information system activity and records.

If an attacker were to gain access to audit tools, he could analyze audit logs for system weaknesses or weaknesses in the auditing itself. An attacker could also manipulate logs to hide evidence of malicious activity.

Check

Note: The following instructions use the PGDATA environment variable. See supplementary content APPENDIX-F for instructions on configuring PGDATA. Only the database owner and superuser can alter configuration of PostgreSQL.

Make sure the pg_log directory are owned by postgres user and group:

$ sudo su - postgres $ ls -la ${PGDATA?}/pg_log

If pg_log is not owned by the database owner, this is a finding.

Make sure the data directory are owned by postgres user and group.

$ sudo su - postgres $ ls -la ${PGDATA?}

If PGDATA is not owned by the database owner, this is a finding.

Make sure pgaudit installation is owned by root:

$ sudo su - postgres $ ls -la /usr/pgsql-9.5/share/contrib/pgaudit

If pgaudit installation is not owned by root, this is a finding.

Next, as the database administrator (shown here as “postgres”), run the following SQL to list all roles and their privileges:

$ sudo su - postgres $ psql -x -c “\du”

If any role has “superuser” that should not, this is a finding.

Fix

Note: The following instructions use the PGDATA environment variable. See supplementary content APPENDIX-F for instructions on configuring PGDATA.

If pg_log or data directory are not owned by postgres user and group, configure them as follows:

$ sudo chown -R postgres:postgres ${PGDATA?}

If the pgaudit installation is not owned by root user and group, configure it as follows:

$ sudo chown -R root:root /usr/pgsql-9.5/share/contrib/pgaudit.

To remove superuser from a role, as the database administrator (shown here as “postgres”), run the following SQL:

$ sudo su - postgres $ psql -c “ALTER ROLE WITH NOSUPERUSER”

Test Results

  Result
Directory /var/vcap/sys/log/postgresql should be directory passed
Directory /var/vcap/sys/log/postgresql should be owned by "vcap" passed
Directory /var/vcap/sys/log/postgresql should be grouped into "vcap" passed
Directory /var/vcap/store/postgresql/data should be directory passed
Directory /var/vcap/store/postgresql/data should be owned by "vcap" passed
Directory /var/vcap/store/postgresql/data should be grouped into "vcap" passed
Command: `find /usr/lib/postgresql/10/bin /usr/lib/postgresql/10/lib /usr/include/postgresql/10 /usr/share/postgresql/10 -type f -iname '*pgaudit*' ! -user root` stdout should eq "" passed
Command: `find /usr/lib/postgresql/10/bin /usr/lib/postgresql/10/lib /usr/include/postgresql/10 /usr/share/postgresql/10 -type f -iname '*pgaudit*' ! -user root` exit_status should cmp == 0 passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'pg_monitor'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'pg_read_all_settings'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'pg_read_all_stats'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'pg_stat_scan_tables'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'pg_signal_backend'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'dashboard'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'replication'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'haproxy'; output should not eq "t" passed
PostgreSQL query: SELECT r.rolsuper FROM pg_catalog.pg_roles r WHERE r.rolname = 'testuser'; output should not eq "t" passed

Code

control "V-73039" do
  title "PostgreSQL must protect its audit features from unauthorized access."
  desc  "Protecting audit data also includes identifying and protecting the tools
used to view and manipulate log data.

Depending upon the log format and application, system and application log tools may
provide the only means to manipulate and manage application and system log data. It
is, therefore, imperative that access to audit tools be controlled and protected
from unauthorized access.

Applications providing tools to interface with audit data will leverage user
permissions and roles identifying the user accessing the tools and the corresponding
rights the user enjoys in order make access decisions regarding the access to audit
tools.

Audit tools include, but are not limited to, OS-provided audit tools,
vendor-provided audit tools, and open source audit tools needed to successfully view
and manipulate audit information system activity and records.

If an attacker were to gain access to audit tools, he could analyze audit logs for
system weaknesses or weaknesses in the auditing itself. An attacker could also
manipulate logs to hide evidence of malicious activity."
  impact 0.5
  tag "severity": "medium"
  tag "gtitle": "SRG-APP-000121-DB-000202"
  tag "gid": "V-73039"
  tag "rid": "SV-87691r1_rule"
  tag "stig_id": "PGS9-00-010700"
  tag "cci": "CCI-001493"
  tag "nist": ["AU-9", "Rev_4"]
  tag "check": "Note: The following instructions use the PGDATA environment
variable. See supplementary content APPENDIX-F for instructions on configuring
PGDATA. Only the database owner and superuser can alter configuration of PostgreSQL.

Make sure the pg_log directory are owned by postgres user and group:

$ sudo su - postgres
$ ls -la ${PGDATA?}/pg_log

If pg_log is not owned by the database owner, this is a finding.

Make sure the data directory are owned by postgres user and group.

$ sudo su - postgres
$ ls -la ${PGDATA?}

If PGDATA is not owned by the database owner, this is a finding.

Make sure pgaudit installation is owned by root:

$ sudo su - postgres
$ ls -la /usr/pgsql-9.5/share/contrib/pgaudit

If pgaudit installation is not owned by root, this is a finding.

Next, as the database administrator (shown here as \"postgres\"), run the following
SQL to list all roles and their privileges:

$ sudo su - postgres
$ psql -x -c \"\\du\"

If any role has \"superuser\" that should not, this is a finding."
  tag "fix": "Note: The following instructions use the PGDATA environment variable.
See supplementary content APPENDIX-F for instructions on configuring PGDATA.

If pg_log or data directory are not owned by postgres user and group, configure them
as follows:

$ sudo chown -R postgres:postgres ${PGDATA?}

If the pgaudit installation is not owned by root user and group, configure it as
follows:

$ sudo chown -R root:root /usr/pgsql-9.5/share/contrib/pgaudit.

To remove superuser from a role, as the database administrator (shown here as
\"postgres\"), run the following SQL:

$ sudo su - postgres
$ psql -c \"ALTER ROLE <role-name> WITH NOSUPERUSER\""

  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

  describe directory(log_directory) do
    it { should be_directory }
    it { should be_owned_by PG_OWNER }
    it { should be_grouped_into PG_GROUP }
  end

  describe directory(PG_DATA) do
    it { should be_directory }
    it { should be_owned_by PG_OWNER }
    it { should be_grouped_into PG_GROUP }
  end

  find_insecure_files = "find #{PG_SHARED_LIBS.join(' ')} -type f "\
    "-iname '*pgaudit*' ! -user root"

  describe command(find_insecure_files) do
    its('stdout') { should eq '' }
    its('exit_status') { should cmp 0 }
  end

  roles_sql = 'SELECT r.rolname FROM pg_catalog.pg_roles r;'
  roles_query = sql.query(roles_sql, [PG_DB])
  roles = roles_query.lines

  roles.each do |role|
    unless PG_SUPERUSERS.include?(role)
      superuser_sql = "SELECT r.rolsuper FROM pg_catalog.pg_roles r "\
        "WHERE r.rolname = '#{role}';"

      describe sql.query(superuser_sql, [PG_DB]) do
        its('output') { should_not eq 't' }
      end
    end
  end
end