gitlab-secret_detection 0.13.0 → 0.14.1
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/lib/gitlab/secret_detection/core/response.rb +3 -1
- data/lib/gitlab/secret_detection/core/ruleset.rb +1 -1
- data/lib/gitlab/secret_detection/core/scanner.rb +25 -24
- data/lib/gitlab/secret_detection/core/secret_push_protection_rules.toml +223 -0
- data/lib/gitlab/secret_detection/grpc/generated/secret_detection_pb.rb +1 -1
- data/lib/gitlab/secret_detection/grpc/scanner_service.rb +12 -10
- data/proto/secret_detection.proto +1 -0
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b0ab467aac5be2b21d736da1917982e522bb79522d108ae9edeb0ad0b80b0c09
         | 
| 4 | 
            +
              data.tar.gz: c0bdaee4db1a8d5220333e44c6ca87645c48ba10d838ecfef5fd632eb7169f31
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f54376fa5767253bd79e88b826e1a19f79c0222e16f1394b301c801ff61fb1fbb0f27fbbdd6b0c8899f013fdae75c5b5887327e8e7873c17257a2c16968d70f5
         | 
| 7 | 
            +
              data.tar.gz: 7805cd5cf18f94006d4e0fb6409d79b2b48fed3108f7eb598a6cea64141d2a43065dad5d0cd58867138cd6aaf8ef71bbd17479b992d9853f46c198f468311bf0
         | 
| @@ -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  | 
| 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 | 
            -
                    # + | 
| 63 | 
            -
                    #  | 
| 64 | 
            -
                    #            | 
| 65 | 
            -
                    #            | 
| 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 | 
            -
                       | 
| 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 | 
            -
                           | 
| 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 | 
| 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 | 
            -
                       | 
| 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 | 
            -
                             | 
| 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 | 
| 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 | 
            -
                       | 
| 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 | 
            -
                               | 
| 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 | 
| 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:,  | 
| 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 | | 
| 293 | 
            -
                            line.gsub!(value, '') # replace input that doesn't contain allowed value in it
         | 
| 294 | 
            -
                            applied_exclusions <<  | 
| 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 | 
| 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 |  | 
| @@ -0,0 +1,223 @@ | |
| 1 | 
            +
            # rule-set version: 0.3.0
         | 
| 2 | 
            +
            # Rules are auto-generated. See https://gitlab.com/gitlab-org/security-products/secret-detection/secret-detection-rules for instructions on updating the rules.
         | 
| 3 | 
            +
            [[rules]]
         | 
| 4 | 
            +
            description = "Anthropic keys"
         | 
| 5 | 
            +
            id = "anthropic_key"
         | 
| 6 | 
            +
            keywords = ["sk-ant-"]
         | 
| 7 | 
            +
            regex = "\\b(sk-ant-[a-z]{3}\\d{2}-[A-Za-z0-9\\\\-_]{86}-[A-Za-z0-9\\\\-_]{8})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 8 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 9 | 
            +
            [[rules]]
         | 
| 10 | 
            +
            description = "AWS Access Token"
         | 
| 11 | 
            +
            id = "AWS"
         | 
| 12 | 
            +
            keywords = ["AKIA"]
         | 
| 13 | 
            +
            regex = "\\bAKIA[0-9A-Z]{16}\\b"
         | 
| 14 | 
            +
            tags = ["aws", "revocation_type", "gitlab_blocking"]
         | 
| 15 | 
            +
            [[rules]]
         | 
| 16 | 
            +
            description = "GCP API keys can be misused to gain API quota from billed projects"
         | 
| 17 | 
            +
            id = "GCP API key"
         | 
| 18 | 
            +
            keywords = ["AIza"]
         | 
| 19 | 
            +
            regex = "(?i)\\b(AIza[0-9A-Za-z-_]{35})(?:['|\\\"|\\n|\\r|\\s|\\x60|;]|$)"
         | 
| 20 | 
            +
            secretGroup = 1
         | 
| 21 | 
            +
            tags = ["gitlab_partner_token", "revocation_type", "gitlab_blocking"]
         | 
| 22 | 
            +
            [[rules]]
         | 
| 23 | 
            +
            description = "GCP OAuth client secrets can be misused to spoof your application"
         | 
| 24 | 
            +
            id = "GCP OAuth client secret"
         | 
| 25 | 
            +
            keywords = ["GOCSPX-"]
         | 
| 26 | 
            +
            regex = "GOCSPX-[a-zA-Z0-9_-]{28}"
         | 
| 27 | 
            +
            tags = ["gitlab_partner_token", "revocation_type", "gitlab_blocking"]
         | 
| 28 | 
            +
            [[rules]]
         | 
| 29 | 
            +
            description = "Google (GCP) Service-account"
         | 
| 30 | 
            +
            id = "Google (GCP) Service-account"
         | 
| 31 | 
            +
            keywords = ["service_account"]
         | 
| 32 | 
            +
            regex = "\\\"private_key\\\":\\s*\\\"-{5}BEGIN PRIVATE KEY-{5}[\\s\\S]*?\","
         | 
| 33 | 
            +
            tags = ["gitlab_partner_token", "revocation_type", "gitlab_blocking"]
         | 
| 34 | 
            +
            [[rules]]
         | 
| 35 | 
            +
            description = "Github Personal Access Token"
         | 
| 36 | 
            +
            id = "Github Personal Access Token"
         | 
| 37 | 
            +
            keywords = ["ghp_"]
         | 
| 38 | 
            +
            regex = "ghp_[0-9a-zA-Z]{36}"
         | 
| 39 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 40 | 
            +
            [[rules]]
         | 
| 41 | 
            +
            description = "Github OAuth Access Token"
         | 
| 42 | 
            +
            id = "Github OAuth Access Token"
         | 
| 43 | 
            +
            keywords = ["gho_"]
         | 
| 44 | 
            +
            regex = "gho_[0-9a-zA-Z]{36}"
         | 
| 45 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 46 | 
            +
            [[rules]]
         | 
| 47 | 
            +
            description = "Github App Token"
         | 
| 48 | 
            +
            id = "Github App Token"
         | 
| 49 | 
            +
            keywords = ["ghu_", "ghs_"]
         | 
| 50 | 
            +
            regex = "(ghu|ghs)_[0-9a-zA-Z]{36}"
         | 
| 51 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 52 | 
            +
            [[rules]]
         | 
| 53 | 
            +
            description = "Github Refresh Token"
         | 
| 54 | 
            +
            id = "Github Refresh Token"
         | 
| 55 | 
            +
            keywords = ["ghr_"]
         | 
| 56 | 
            +
            regex = "ghr_[0-9a-zA-Z]{76}"
         | 
| 57 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 58 | 
            +
            [[rules]]
         | 
| 59 | 
            +
            description = "GitLab Personal Access Token"
         | 
| 60 | 
            +
            id = "gitlab_personal_access_token"
         | 
| 61 | 
            +
            keywords = ["glpat"]
         | 
| 62 | 
            +
            regex = "\\b(glpat-[0-9a-zA-Z_\\-]{20})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 63 | 
            +
            tags = ["gitlab", "revocation_type", "gitlab_blocking"]
         | 
| 64 | 
            +
            [[rules]]
         | 
| 65 | 
            +
            description = "GitLab Pipeline Trigger Token"
         | 
| 66 | 
            +
            id = "gitlab_pipeline_trigger_token"
         | 
| 67 | 
            +
            keywords = ["glptt"]
         | 
| 68 | 
            +
            regex = "\\b(glptt-[0-9a-zA-Z_\\-]{40})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 69 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 70 | 
            +
            [[rules]]
         | 
| 71 | 
            +
            description = "GitLab Runner Registration Token"
         | 
| 72 | 
            +
            id = "gitlab_runner_registration_token"
         | 
| 73 | 
            +
            keywords = ["GR1348941"]
         | 
| 74 | 
            +
            regex = "\\b(GR1348941[0-9a-zA-Z_\\-]{20})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 75 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 76 | 
            +
            [[rules]]
         | 
| 77 | 
            +
            description = "GitLab Runner Authentication Token"
         | 
| 78 | 
            +
            id = "gitlab_runner_auth_token"
         | 
| 79 | 
            +
            keywords = ["glrt"]
         | 
| 80 | 
            +
            regex = "\\b(glrt-[0-9a-zA-Z_\\-]{20})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 81 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 82 | 
            +
            [[rules]]
         | 
| 83 | 
            +
            description = "GitLab OAuth Application Secrets"
         | 
| 84 | 
            +
            id = "gitlab_oauth_app_secret"
         | 
| 85 | 
            +
            keywords = ["gloas"]
         | 
| 86 | 
            +
            regex = "\\b(gloas-[0-9a-zA-Z_\\-]{64})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 87 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 88 | 
            +
            [[rules]]
         | 
| 89 | 
            +
            description = "GitLab Feed token"
         | 
| 90 | 
            +
            id = "gitlab_feed_token_v2"
         | 
| 91 | 
            +
            keywords = ["glft"]
         | 
| 92 | 
            +
            regex = "\\b(glft-[0-9a-zA-Z_\\-]{20})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 93 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 94 | 
            +
            [[rules]]
         | 
| 95 | 
            +
            description = "GitLab Agent for Kubernetes token"
         | 
| 96 | 
            +
            id = "gitlab_kubernetes_agent_token"
         | 
| 97 | 
            +
            keywords = ["glagent"]
         | 
| 98 | 
            +
            regex = "\\b(glagent-[0-9a-zA-Z_\\-]{50})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 99 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 100 | 
            +
            [[rules]]
         | 
| 101 | 
            +
            description = "GitLab Incoming email token"
         | 
| 102 | 
            +
            id = "gitlab_incoming_email_token"
         | 
| 103 | 
            +
            keywords = ["glimt"]
         | 
| 104 | 
            +
            regex = "\\b(glimt-[0-9a-zA-Z_\\-]{25})(?:[[:punct:]]|[[:space:]]|[[:blank:]]|$)"
         | 
| 105 | 
            +
            tags = ["gitlab", "gitlab_blocking"]
         | 
| 106 | 
            +
            [[rules]]
         | 
| 107 | 
            +
            description = "Grafana API token"
         | 
| 108 | 
            +
            id = "Grafana API token"
         | 
| 109 | 
            +
            keywords = ["grafana"]
         | 
| 110 | 
            +
            regex = "['\\\"]eyJrIjoi(?i)[a-z0-9-_=]{72,92}['\\\"]"
         | 
| 111 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 112 | 
            +
            [[rules]]
         | 
| 113 | 
            +
            description = "Hashicorp Terraform user/org API token"
         | 
| 114 | 
            +
            id = "Hashicorp Terraform user/org API token"
         | 
| 115 | 
            +
            keywords = ["atlasv1", "hashicorp", "terraform"]
         | 
| 116 | 
            +
            regex = "['\\\"](?i)[a-z0-9]{14}\\.atlasv1\\.[a-z0-9-_=]{60,70}['\\\"]"
         | 
| 117 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 118 | 
            +
            [[rules]]
         | 
| 119 | 
            +
            description = "Hashicorp Vault batch token"
         | 
| 120 | 
            +
            id = "Hashicorp Vault batch token"
         | 
| 121 | 
            +
            keywords = ["hashicorp", "AAAAAQ", "vault"]
         | 
| 122 | 
            +
            regex = "b\\.AAAAAQ[0-9a-zA-Z_-]{156}"
         | 
| 123 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 124 | 
            +
            [[rules]]
         | 
| 125 | 
            +
            description = "Mailchimp API key"
         | 
| 126 | 
            +
            id = "Mailchimp API key"
         | 
| 127 | 
            +
            keywords = ["mailchimp"]
         | 
| 128 | 
            +
            regex = "(?i)(mailchimp[a-z0-9_ .\\-,]{0,25})(=|>|:=|\\|\\|:|<=|=>|:).{0,5}['\\\"]([a-f0-9]{32}-us20)['\\\"]"
         | 
| 129 | 
            +
            secretGroup = 3
         | 
| 130 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 131 | 
            +
            [[rules]]
         | 
| 132 | 
            +
            description = "Mailgun private API token"
         | 
| 133 | 
            +
            id = "Mailgun private API token"
         | 
| 134 | 
            +
            keywords = ["mailgun"]
         | 
| 135 | 
            +
            regex = "(?i)(mailgun[a-z0-9_ .\\-,]{0,25})(=|>|:=|\\|\\|:|<=|=>|:).{0,5}['\\\"](key-[a-f0-9]{32})['\\\"]"
         | 
| 136 | 
            +
            secretGroup = 3
         | 
| 137 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 138 | 
            +
            [[rules]]
         | 
| 139 | 
            +
            description = "Mailgun webhook signing key"
         | 
| 140 | 
            +
            id = "Mailgun webhook signing key"
         | 
| 141 | 
            +
            keywords = ["mailgun"]
         | 
| 142 | 
            +
            regex = "(?i)(mailgun[a-z0-9_ .\\-,]{0,25})(=|>|:=|\\|\\|:|<=|=>|:).{0,5}['\\\"]([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})['\\\"]"
         | 
| 143 | 
            +
            secretGroup = 3
         | 
| 144 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 145 | 
            +
            [[rules]]
         | 
| 146 | 
            +
            description = "New Relic user API Key"
         | 
| 147 | 
            +
            id = "New Relic user API Key"
         | 
| 148 | 
            +
            keywords = ["NRAK"]
         | 
| 149 | 
            +
            regex = "['\\\"](NRAK-[A-Z0-9]{27})['\\\"]"
         | 
| 150 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 151 | 
            +
            [[rules]]
         | 
| 152 | 
            +
            description = "New Relic user API ID"
         | 
| 153 | 
            +
            id = "New Relic user API ID"
         | 
| 154 | 
            +
            keywords = ["newrelic"]
         | 
| 155 | 
            +
            regex = "(?i)(newrelic[a-z0-9_ .\\-,]{0,25})(=|>|:=|\\|\\|:|<=|=>|:).{0,5}['\\\"]([A-Z0-9]{64})['\\\"]"
         | 
| 156 | 
            +
            secretGroup = 3
         | 
| 157 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 158 | 
            +
            [[rules]]
         | 
| 159 | 
            +
            description = "npm access token"
         | 
| 160 | 
            +
            id = "npm access token"
         | 
| 161 | 
            +
            keywords = ["npm_"]
         | 
| 162 | 
            +
            regex = "['\\\"](npm_(?i)[a-z0-9]{36})['\\\"]"
         | 
| 163 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 164 | 
            +
            [[rules]]
         | 
| 165 | 
            +
            description = "PyPI upload token"
         | 
| 166 | 
            +
            id = "PyPI upload token"
         | 
| 167 | 
            +
            keywords = ["pypi-AgEIcHlwaS5vcmc"]
         | 
| 168 | 
            +
            regex = "pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}"
         | 
| 169 | 
            +
            tags = ["pypi", "revocation_type", "gitlab_blocking"]
         | 
| 170 | 
            +
            [[rules]]
         | 
| 171 | 
            +
            description = "Rubygem API token"
         | 
| 172 | 
            +
            id = "Rubygem API token"
         | 
| 173 | 
            +
            keywords = ["rubygems_"]
         | 
| 174 | 
            +
            regex = "rubygems_[a-f0-9]{48}"
         | 
| 175 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 176 | 
            +
            [[rules]]
         | 
| 177 | 
            +
            description = "Segment Public API token"
         | 
| 178 | 
            +
            id = "Segment Public API token"
         | 
| 179 | 
            +
            keywords = ["sgp_"]
         | 
| 180 | 
            +
            regex = "sgp_[a-zA-Z0-9]{64}"
         | 
| 181 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 182 | 
            +
            [[rules]]
         | 
| 183 | 
            +
            description = "Sendgrid API token"
         | 
| 184 | 
            +
            id = "Sendgrid API token"
         | 
| 185 | 
            +
            keywords = ["sendgrid"]
         | 
| 186 | 
            +
            regex = "SG\\.(?i)[a-z0-9_\\-\\.]{66}"
         | 
| 187 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 188 | 
            +
            [[rules]]
         | 
| 189 | 
            +
            description = "Shopify shared secret"
         | 
| 190 | 
            +
            id = "Shopify shared secret"
         | 
| 191 | 
            +
            keywords = ["shpss_"]
         | 
| 192 | 
            +
            regex = "shpss_[a-fA-F0-9]{32}"
         | 
| 193 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 194 | 
            +
            [[rules]]
         | 
| 195 | 
            +
            description = "Shopify access token"
         | 
| 196 | 
            +
            id = "Shopify access token"
         | 
| 197 | 
            +
            keywords = ["shpat_"]
         | 
| 198 | 
            +
            regex = "shpat_[a-fA-F0-9]{32}"
         | 
| 199 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 200 | 
            +
            [[rules]]
         | 
| 201 | 
            +
            description = "Shopify custom app access token"
         | 
| 202 | 
            +
            id = "Shopify custom app access token"
         | 
| 203 | 
            +
            keywords = ["shpca_"]
         | 
| 204 | 
            +
            regex = "shpca_[a-fA-F0-9]{32}"
         | 
| 205 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 206 | 
            +
            [[rules]]
         | 
| 207 | 
            +
            description = "Shopify private app access token"
         | 
| 208 | 
            +
            id = "Shopify private app access token"
         | 
| 209 | 
            +
            keywords = ["shppa_"]
         | 
| 210 | 
            +
            regex = "shppa_[a-fA-F0-9]{32}"
         | 
| 211 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 212 | 
            +
            [[rules]]
         | 
| 213 | 
            +
            description = "Slack token"
         | 
| 214 | 
            +
            id = "Slack token"
         | 
| 215 | 
            +
            keywords = ["xoxb", "xoxa", "xoxp", "xoxr", "xoxs"]
         | 
| 216 | 
            +
            regex = "xox[baprs]-([0-9a-zA-Z]{10,48})"
         | 
| 217 | 
            +
            tags = ["gitlab_blocking"]
         | 
| 218 | 
            +
            [[rules]]
         | 
| 219 | 
            +
            description = "Stripe"
         | 
| 220 | 
            +
            id = "Stripe"
         | 
| 221 | 
            +
            keywords = ["sk_test", "pk_test", "sk_live", "pk_live"]
         | 
| 222 | 
            +
            regex = "(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}"
         | 
| 223 | 
            +
            tags = ["gitlab_blocking"]
         | 
| @@ -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 | 
| 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 | 
            -
                       | 
| 66 | 
            -
             | 
| 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 | 
            -
                           | 
| 69 | 
            +
                          exclusions[:raw] << exclusion
         | 
| 72 70 | 
             
                        when :EXCLUSION_TYPE_RULE
         | 
| 73 | 
            -
                           | 
| 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 | 
            -
                           | 
| 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. | 
| 4 | 
            +
              version: 0.14.1
         | 
| 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- | 
| 13 | 
            +
            date: 2024-12-17 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: grpc
         | 
| @@ -103,6 +103,7 @@ files: | |
| 103 103 | 
             
            - lib/gitlab/secret_detection/core/response.rb
         | 
| 104 104 | 
             
            - lib/gitlab/secret_detection/core/ruleset.rb
         | 
| 105 105 | 
             
            - lib/gitlab/secret_detection/core/scanner.rb
         | 
| 106 | 
            +
            - lib/gitlab/secret_detection/core/secret_push_protection_rules.toml
         | 
| 106 107 | 
             
            - lib/gitlab/secret_detection/core/status.rb
         | 
| 107 108 | 
             
            - lib/gitlab/secret_detection/grpc.rb
         | 
| 108 109 | 
             
            - lib/gitlab/secret_detection/grpc/client/grpc_client.rb
         |