Module: PWN::Redaction
- Defined in:
- lib/pwn/redaction.rb
Overview
Shared write-boundary redaction. Never opens a credential store.
Constant Summary collapse
- PATTERNS =
{ pem: /-----BEGIN [A-Z ]*PRIVATE KEY-----.*?(?:-----END [A-Z ]*PRIVATE KEY-----|\z)/m, authorization: /\b(?:Proxy-)?Authorization\s*[:=]\s*(?!\[REDACTED:)[^\r\n"'\\]+/i, jwt: /\beyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/, aws: /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/, bearer: %r{\bBearer\s+[A-Za-z0-9._~+/=-]+}i, api_key: /\b(?:sk|rk|xai|xox[baprs]|ghp|gho|ghu|ghs|ghr|glpat)[-_][A-Za-z0-9_-]{16,}/, password: /\b(?:password|passwd|api[_-]?key|access[_-]?token|refresh[_-]?token|secret)\s*[:=]\s*(?!\[REDACTED:)[^\s,"'}]+/i, cookie: /\bSet-Cookie:\s*(?!\[REDACTED:)[^\r\n]+/i }.freeze
- SECRET_FIELD =
/\A(?:password|passwd|secret|api[_-]?key|authorization|proxy-authorization|access[_-]?token|refresh[_-]?token|private[_-]?key|client[_-]?secret)\z/i
Class Method Summary collapse
Class Method Details
.authors ⇒ Object
50 51 52 |
# File 'lib/pwn/redaction.rb', line 50 public_class_method def self. "AUTHOR(S):\n 0day Inc. <[email protected]>\n" end |
.help ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/pwn/redaction.rb', line 54 public_class_method def self.help puts "USAGE: # Recursively redact secret patterns before persistence. #{self}.redact( value: 'required - string or nested JSON-compatible data' ) # Create a correlatable non-reversible replacement marker. #{self}.token( kind: 'required - secret type label', value: 'required - sensitive value to hash' ) # Print the author information. #{self}.authors " end |
.redact(opts = {}) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/pwn/redaction.rb', line 20 public_class_method def self.redact(opts = {}) value = opts[:value] case value when Hash value.to_h do |key, item| clean = if key.to_s.match?(SECRET_FIELD) && !item.nil? token(kind: key.to_s.downcase, value: item.to_s) else redact(value: item) end [key.is_a?(String) ? redact(value: key) : key, clean] end when Array then value.map { |item| redact(value: item) } when String PATTERNS.reduce(value.dup) do |text, (kind, regex)| text.split(/(\[REDACTED:[^:\]]+:[0-9a-f]{8}\])/).map do |part| part.start_with?('[REDACTED:') ? part : part.gsub(regex) { |match| token(kind: kind, value: match) } end.join end else value end end |
.token(opts = {}) ⇒ Object
43 44 45 46 47 48 |
# File 'lib/pwn/redaction.rb', line 43 public_class_method def self.token(opts = {}) value = opts[:value].to_s return value if value.match?(/\A\[REDACTED:[^:]+:[0-9a-f]{8}\]\z/) "[REDACTED:#{opts[:kind]}:#{Digest::SHA256.hexdigest(value)[0, 8]}]" end |