gitlab-secret_detection 0.13.0 → 0.14.0

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
  SHA256:
3
- metadata.gz: f72d7d8262749305fdf1811df74637af4f7ba4bbf693fc41d2cdb34d1ca25238
4
- data.tar.gz: 6896b4eb32dc734640c0dc125dd75e79b765f27aa618f73fec81c83c0c20df93
3
+ metadata.gz: b011db6024a9386ec45e091c678b4b4ea43986065f846748f9b646caf2232c86
4
+ data.tar.gz: 9faabaf1da62a2470bc8c569a766f48867b0b59c701076b0c8e3d4fbd6ac7550
5
5
  SHA512:
6
- metadata.gz: 2d35dfa136b9524f851a6ed20885aa6d50b9334f12166fd9d131ff523ed38bed1264bad953fd6fa58e63fe2c5f9c62be129d3be231258eef25990803b9b67d4e
7
- data.tar.gz: 331a74ba7a779f275717c769c0f63785d7e74d25b07da5d07f44c08a1a0c7f343eec3ba7fd8285d549d298fac4d93bdc3f2bc122ea7cb30bd567e4c75e43efdb
6
+ metadata.gz: 7bfb7fcda514e6e5baf4d4aac12208629f9034ffea475d815f95644abf385e3d4983d8640524dd297021e5a441b5b9fd0189b26c2aa8db8e0c38f42d59a0e7fd
7
+ data.tar.gz: 188e1ceb321ed6b92535b704dc962d37d2f4aec6c67ecbddb64316d7ec2503f29975ef416fca3b792613a5a2be1c74fa7175c0f161122e0d5e485423ea4ea7c7
@@ -8,7 +8,9 @@ module Gitlab
8
8
  # +status+:: One of values from Gitlab::SecretDetection::Core::Status indicating the scan operation's status
9
9
  # +results+:: Array of Gitlab::SecretDetection::Core::Finding values. Default value is nil.
10
10
  # to embed more information on error.
11
- # +applied_exclusions+:: Array of Exclusions that were applied during this scan.
11
+ # +applied_exclusions+:: Array of exclusions that were applied during this scan.
12
+ # These can be either GRPC::Exclusions when used as a service, or `Security::ProjectSecurityExclusion
13
+ # object when used as a gem.
12
14
  # +metadata+:: Hash object containing additional meta information about the response. It is currently used
13
15
  class Response
14
16
  attr_reader :status, :results, :applied_exclusions, :metadata
@@ -32,7 +32,7 @@ module Gitlab
32
32
  rules_data[:rules].freeze
33
33
  rescue StandardError => e
34
34
  logger.error "Failed to parse secret detection ruleset from '#{path}' path: #{e}"
35
- raise Core::Scanner::RulesetParseError
35
+ raise Core::Scanner::RulesetParseError, e
36
36
  end
37
37
  end
38
38
  end
@@ -59,10 +59,13 @@ module Gitlab
59
59
  # +timeout+:: No of seconds(accepts floating point for smaller time values) to limit the total scan duration
60
60
  # +payload_timeout+:: No of seconds(accepts floating point for smaller time values) to limit
61
61
  # the scan duration on each payload
62
- # +raw_value_exclusions:+:: Array of raw values to exclude from the scan.
63
- # +rule_exclusions+:: Array of rules to exclude from the ruleset used for the scan. Each rule is represented
64
- # by its ID. For example: `gitlab_personal_access_token` for representing Gitlab Personal Access
65
- # Token. By default, no rule is excluded from the ruleset.
62
+ # +exclusions+:: Hash with keys: :raw_value, :rule and values of arrays of either
63
+ # GRPC::Exclusion objects (when used as a standalone service)
64
+ # or Security::ProjectSecurityExclusion objects (when used as gem).
65
+ # :raw_value - Exclusions in the :raw array are the raw values to ignore.
66
+ # :rule - Exclusions in the :rule array are the rules to exclude from the ruleset used for the scan.
67
+ # Each rule is represented by its ID. For example: `gitlab_personal_access_token`
68
+ # for representing Gitlab Personal Access Token. By default, no rule is excluded from the ruleset.
66
69
  # +tags+:: Array of tag values to filter from the default ruleset when determining the rules used for the scan.
67
70
  # For example: Add `gitlab_blocking` to include only rules for Push Protection. Defaults to
68
71
  # [`gitlab_blocking`] (+DEFAULT_PATTERN_MATCHER_TAGS+).
@@ -84,8 +87,7 @@ module Gitlab
84
87
  payloads,
85
88
  timeout: DEFAULT_SCAN_TIMEOUT_SECS,
86
89
  payload_timeout: DEFAULT_PAYLOAD_TIMEOUT_SECS,
87
- raw_value_exclusions: [],
88
- rule_exclusions: [],
90
+ exclusions: {},
89
91
  tags: DEFAULT_PATTERN_MATCHER_TAGS,
90
92
  subprocess: RUN_IN_SUBPROCESS
91
93
  )
@@ -108,8 +110,7 @@ module Gitlab
108
110
  payloads: matched_payloads,
109
111
  payload_timeout:,
110
112
  pattern_matcher: build_pattern_matcher(tags:),
111
- raw_value_exclusions:,
112
- rule_exclusions:
113
+ exclusions:
113
114
  }
114
115
 
115
116
  secrets, applied_exclusions = subprocess ? run_scan_within_subprocess(**scan_args) : run_scan(**scan_args)
@@ -203,7 +204,7 @@ module Gitlab
203
204
  matched_payloads << payload
204
205
  end
205
206
 
206
- matched_payloads.freeze
207
+ matched_payloads
207
208
  end
208
209
 
209
210
  # Runs the secret detection scan on the given list of payloads. It accepts
@@ -213,8 +214,7 @@ module Gitlab
213
214
  payloads:,
214
215
  payload_timeout:,
215
216
  pattern_matcher:,
216
- raw_value_exclusions: [],
217
- rule_exclusions: []
217
+ exclusions: {}
218
218
  )
219
219
  all_applied_exclusions = Set.new
220
220
 
@@ -223,8 +223,7 @@ module Gitlab
223
223
  findings, applied_exclusions = find_secrets_in_payload(
224
224
  payload:,
225
225
  pattern_matcher:,
226
- raw_value_exclusions:,
227
- rule_exclusions:
226
+ exclusions:
228
227
  )
229
228
  all_applied_exclusions.merge(applied_exclusions)
230
229
  findings
@@ -235,15 +234,14 @@ module Gitlab
235
234
  Core::Finding.new(payload.id,
236
235
  Core::Status::PAYLOAD_TIMEOUT)
237
236
  end
238
- [all_findings.freeze, all_applied_exclusions.to_a.freeze]
237
+ [all_findings, all_applied_exclusions.to_a]
239
238
  end
240
239
 
241
240
  def run_scan_within_subprocess(
242
241
  payloads:,
243
242
  payload_timeout:,
244
243
  pattern_matcher:,
245
- raw_value_exclusions: [],
246
- rule_exclusions: []
244
+ exclusions: {}
247
245
  )
248
246
  all_applied_exclusions = Set.new
249
247
  payload_sizes = payloads.map(&:size)
@@ -261,7 +259,7 @@ module Gitlab
261
259
  findings, applied_exclusions = find_secrets_in_payload(
262
260
  payload:,
263
261
  pattern_matcher:,
264
- raw_value_exclusions:, rule_exclusions:
262
+ exclusions:
265
263
  )
266
264
  all_applied_exclusions.merge(applied_exclusions)
267
265
  findings
@@ -273,25 +271,28 @@ module Gitlab
273
271
  end
274
272
  end
275
273
 
276
- [found_secrets.freeze, all_applied_exclusions.to_a.freeze]
274
+ [found_secrets, all_applied_exclusions.to_a]
277
275
  end
278
276
 
279
277
  # Finds secrets in the given payload guarded with a timeout as a circuit breaker. It accepts
280
278
  # literal values to exclude from the input before the scan, also SD rules to exclude during
281
279
  # the scan.
282
- def find_secrets_in_payload(payload:, pattern_matcher:, raw_value_exclusions: [], rule_exclusions: [])
280
+ def find_secrets_in_payload(payload:, pattern_matcher:, exclusions: {})
283
281
  findings = []
284
282
  applied_exclusions = Set.new
285
283
 
286
284
  payload_offset = payload.respond_to?(:offset) ? payload.offset : 0
287
285
 
286
+ raw_value_exclusions = exclusions.fetch(:raw_value, [])
287
+ rule_exclusions = exclusions.fetch(:rule, [])
288
+
288
289
  payload.data
289
290
  .each_line($INPUT_RECORD_SEPARATOR, chomp: true)
290
291
  .each_with_index do |line, index|
291
292
  unless raw_value_exclusions.empty?
292
- raw_value_exclusions.each do |value|
293
- line.gsub!(value, '') # replace input that doesn't contain allowed value in it
294
- applied_exclusions << value # TODO we need the id of the exclusion
293
+ raw_value_exclusions.each do |exclusion|
294
+ line.gsub!(exclusion.value, '') # replace input that doesn't contain allowed value in it
295
+ applied_exclusions << exclusion
295
296
  end
296
297
  end
297
298
 
@@ -322,7 +323,7 @@ module Gitlab
322
323
  end
323
324
  end
324
325
 
325
- [findings.freeze, applied_exclusions]
326
+ [findings, applied_exclusions]
326
327
  rescue StandardError => e
327
328
  logger.error "Secret Detection scan failed on the payload(id:#{payload.id}): #{e}"
328
329
 
@@ -330,7 +331,7 @@ module Gitlab
330
331
  end
331
332
 
332
333
  def applied_rule_exclusion?(type, rule_exclusions, applied_exclusions)
333
- applied_exclusion = rule_exclusions&.find { |rule_exclusion| rule_exclusion == type }
334
+ applied_exclusion = rule_exclusions&.find { |rule_exclusion| rule_exclusion.value == type }
334
335
  applied_exclusion && (applied_exclusions << applied_exclusion)
335
336
  end
336
337
 
@@ -5,7 +5,7 @@
5
5
  require 'google/protobuf'
6
6
 
7
7
 
8
- descriptor_data = "\n\x16secret_detection.proto\x12\x17gitlab.secret_detection\"Z\n\tExclusion\x12>\n\x0e\x65xclusion_type\x18\x01 \x01(\x0e\x32&.gitlab.secret_detection.ExclusionType\x12\r\n\x05value\x18\x02 \x01(\t\"\xc0\x02\n\x0bScanRequest\x12>\n\x08payloads\x18\x01 \x03(\x0b\x32,.gitlab.secret_detection.ScanRequest.Payload\x12\x19\n\x0ctimeout_secs\x18\x02 \x01(\x02H\x00\x88\x01\x01\x12!\n\x14payload_timeout_secs\x18\x03 \x01(\x02H\x01\x88\x01\x01\x12\x36\n\nexclusions\x18\x04 \x03(\x0b\x32\".gitlab.secret_detection.Exclusion\x12\x0c\n\x04tags\x18\x05 \x03(\t\x1a\x43\n\x07Payload\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\x12\x13\n\x06offset\x18\x03 \x01(\x05H\x00\x88\x01\x01\x42\t\n\x07_offsetB\x0f\n\r_timeout_secsB\x17\n\x15_payload_timeout_secs\"\xa2\x04\n\x0cScanResponse\x12>\n\x07results\x18\x01 \x03(\x0b\x32-.gitlab.secret_detection.ScanResponse.Finding\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12>\n\x12\x61pplied_exclusions\x18\x03 \x03(\x0b\x32\".gitlab.secret_detection.Exclusion\x1a\x9d\x01\n\x07\x46inding\x12\x12\n\npayload_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12\x11\n\x04type\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bline_number\x18\x05 \x01(\x05H\x02\x88\x01\x01\x42\x07\n\x05_typeB\x0e\n\x0c_descriptionB\x0e\n\x0c_line_number\"\xe1\x01\n\x06Status\x12\x16\n\x12STATUS_UNSPECIFIED\x10\x00\x12\x10\n\x0cSTATUS_FOUND\x10\x01\x12\x1c\n\x18STATUS_FOUND_WITH_ERRORS\x10\x02\x12\x17\n\x13STATUS_SCAN_TIMEOUT\x10\x03\x12\x1a\n\x16STATUS_PAYLOAD_TIMEOUT\x10\x04\x12\x15\n\x11STATUS_SCAN_ERROR\x10\x05\x12\x16\n\x12STATUS_INPUT_ERROR\x10\x06\x12\x14\n\x10STATUS_NOT_FOUND\x10\x07\x12\x15\n\x11STATUS_AUTH_ERROR\x10\x08*f\n\rExclusionType\x12\x1e\n\x1a\x45XCLUSION_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13\x45XCLUSION_TYPE_RULE\x10\x01\x12\x1c\n\x18\x45XCLUSION_TYPE_RAW_VALUE\x10\x02\x32\xc1\x01\n\x07Scanner\x12U\n\x04Scan\x12$.gitlab.secret_detection.ScanRequest\x1a%.gitlab.secret_detection.ScanResponse\"\x00\x12_\n\nScanStream\x12$.gitlab.secret_detection.ScanRequest\x1a%.gitlab.secret_detection.ScanResponse\"\x00(\x01\x30\x01\x42 \xea\x02\x1dGitlab::SecretDetection::GRPCb\x06proto3"
8
+ descriptor_data = "\n\x16secret_detection.proto\x12\x17gitlab.secret_detection\"Z\n\tExclusion\x12>\n\x0e\x65xclusion_type\x18\x01 \x01(\x0e\x32&.gitlab.secret_detection.ExclusionType\x12\r\n\x05value\x18\x02 \x01(\t\"\xc0\x02\n\x0bScanRequest\x12>\n\x08payloads\x18\x01 \x03(\x0b\x32,.gitlab.secret_detection.ScanRequest.Payload\x12\x19\n\x0ctimeout_secs\x18\x02 \x01(\x02H\x00\x88\x01\x01\x12!\n\x14payload_timeout_secs\x18\x03 \x01(\x02H\x01\x88\x01\x01\x12\x36\n\nexclusions\x18\x04 \x03(\x0b\x32\".gitlab.secret_detection.Exclusion\x12\x0c\n\x04tags\x18\x05 \x03(\t\x1a\x43\n\x07Payload\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\x12\x13\n\x06offset\x18\x03 \x01(\x05H\x00\x88\x01\x01\x42\t\n\x07_offsetB\x0f\n\r_timeout_secsB\x17\n\x15_payload_timeout_secs\"\xa2\x04\n\x0cScanResponse\x12>\n\x07results\x18\x01 \x03(\x0b\x32-.gitlab.secret_detection.ScanResponse.Finding\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12>\n\x12\x61pplied_exclusions\x18\x03 \x03(\x0b\x32\".gitlab.secret_detection.Exclusion\x1a\x9d\x01\n\x07\x46inding\x12\x12\n\npayload_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12\x11\n\x04type\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bline_number\x18\x05 \x01(\x05H\x02\x88\x01\x01\x42\x07\n\x05_typeB\x0e\n\x0c_descriptionB\x0e\n\x0c_line_number\"\xe1\x01\n\x06Status\x12\x16\n\x12STATUS_UNSPECIFIED\x10\x00\x12\x10\n\x0cSTATUS_FOUND\x10\x01\x12\x1c\n\x18STATUS_FOUND_WITH_ERRORS\x10\x02\x12\x17\n\x13STATUS_SCAN_TIMEOUT\x10\x03\x12\x1a\n\x16STATUS_PAYLOAD_TIMEOUT\x10\x04\x12\x15\n\x11STATUS_SCAN_ERROR\x10\x05\x12\x16\n\x12STATUS_INPUT_ERROR\x10\x06\x12\x14\n\x10STATUS_NOT_FOUND\x10\x07\x12\x15\n\x11STATUS_AUTH_ERROR\x10\x08*\x7f\n\rExclusionType\x12\x1e\n\x1a\x45XCLUSION_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13\x45XCLUSION_TYPE_RULE\x10\x01\x12\x1c\n\x18\x45XCLUSION_TYPE_RAW_VALUE\x10\x02\x12\x17\n\x13\x45XCLUSION_TYPE_PATH\x10\x03\x32\xc1\x01\n\x07Scanner\x12U\n\x04Scan\x12$.gitlab.secret_detection.ScanRequest\x1a%.gitlab.secret_detection.ScanResponse\"\x00\x12_\n\nScanStream\x12$.gitlab.secret_detection.ScanRequest\x1a%.gitlab.secret_detection.ScanResponse\"\x00(\x01\x30\x01\x42 \xea\x02\x1dGitlab::SecretDetection::GRPCb\x06proto3"
9
9
 
10
10
  pool = Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
@@ -61,24 +61,25 @@ module Gitlab
61
61
  validate_request(request)
62
62
 
63
63
  payloads = request.payloads.to_a
64
+ exclusions = { raw_value: [], rule: [], path: [] }
64
65
 
65
- raw_value_exclusions = []
66
- rule_exclusions = []
67
-
68
- request.exclusions&.each do |exclusion|
69
- case exclusion.type
66
+ request.exclusions.each do |exclusion|
67
+ case exclusion.exclusion_type
70
68
  when :EXCLUSION_TYPE_RAW_VALUE
71
- raw_value_exclusions << exclusion.value
69
+ exclusions[:raw] << exclusion
72
70
  when :EXCLUSION_TYPE_RULE
73
- rule_exclusions << exclusion.value
71
+ exclusions[:rule] << exclusion
72
+ when :EXCLUSION_TYPE_PATH
73
+ exclusions[:path] << exclusion
74
+ else
75
+ logger.warn("Unknown exclusion type #{exclusion.exclusion_type}")
74
76
  end
75
77
  end
76
78
 
77
79
  begin
78
80
  result = scanner.secrets_scan(
79
81
  payloads,
80
- raw_value_exclusions:,
81
- rule_exclusions:,
82
+ exclusions:,
82
83
  tags: request.tags.to_a,
83
84
  timeout: request.timeout_secs,
84
85
  payload_timeout: request.payload_timeout_secs
@@ -94,7 +95,8 @@ module Gitlab
94
95
 
95
96
  Gitlab::SecretDetection::GRPC::ScanResponse.new(
96
97
  results: findings,
97
- status: result.status
98
+ status: result.status,
99
+ applied_exclusions: result.applied_exclusions
98
100
  )
99
101
  end
100
102
 
@@ -17,6 +17,7 @@ enum ExclusionType {
17
17
  EXCLUSION_TYPE_UNSPECIFIED = 0;
18
18
  EXCLUSION_TYPE_RULE = 1; // Rule ID to exclude
19
19
  EXCLUSION_TYPE_RAW_VALUE = 2; // Raw value to exclude
20
+ EXCLUSION_TYPE_PATH = 3; // Specific file path to exclude
20
21
  }
21
22
 
22
23
  /* Request arg for triggering Scan/ScanStream method */
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-secret_detection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - group::secret detection
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-12-11 00:00:00.000000000 Z
13
+ date: 2024-12-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: grpc