gitlab-secret_detection 0.45.0 → 0.46.0
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 +4 -4
- data/README.md +27 -0
- data/lib/gitlab/secret_detection/core/ruleset.rb +152 -16
- data/lib/gitlab/secret_detection/core/scanner.rb +57 -24
- data/lib/gitlab/secret_detection/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31d3996d42590cabd29d5198d67cc9ee716f31232d207183f98986a3dc0f4bdb
|
|
4
|
+
data.tar.gz: 44811e65092f594a602a9cc2f399d98ac047569dc7bac7f359a18190fa18c54e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ab9cea777bf959289694831001f055df76b80265df7af578e167b25096403952f4a659f442351f301d6b38a31865a579d47d9b83f68f5201dfbecd1f60679c3
|
|
7
|
+
data.tar.gz: 520ad2c9f1a97c9576460e0b28071564acf9cadf3516118051e91bb4c09e1ef103b86a054573efe8755d3def33a3b899c74baa01488e326c5a6fa32fcffedb0e
|
data/README.md
CHANGED
|
@@ -88,6 +88,33 @@ The command is called when running tests as well as when building the Dockerfile
|
|
|
88
88
|
The secret_push_protection_rules.toml file is added to .gitignore to
|
|
89
89
|
avoid checking in changes.
|
|
90
90
|
|
|
91
|
+
### Custom ruleset file (gem only)
|
|
92
|
+
|
|
93
|
+
A consumer of the ruby gem can use a custom ruleset file instead of the bundled
|
|
94
|
+
secret_push_protection_rules.toml file. Set the `GITLAB_SD_RULESET_FILE_PATH` environment variable
|
|
95
|
+
to the path of the custom file. Set it in the environment of the process that runs the scan.
|
|
96
|
+
|
|
97
|
+
- The file must be a TOML file with a `.toml` extension.
|
|
98
|
+
- A relative path is resolved against the working directory of the process. `~` is not expanded.
|
|
99
|
+
- A `path:` argument to `Gitlab::SecretDetection::Core::Ruleset.new` has priority over the environment variable.
|
|
100
|
+
- The rules are loaded one time for each `Ruleset` object. A change to the file has an effect only on a new load.
|
|
101
|
+
- The gRPC service also reads this environment variable, but this use is not supported.
|
|
102
|
+
|
|
103
|
+
The custom file must have a non-empty `[[rules]]` array. Each rule must have these fields:
|
|
104
|
+
|
|
105
|
+
| Field | Required | Description |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `id` | Yes | A non-empty string. Each `id` must be unique in the file. |
|
|
108
|
+
| `regex` | Yes | A non-empty string that RE2 can compile. |
|
|
109
|
+
| `title` or `description` | Yes | The scanner uses the `title` as the finding description. It uses the `description` only if the `title` is missing, empty, or has only white space. The value that the scanner uses must be a non-empty string. |
|
|
110
|
+
| `keywords` | No | An array of non-empty strings. |
|
|
111
|
+
|
|
112
|
+
The scanner uses the keyword prefilter only for the rules that have keywords. It matches the rules that have no keywords on all payloads.
|
|
113
|
+
|
|
114
|
+
If the custom file cannot be loaded or fails validation, the gem logs an error with the message
|
|
115
|
+
`Failed to load custom secret detection ruleset. Using the default ruleset.` and loads the bundled file.
|
|
116
|
+
The log entry contains the error class and the full error message. For a validation error, the message lists each problem on its own line. For a TOML syntax error, the message contains the line of the file that has the error.
|
|
117
|
+
|
|
91
118
|
## Generating a ruby gem
|
|
92
119
|
|
|
93
120
|
In the project directory, run `make gem` command in the terminal that builds a ruby gem(ex: `secret_detection-0.1.0.gem`) in the root of
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
require 'toml-rb'
|
|
4
4
|
require 'logger'
|
|
5
|
+
require 're2'
|
|
6
|
+
require_relative '../utils/memoize'
|
|
5
7
|
|
|
6
8
|
module Gitlab
|
|
7
9
|
module SecretDetection
|
|
8
10
|
module Core
|
|
9
11
|
class Ruleset
|
|
12
|
+
include ::Gitlab::SecretDetection::Utils::StrongMemoize
|
|
13
|
+
|
|
10
14
|
# RulesetParseError is thrown when the code fails to parse the
|
|
11
15
|
# ruleset file from the given path
|
|
12
16
|
RulesetParseError = Class.new(StandardError)
|
|
@@ -15,10 +19,42 @@ module Gitlab
|
|
|
15
19
|
# the predefined rulesets
|
|
16
20
|
RulesetCompilationError = Class.new(StandardError)
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
ERROR_MESSAGES = {
|
|
23
|
+
version_extraction_failed: "Failed to extract Secret Detection Ruleset version from ruleset file",
|
|
24
|
+
parse_failed: "Failed to parse local secret detection ruleset: %<error>s",
|
|
25
|
+
fallback: "Failed to load custom secret detection ruleset. Using the default ruleset.",
|
|
26
|
+
validation_failed: "Ruleset validation failed:\n%<errors>s",
|
|
27
|
+
invalid_extension: "Ruleset file must have a .toml extension",
|
|
28
|
+
empty_rules: "Rules must be a non-empty Array of [[rules]] tables",
|
|
29
|
+
duplicate_ids: "Rule ids must be unique",
|
|
30
|
+
rule_error: "rules[%<index>d]: %<error>s",
|
|
31
|
+
rule_not_table: "Rule must be a toml table",
|
|
32
|
+
invalid_id: "Rule id must be a non-empty String",
|
|
33
|
+
empty_regex: "Rule regex must be a non-empty String",
|
|
34
|
+
invalid_regex: "Rule regex is not valid: %<error>s",
|
|
35
|
+
invalid_description: "Rule title or description must be a non-empty String",
|
|
36
|
+
invalid_keywords: "Rule keywords must be either empty or an Array of non-empty Strings"
|
|
37
|
+
}.freeze
|
|
38
|
+
|
|
39
|
+
# RulesetValidationError is raised when a custom ruleset file fails validation
|
|
40
|
+
class RulesetValidationError < RulesetParseError
|
|
41
|
+
def initialize(errors)
|
|
42
|
+
super(format(ERROR_MESSAGES[:validation_failed], errors: errors.join("\n")))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Default ruleset file path
|
|
19
47
|
RULESET_FILE_PATH = File.expand_path('secret_push_protection_rules.toml', __dir__)
|
|
20
48
|
|
|
21
|
-
|
|
49
|
+
RULESET_FILE_PATH_ENV = 'GITLAB_SD_RULESET_FILE_PATH'
|
|
50
|
+
|
|
51
|
+
# Returns the rule title, or the rule description when the title is nil or blank.
|
|
52
|
+
def self.finding_description(rule)
|
|
53
|
+
title = rule[:title]
|
|
54
|
+
title.is_a?(String) && !title.strip.empty? ? title : rule[:description]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def initialize(path: nil, logger: Logger.new($stdout))
|
|
22
58
|
@path = path
|
|
23
59
|
@logger = logger
|
|
24
60
|
end
|
|
@@ -29,38 +65,138 @@ module Gitlab
|
|
|
29
65
|
@rule_data = parse_ruleset
|
|
30
66
|
end
|
|
31
67
|
|
|
68
|
+
# Before a load, it reads the file at resolved_path.
|
|
32
69
|
def extract_ruleset_version
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
file_path = loaded_path || resolved_path
|
|
71
|
+
return unless File.readable?(file_path)
|
|
72
|
+
|
|
73
|
+
first_line = File.open(file_path, &:gets)
|
|
74
|
+
first_line&.split(":")&.[](1)&.strip # Gets "0.24.3" from "# rule-set version: 0.24.3"
|
|
37
75
|
rescue StandardError => e
|
|
38
|
-
logger.error(message:
|
|
76
|
+
logger.error(message: ERROR_MESSAGES[:version_extraction_failed], error: e.message)
|
|
77
|
+
nil
|
|
39
78
|
end
|
|
40
79
|
|
|
41
80
|
private
|
|
42
81
|
|
|
43
|
-
attr_reader :
|
|
82
|
+
attr_reader :logger, :loaded_path
|
|
44
83
|
|
|
45
|
-
# parses given ruleset file and returns the parsed rules
|
|
46
84
|
def parse_ruleset
|
|
85
|
+
load_from(resolved_path)
|
|
86
|
+
rescue RulesetParseError => e
|
|
87
|
+
raise if resolved_path == RULESET_FILE_PATH
|
|
88
|
+
|
|
89
|
+
log_fallback(e)
|
|
90
|
+
load_from(RULESET_FILE_PATH)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def resolved_path
|
|
94
|
+
return File.absolute_path(@path) if @path
|
|
95
|
+
|
|
96
|
+
env_value = ENV.fetch(RULESET_FILE_PATH_ENV, '').strip
|
|
97
|
+
env_value.empty? ? RULESET_FILE_PATH : File.absolute_path(env_value)
|
|
98
|
+
end
|
|
99
|
+
strong_memoize_attr :resolved_path
|
|
100
|
+
|
|
101
|
+
def load_from(file_path)
|
|
102
|
+
custom = file_path != RULESET_FILE_PATH
|
|
103
|
+
|
|
47
104
|
logger.info(
|
|
48
|
-
message: "Parsing
|
|
49
|
-
ruleset_path:
|
|
105
|
+
message: "Parsing #{custom ? 'custom' : 'bundled'} ruleset file",
|
|
106
|
+
ruleset_path: file_path
|
|
50
107
|
)
|
|
51
|
-
|
|
52
|
-
|
|
108
|
+
check_toml_extension!(file_path) if custom
|
|
109
|
+
|
|
110
|
+
rules_data = TomlRB.load_file(file_path, symbolize_keys: true).freeze
|
|
111
|
+
validate_rules!(rules_data) if custom
|
|
53
112
|
|
|
113
|
+
@loaded_path = file_path
|
|
54
114
|
logger.info(
|
|
55
115
|
message: "Ruleset details fetched for running Secret Detection scan",
|
|
116
|
+
ruleset_path: file_path,
|
|
56
117
|
total_rules: rules_data[:rules]&.length,
|
|
57
|
-
ruleset_version:
|
|
118
|
+
ruleset_version: extract_ruleset_version,
|
|
119
|
+
custom_ruleset: custom
|
|
58
120
|
)
|
|
59
121
|
rules_data[:rules].freeze
|
|
60
|
-
rescue
|
|
61
|
-
|
|
122
|
+
rescue RulesetParseError
|
|
123
|
+
raise
|
|
124
|
+
# A deeply nested TOML file raises SystemStackError.
|
|
125
|
+
rescue StandardError, SystemStackError => e
|
|
126
|
+
logger.error(message: format(ERROR_MESSAGES[:parse_failed], error: e.message)) unless custom
|
|
62
127
|
raise RulesetParseError, e
|
|
63
128
|
end
|
|
129
|
+
|
|
130
|
+
def check_toml_extension!(file_path)
|
|
131
|
+
return if File.extname(file_path).casecmp?('.toml')
|
|
132
|
+
|
|
133
|
+
raise RulesetValidationError, [ERROR_MESSAGES[:invalid_extension]]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Ruleset validation ensuring it has all the required
|
|
137
|
+
# fields. Applicable to custom ruleset input only.
|
|
138
|
+
def validate_rules!(rules_data)
|
|
139
|
+
rules = rules_data[:rules]
|
|
140
|
+
raise RulesetValidationError, [ERROR_MESSAGES[:empty_rules]] unless rules.is_a?(Array) && !rules.empty?
|
|
141
|
+
|
|
142
|
+
errors = rules.each_with_index.flat_map do |rule, index|
|
|
143
|
+
rule_errors(rule).map { |error| format(ERROR_MESSAGES[:rule_error], index:, error:) }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if errors.empty? && rules.map { |rule| rule[:id] }.uniq.size < rules.size
|
|
147
|
+
errors << ERROR_MESSAGES[:duplicate_ids]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
raise RulesetValidationError, errors unless errors.empty?
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def rule_errors(rule)
|
|
154
|
+
return [ERROR_MESSAGES[:rule_not_table]] unless rule.is_a?(Hash)
|
|
155
|
+
|
|
156
|
+
finding_description = self.class.finding_description(rule)
|
|
157
|
+
keywords = rule[:keywords]
|
|
158
|
+
|
|
159
|
+
errors = []
|
|
160
|
+
errors << ERROR_MESSAGES[:invalid_id] unless non_empty_string?(rule[:id])
|
|
161
|
+
errors << regex_error(rule[:regex])
|
|
162
|
+
errors << ERROR_MESSAGES[:invalid_description] unless non_empty_string?(finding_description)
|
|
163
|
+
|
|
164
|
+
unless keywords.nil? || (keywords.is_a?(Array) && keywords.all? { |keyword| non_empty_string?(keyword) })
|
|
165
|
+
errors << ERROR_MESSAGES[:invalid_keywords]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
errors.compact
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def regex_error(regex)
|
|
172
|
+
return ERROR_MESSAGES[:empty_regex] unless non_empty_string?(regex)
|
|
173
|
+
|
|
174
|
+
# Without log_errors: false, RE2 writes the pattern to STDERR.
|
|
175
|
+
compiled = RE2::Regexp.new(regex, log_errors: false)
|
|
176
|
+
format(ERROR_MESSAGES[:invalid_regex], error: compiled.error) unless compiled.ok?
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def non_empty_string?(value)
|
|
180
|
+
value.is_a?(String) && !value.strip.empty?
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def log_fallback(error)
|
|
184
|
+
logger.error(
|
|
185
|
+
message: ERROR_MESSAGES[:fallback],
|
|
186
|
+
custom_ruleset_path: resolved_path,
|
|
187
|
+
default_ruleset_path: RULESET_FILE_PATH,
|
|
188
|
+
ruleset_path_env: RULESET_FILE_PATH_ENV,
|
|
189
|
+
error_class: fallback_error_class(error),
|
|
190
|
+
error_message: error.message
|
|
191
|
+
)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# A validation error gets an unrelated cause when #rules runs inside a rescue block.
|
|
195
|
+
def fallback_error_class(error)
|
|
196
|
+
return error.class.name if error.is_a?(RulesetValidationError)
|
|
197
|
+
|
|
198
|
+
(error.cause || error).class.name
|
|
199
|
+
end
|
|
64
200
|
end
|
|
65
201
|
end
|
|
66
202
|
end
|
|
@@ -46,10 +46,14 @@ module Gitlab
|
|
|
46
46
|
# Raises +RulesetCompilationError+ in case the regex pattern compilation fails.
|
|
47
47
|
def initialize(rules:, logger: Logger.new($stdout))
|
|
48
48
|
@logger = logger
|
|
49
|
-
|
|
49
|
+
selected_rules = select_push_protection_rules(rules)
|
|
50
|
+
keywordless_rules, keyword_rules = selected_rules.partition { |rule| Array(rule[:keywords]).empty? }
|
|
51
|
+
# Rules with no keywords come first, so that the indexes of their pattern matcher are also indexes in @rules.
|
|
52
|
+
@rules = (keywordless_rules + keyword_rules).freeze
|
|
50
53
|
@keywords = create_keywords(@rules)
|
|
51
|
-
@keyword_matcher = build_keyword_matcher(@
|
|
54
|
+
@keyword_matcher = build_keyword_matcher(@keywords)
|
|
52
55
|
@pattern_matcher = build_pattern_matcher(@rules)
|
|
56
|
+
@keywordless_pattern_matcher = build_pattern_matcher(keywordless_rules) unless keywordless_rules.empty?
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
# Runs Secret Detection scan on the list of given payloads. Both the total scan duration and
|
|
@@ -123,16 +127,17 @@ module Gitlab
|
|
|
123
127
|
|
|
124
128
|
Timeout.timeout(timeout) do
|
|
125
129
|
matched_payloads = filter_by_keywords(keyword_matcher, payloads)
|
|
130
|
+
# Rules with no keywords also apply to the payloads that the keyword prefilter drops.
|
|
131
|
+
unmatched_payloads = keywordless_pattern_matcher ? payloads - matched_payloads : []
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
if matched_payloads.empty? && unmatched_payloads.empty?
|
|
134
|
+
next Core::Response.new(status: Core::Status::NOT_FOUND)
|
|
135
|
+
end
|
|
128
136
|
|
|
129
137
|
scan_args = {
|
|
130
|
-
payloads: matched_payloads,
|
|
131
138
|
payload_timeout:,
|
|
132
|
-
pattern_matcher:,
|
|
133
139
|
rules:,
|
|
134
140
|
exclusions:,
|
|
135
|
-
max_findings_limit:,
|
|
136
141
|
include_raw_value:
|
|
137
142
|
}.freeze
|
|
138
143
|
|
|
@@ -141,14 +146,17 @@ module Gitlab
|
|
|
141
146
|
timeout:,
|
|
142
147
|
payload_timeout:,
|
|
143
148
|
given_total_payloads: payloads.length,
|
|
144
|
-
|
|
149
|
+
keyword_matched_payloads: matched_payloads.length,
|
|
150
|
+
payloads_for_keywordless_rules: unmatched_payloads.length,
|
|
145
151
|
active_rules: rules.length,
|
|
146
152
|
run_in_subprocess: subprocess,
|
|
147
153
|
max_findings_limit:,
|
|
148
154
|
given_exclusions: format_exclusions_hash(exclusions)
|
|
149
155
|
)
|
|
150
156
|
|
|
151
|
-
secrets, applied_exclusions =
|
|
157
|
+
secrets, applied_exclusions = scan_payload_groups(
|
|
158
|
+
matched_payloads, unmatched_payloads, subprocess:, max_findings_limit:, **scan_args
|
|
159
|
+
)
|
|
152
160
|
|
|
153
161
|
scan_status = overall_scan_status(secrets)
|
|
154
162
|
|
|
@@ -168,7 +176,7 @@ module Gitlab
|
|
|
168
176
|
|
|
169
177
|
private
|
|
170
178
|
|
|
171
|
-
attr_reader :logger, :rules, :keywords, :pattern_matcher, :keyword_matcher
|
|
179
|
+
attr_reader :logger, :rules, :keywords, :pattern_matcher, :keyword_matcher, :keywordless_pattern_matcher
|
|
172
180
|
|
|
173
181
|
# A rule applies to push protection when its structured `scanningCapabilities`
|
|
174
182
|
# field includes `pushProtection`. Rules without the field are included for
|
|
@@ -245,36 +253,41 @@ module Gitlab
|
|
|
245
253
|
secrets_keywords.freeze
|
|
246
254
|
end
|
|
247
255
|
|
|
248
|
-
# Builds RE2 keyword matcher from the
|
|
249
|
-
# nil when the
|
|
256
|
+
# Builds RE2 keyword matcher from the given set of keywords. Returns
|
|
257
|
+
# nil when the set is empty, in which case the keyword-based
|
|
250
258
|
# payload prefilter is skipped.
|
|
251
|
-
def build_keyword_matcher(
|
|
259
|
+
def build_keyword_matcher(keywords)
|
|
252
260
|
logger.info(
|
|
253
261
|
message: "Creating RE2 Keyword Matcher",
|
|
254
|
-
|
|
262
|
+
keywords_count: keywords.size
|
|
255
263
|
)
|
|
256
264
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
rules.each do |rule|
|
|
260
|
-
include_keywords.merge(rule[:keywords]) unless rule[:keywords].nil?
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
if include_keywords.empty?
|
|
265
|
+
if keywords.empty?
|
|
264
266
|
logger.error(
|
|
265
267
|
message: "No rule keywords found in the given rules, returning empty RE2 Keyword Matcher"
|
|
266
268
|
)
|
|
267
269
|
return nil
|
|
268
270
|
end
|
|
269
271
|
|
|
270
|
-
keywords_regex =
|
|
272
|
+
keywords_regex = keywords.map { |keyword| RE2::Regexp.quote(keyword) }.join('|')
|
|
271
273
|
|
|
272
274
|
logger.debug(
|
|
273
275
|
message: "Creating RE2 Keyword Matcher with set of rule keywords",
|
|
274
|
-
keywords:
|
|
276
|
+
keywords: keywords.to_a
|
|
275
277
|
)
|
|
276
278
|
|
|
277
|
-
RE2
|
|
279
|
+
# Without log_errors: false, RE2 writes the pattern to STDERR.
|
|
280
|
+
keyword_matcher = RE2::Regexp.new("(#{keywords_regex})", log_errors: false)
|
|
281
|
+
return keyword_matcher if keyword_matcher.ok?
|
|
282
|
+
|
|
283
|
+
# A matcher that does not compile matches no payload.
|
|
284
|
+
logger.error(
|
|
285
|
+
message: "Failed to compile the RE2 Keyword Matcher. The scan skips the keyword prefilter and directly " \
|
|
286
|
+
"scans all payloads with rule regex patterns.",
|
|
287
|
+
keywords_count: keywords.size,
|
|
288
|
+
error: keyword_matcher.error
|
|
289
|
+
)
|
|
290
|
+
nil
|
|
278
291
|
end
|
|
279
292
|
|
|
280
293
|
def filter_by_keywords(keyword_matcher, payloads)
|
|
@@ -307,6 +320,26 @@ module Gitlab
|
|
|
307
320
|
matched_payloads
|
|
308
321
|
end
|
|
309
322
|
|
|
323
|
+
# Scans the payloads that have a keyword with all rules, and the other payloads
|
|
324
|
+
# with only the rules that have no keywords.
|
|
325
|
+
def scan_payload_groups(matched_payloads, unmatched_payloads, subprocess:, max_findings_limit:, **scan_args)
|
|
326
|
+
secrets = []
|
|
327
|
+
applied_exclusions = []
|
|
328
|
+
groups = [[matched_payloads, pattern_matcher], [unmatched_payloads, keywordless_pattern_matcher]]
|
|
329
|
+
|
|
330
|
+
groups.each do |group, matcher|
|
|
331
|
+
remaining_limit = max_findings_limit - secrets.length
|
|
332
|
+
next if group.empty? || remaining_limit <= 0
|
|
333
|
+
|
|
334
|
+
args = scan_args.merge(payloads: group, pattern_matcher: matcher, max_findings_limit: remaining_limit)
|
|
335
|
+
found, excluded = subprocess ? run_scan_within_subprocess(**args) : run_scan(**args)
|
|
336
|
+
secrets.concat(found)
|
|
337
|
+
applied_exclusions |= excluded
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
[secrets, applied_exclusions]
|
|
341
|
+
end
|
|
342
|
+
|
|
310
343
|
# Runs the secret detection scan on the given list of payloads. It accepts
|
|
311
344
|
# literal values to exclude from the input before the scan, also SD rules to exclude during
|
|
312
345
|
# the scan when performed on the payloads.
|
|
@@ -477,7 +510,7 @@ module Gitlab
|
|
|
477
510
|
Core::Status::FOUND,
|
|
478
511
|
line_no,
|
|
479
512
|
rule[:id],
|
|
480
|
-
rule
|
|
513
|
+
Core::Ruleset.finding_description(rule),
|
|
481
514
|
raw_value: secret
|
|
482
515
|
)
|
|
483
516
|
end
|
|
@@ -5,7 +5,7 @@ module Gitlab
|
|
|
5
5
|
class Gem
|
|
6
6
|
# Ensure to maintain the same version in CHANGELOG file.
|
|
7
7
|
# More details available under 'Release Process' section in the README.md file.
|
|
8
|
-
VERSION = "0.
|
|
8
|
+
VERSION = "0.46.0"
|
|
9
9
|
|
|
10
10
|
# SD_ENV env var is used to determine which environment the
|
|
11
11
|
# server is running. This var is defined in `.runway/env-<env>.yml` files.
|
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.
|
|
4
|
+
version: 0.46.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: 2026-
|
|
13
|
+
date: 2026-09-28 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: grpc
|