crypt_keeper 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
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
|