Class: Contrast::Utils::HashDigest
- Includes:
- Digest::Instance
- Defined in:
- lib/contrast/utils/hash_digest.rb
Overview
We use this class to provide hashes for our Request and Finding objects based upon our definitions of uniqueness. While the uniqueness of the request object is something internal to the Ruby agent, the uniqueness of the Finding hash is defined by a specification shared across all agent teams. The spec can be found here: bitbucket.org/contrastsecurity/assess-specifications/src/master/vulnerability/preflight.md
Constant Summary collapse
- CONTENT_LENGTH_HEADER =
'Content-Length'- CRYPTO_RULES =
%w[ crypto-bad-ciphers crypto-bad-mac ].cs__freeze
- CONFIG_PATH_KEY =
'path'- CONFIG_SESSION_ID_KEY =
'sessionId'- CLASS_SOURCE_KEY =
'source'- CLASS_CONSTANT_NAME_KEY =
'name'- CLASS_LINE_NO_KEY =
'lineNo'- CHARS =
%w[a b c d e f g].cs__freeze
Class Method Summary collapse
- .generate_class_scanning_hash(finding) ⇒ Object
- .generate_config_hash(finding) ⇒ Object
- .generate_event_hash(finding, source) ⇒ Object
- .generate_request_hash(request) ⇒ Object
Instance Method Summary collapse
- #finish ⇒ Object
-
#initialize ⇒ HashDigest
constructor
A new instance of HashDigest.
- #update(str) ⇒ Object
-
#update_on_content_length(chr) ⇒ Object
This method converts and integer value for length into a string value that we can hash on, based on the logarithmic value of the length, and updates the current hash with that value.
- #update_on_request ⇒ Object
- #update_on_sources(events) ⇒ Object
Constructor Details
#initialize ⇒ HashDigest
Returns a new instance of HashDigest.
133 134 135 136 |
# File 'lib/contrast/utils/hash_digest.rb', line 133 def initialize super @crc32 = 0 end |
Class Method Details
.generate_class_scanning_hash(finding) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/contrast/utils/hash_digest.rb', line 59 def generate_class_scanning_hash finding hash = new hash.update(finding.rule_id) module_name = finding.properties[CLASS_SOURCE_KEY] hash.update(module_name) # We're not currently collecting this. 30/7/19 HM line_no = finding.properties[CLASS_LINE_NO_KEY] hash.update(line_no) field = finding.properties[CLASS_CONSTANT_NAME_KEY] hash.update(field) hash.finish end |
.generate_config_hash(finding) ⇒ Object
49 50 51 52 53 54 55 56 57 |
# File 'lib/contrast/utils/hash_digest.rb', line 49 def generate_config_hash finding hash = new hash.update(finding.rule_id) path = finding.properties[CONFIG_PATH_KEY] hash.update(path) method = finding.properties[CONFIG_SESSION_ID_KEY] hash.update(method) hash.finish end |
.generate_event_hash(finding, source) ⇒ Object
40 41 42 43 44 45 46 47 |
# File 'lib/contrast/utils/hash_digest.rb', line 40 def generate_event_hash finding, source return generate_dataflow_hash(finding) if finding.events.length.to_i > 1 id = finding.rule_id return generate_crypto_hash(finding, source) if CRYPTO_RULES.include?(id) generate_trigger_hash(finding) end |
.generate_request_hash(request) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/contrast/utils/hash_digest.rb', line 28 def generate_request_hash request hash = new hash.update(request.request_method) hash.update(request.normalized_uri) request.parameters.each_key do |name| hash.update(name) end cl = request.headers[CONTENT_LENGTH_HEADER] hash.update_on_content_length(cl) if cl hash.finish end |
Instance Method Details
#finish ⇒ Object
144 145 146 |
# File 'lib/contrast/utils/hash_digest.rb', line 144 def finish @crc32.to_s end |
#update(str) ⇒ Object
138 139 140 141 142 |
# File 'lib/contrast/utils/hash_digest.rb', line 138 def update str return unless str @crc32 = Zlib.crc32(str, @crc32) end |
#update_on_content_length(chr) ⇒ Object
This method converts and integer value for length into a string value that we can hash on, based on the logarithmic value of the length, and updates the current hash with that value.
129 130 131 |
# File 'lib/contrast/utils/hash_digest.rb', line 129 def update_on_content_length chr update(CHARS[Math.log10(chr.to_s.length).to_i] || CHARS[-1]) end |
#update_on_request ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/contrast/utils/hash_digest.rb', line 98 def update_on_request context = Contrast::Agent::REQUEST_TRACKER.current return unless context route = context.route request = context.request if route update(route.route) update(route.verb) elsif request update(request.normalized_uri) update(request.request_method) end end |
#update_on_sources(events) ⇒ Object
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/contrast/utils/hash_digest.rb', line 113 def update_on_sources events return unless events&.any? events.each do |event| event.event_sources.each do |source| update(source.type) update(source.name) end end end |