Signed-off-by: Adam M Dutko <adutko@chef.io>
This commit is contained in:
Adam M Dutko 2020-08-11 10:34:13 -04:00
parent 679ddd1ee8
commit 04c3aef004
4 changed files with 27 additions and 15 deletions

View file

@ -24,18 +24,19 @@ This resource first became available in v1.0.0 of InSpec.
A `postgres_session` resource block declares the username and password to use for the session, and then the command to be run: A `postgres_session` resource block declares the username and password to use for the session, and then the command to be run:
# Create a PostgreSQL session: # Create a PostgreSQL session:
sql = postgres_session('username', 'password', 'host') sql = postgres_session('username', 'password', 'host', 'port')
# default values: # default values:
# username: 'postgres' # username: 'postgres'
# host: 'localhost' # host: 'localhost'
# port: 5432
# Run an SQL query with an optional database to execute # Run an SQL query with an optional database to execute
sql.query('sql_query', ['database_name'])` sql.query('sql_query', ['database_name'])`
A full example is: A full example is:
sql = postgres_session('username', 'password', 'host') sql = postgres_session('username', 'password', 'host', 'port')
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
its('output') { should eq '' } its('output') { should eq '' }
end end
@ -50,7 +51,7 @@ The following examples show how to use this Chef InSpec audit resource.
### Test the PostgreSQL shadow password ### Test the PostgreSQL shadow password
sql = postgres_session('my_user', 'password', '192.168.1.2') sql = postgres_session('my_user', 'password', '192.168.1.2', 5432)
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;', ['testdb']) do describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;', ['testdb']) do
its('output') { should eq('') } its('output') { should eq('') }

View file

@ -26,12 +26,13 @@ module Inspec::Resources
supports platform: "windows" supports platform: "windows"
desc "Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database." desc "Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database."
example <<~EXAMPLE example <<~EXAMPLE
sql = postgres_session('username', 'password', 'host') sql = postgres_session('username', 'password', 'host', 'port')
query('sql_query', ['database_name'])` contains the query and (optional) database to execute query('sql_query', ['database_name'])` contains the query and (optional) database to execute
# default values: # default values:
# username: 'postgres' # username: 'postgres'
# host: 'localhost' # host: 'localhost'
# port: 5432
# db: databse == db_user running the sql query # db: databse == db_user running the sql query
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
@ -39,10 +40,11 @@ module Inspec::Resources
end end
EXAMPLE EXAMPLE
def initialize(user, pass, host = nil) def initialize(user, pass, host = nil, port = nil)
@user = user || "postgres" @user = user || "postgres"
@pass = pass @pass = pass
@host = host || "localhost" @host = host || "localhost"
@port = port || 5432
end end
def query(query, db = []) def query(query, db = [])
@ -64,7 +66,7 @@ module Inspec::Resources
def create_psql_cmd(query, db = []) def create_psql_cmd(query, db = [])
dbs = db.map { |x| "-d #{x}" }.join(" ") dbs = db.map { |x| "-d #{x}" }.join(" ")
"PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}" "PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -p #{@port} -A -t -c #{escaped_query(query)}"
end end
end end
end end

View file

@ -5,19 +5,27 @@ require "inspec/resources/command"
describe "Inspec::Resources::PostgresSession" do describe "Inspec::Resources::PostgresSession" do
it "verify postgres_session create_psql_cmd with a basic query" do it "verify postgres_session create_psql_cmd with a basic query" do
resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1") resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1", 5432)
_(resource.send(:create_psql_cmd, "SELECT * FROM STUDENTS;", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;" _(resource.send(:create_psql_cmd, "SELECT * FROM STUDENTS;", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -p 5432 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;"
end end
it "verify postgres_session escaped_query with a complex query" do it "verify postgres_session escaped_query with a complex query" do
resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1") resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1", 5432)
_(resource.send(:create_psql_cmd, "SELECT current_setting('client_min_messages')", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c SELECT\\ current_setting\\(\\'client_min_messages\\'\\)" _(resource.send(:create_psql_cmd, "SELECT current_setting('client_min_messages')", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -p 5432 -A -t -c SELECT\\ current_setting\\(\\'client_min_messages\\'\\)"
end end
it "verify postgres_session redacts output" do it "verify postgres_session redacts output" do
cmd = %q{PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c "SELECT current_setting('client_min_messages')"} cmd = %q{PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -p 5432 -A -t -c "SELECT current_setting('client_min_messages')"}
options = { redact_regex: /(PGPASSWORD=').+(' psql .*)/ } options = { redact_regex: /(PGPASSWORD=').+(' psql .*)/ }
resource = load_resource("command", cmd, options) resource = load_resource("command", cmd, options)
expected_to_s = %q{Command: `PGPASSWORD='REDACTED' psql -U myuser -d testdb -h 127.0.0.1 -A -t -c "SELECT current_setting('client_min_messages')"`} expected_to_s = %q{Command: `PGPASSWORD='REDACTED' psql -U myuser -d testdb -h 127.0.0.1 -p 5432 -A -t -c "SELECT current_setting('client_min_messages')"`}
_(resource.to_s).must_equal(expected_to_s) _(resource.to_s).must_equal(expected_to_s)
end end
it "verify postgres_session works with empty port value" do
resource = load_resource("postgres_session", "myuser", "mypass", "127.0.0.1")
_(resource.send(:create_psql_cmd, "SELECT * FROM STUDENTS;", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h 127.0.0.1 -p 5432 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;"
end
it "verify postgres_session works with empty host and port value" do
resource = load_resource("postgres_session", "myuser", "mypass")
_(resource.send(:create_psql_cmd, "SELECT * FROM STUDENTS;", ["testdb"])).must_equal "PGPASSWORD='mypass' psql -U myuser -d testdb -h localhost -p 5432 -A -t -c SELECT\\ \\*\\ FROM\\ STUDENTS\\;"
end
end end

View file

@ -29,18 +29,19 @@ This resource first became available in v1.0.0 of InSpec.
A `postgres_session` resource block declares the username and password to use for the session, and then the command to be run: A `postgres_session` resource block declares the username and password to use for the session, and then the command to be run:
# Create a PostgreSQL session: # Create a PostgreSQL session:
sql = postgres_session('username', 'password', 'host') sql = postgres_session('username', 'password', 'host', 'port')
# default values: # default values:
# username: 'postgres' # username: 'postgres'
# host: 'localhost' # host: 'localhost'
# port: 5432
# Run an SQL query with an optional database to execute # Run an SQL query with an optional database to execute
sql.query('sql_query', ['database_name'])` sql.query('sql_query', ['database_name'])`
A full example is: A full example is:
sql = postgres_session('username', 'password', 'host') sql = postgres_session('username', 'password', 'host', 'port')
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
its('output') { should eq '' } its('output') { should eq '' }
end end
@ -53,7 +54,7 @@ The following examples show how to use this Chef InSpec audit resource.
### Test the PostgreSQL shadow password ### Test the PostgreSQL shadow password
sql = postgres_session('my_user', 'password', '192.168.1.2') sql = postgres_session('my_user', 'password', '192.168.1.2', 5432)
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;', ['testdb']) do describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;', ['testdb']) do
its('output') { should eq('') } its('output') { should eq('') }