crypt_keeper 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0721f2abe4b641ef62278b76effaa56c2cb42cf7
|
4
|
+
data.tar.gz: b252fa5c0254f644721b50e5dbfbd4696bbe1fdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f84ddf6b8f31d846d3d154dddabaf1a34eb6c5093cf014c228ff61d43957ff8ab0baa9bb5c92fa8b4531a3a769586fb5b37b793e988ae0d1c9208d467bcdaee
|
7
|
+
data.tar.gz: cc33b4af5ae25d8e011767510c99004ad1dcf653c067a552d8661b684660b71afa07d7f8b87947da540e27d67b1a0e6f111539a63355d5d906814228eaf1a064
|
@@ -4,23 +4,43 @@ require 'active_support/lazy_load_hooks'
|
|
4
4
|
module CryptKeeper
|
5
5
|
module LogSubscriber
|
6
6
|
module PostgresPgp
|
7
|
+
FILTER = /(\(*)pgp_(sym|pub)_(?<operation>decrypt|encrypt)(\(+.*\)+)/im
|
8
|
+
|
7
9
|
# Public: Prevents sensitive data from being logged
|
8
10
|
#
|
9
11
|
# event - An ActiveSupport::Notifications::Event
|
10
12
|
#
|
11
13
|
# Returns a boolean.
|
12
14
|
def sql(event)
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
payload = crypt_keeper_payload_parse(event.payload[:sql])
|
16
|
+
|
17
|
+
return if CryptKeeper.silence_logs? && payload =~ FILTER
|
16
18
|
|
17
|
-
|
19
|
+
event.payload[:sql] = crypt_keeper_filter_postgres_log(payload)
|
20
|
+
super(event)
|
21
|
+
end
|
18
22
|
|
19
|
-
|
23
|
+
private
|
24
|
+
|
25
|
+
# Private: Parses the payload to UTF.
|
26
|
+
#
|
27
|
+
# payload - the payload string
|
28
|
+
#
|
29
|
+
# Returns a string.
|
30
|
+
def crypt_keeper_payload_parse(payload)
|
31
|
+
payload.encode('UTF-8', 'binary',
|
32
|
+
invalid: :replace, undef: :replace, replace: '')
|
33
|
+
end
|
34
|
+
|
35
|
+
# Private: Filters the payload.
|
36
|
+
#
|
37
|
+
# payload - the payload string
|
38
|
+
#
|
39
|
+
# Returns a string.
|
40
|
+
def crypt_keeper_filter_postgres_log(payload)
|
41
|
+
payload.gsub(FILTER) do |_|
|
20
42
|
"#{$~[:operation]}([FILTERED])"
|
21
43
|
end
|
22
|
-
|
23
|
-
super(event)
|
24
44
|
end
|
25
45
|
end
|
26
46
|
end
|
@@ -4,6 +4,7 @@ module CryptKeeper
|
|
4
4
|
module Provider
|
5
5
|
class PostgresPgp < Base
|
6
6
|
include CryptKeeper::Helper::SQL
|
7
|
+
include CryptKeeper::LogSubscriber::PostgresPgp
|
7
8
|
|
8
9
|
attr_accessor :key
|
9
10
|
attr_accessor :pgcrypto_options
|
@@ -25,18 +26,37 @@ module CryptKeeper
|
|
25
26
|
#
|
26
27
|
# Returns an encrypted string
|
27
28
|
def encrypt(value)
|
28
|
-
|
29
|
+
rescue_invalid_statement do
|
30
|
+
escape_and_execute_sql(["SELECT pgp_sym_encrypt(?, ?, ?)",
|
31
|
+
value.to_s, key, pgcrypto_options])['pgp_sym_encrypt']
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
# Public: Decrypts a string
|
32
36
|
#
|
33
37
|
# Returns a plaintext string
|
34
38
|
def decrypt(value)
|
35
|
-
|
39
|
+
rescue_invalid_statement do
|
40
|
+
escape_and_execute_sql(["SELECT pgp_sym_decrypt(?, ?)",
|
41
|
+
value, key])['pgp_sym_decrypt']
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
45
|
def search(records, field, criteria)
|
39
|
-
records.where("(pgp_sym_decrypt(cast(\"#{field}\" AS bytea), ?) = ?)",
|
46
|
+
records.where("(pgp_sym_decrypt(cast(\"#{field}\" AS bytea), ?) = ?)",
|
47
|
+
key, criteria)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Private: Rescues and filters invalid statement errors. Run the code
|
53
|
+
# within a block for it to be rescued.
|
54
|
+
def rescue_invalid_statement
|
55
|
+
yield
|
56
|
+
rescue ActiveRecord::StatementInvalid => e
|
57
|
+
message = crypt_keeper_payload_parse(e.message)
|
58
|
+
message = crypt_keeper_filter_postgres_log(message)
|
59
|
+
raise ActiveRecord::StatementInvalid, message
|
40
60
|
end
|
41
61
|
end
|
42
62
|
end
|
data/lib/crypt_keeper/version.rb
CHANGED
@@ -28,11 +28,31 @@ describe CryptKeeper::Provider::PostgresPgp do
|
|
28
28
|
specify { expect(subject.encrypt(integer_plain_text)).to_not eq(integer_plain_text) }
|
29
29
|
specify { expect(subject.encrypt(integer_plain_text)).to_not be_empty }
|
30
30
|
end
|
31
|
+
|
32
|
+
it "filters StatementInvalid errors" do
|
33
|
+
subject.pgcrypto_options = "invalid"
|
34
|
+
|
35
|
+
begin
|
36
|
+
subject.encrypt(plain_text)
|
37
|
+
rescue ActiveRecord::StatementInvalid => e
|
38
|
+
expect(e.message).to_not include("invalid")
|
39
|
+
expect(e.message).to_not include(ENCRYPTION_PASSWORD)
|
40
|
+
end
|
41
|
+
end
|
31
42
|
end
|
32
43
|
|
33
44
|
describe "#decrypt" do
|
34
45
|
specify { expect(subject.decrypt(cipher_text)).to eq(plain_text) }
|
35
46
|
specify { expect(subject.decrypt(integer_cipher_text)).to eq(integer_plain_text.to_s) }
|
47
|
+
|
48
|
+
it "filters StatementInvalid errors" do
|
49
|
+
begin
|
50
|
+
subject.decrypt("invalid")
|
51
|
+
rescue ActiveRecord::StatementInvalid => e
|
52
|
+
expect(e.message).to_not include("invalid")
|
53
|
+
expect(e.message).to_not include(ENCRYPTION_PASSWORD)
|
54
|
+
end
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
58
|
describe "#search" do
|