Class: Gitlab::Middleware::JsonValidation
- Inherits:
-
Object
- Object
- Gitlab::Middleware::JsonValidation
- Defined in:
- lib/gitlab/middleware/json_validation.rb
Overview
JsonValidation middleware provides JSON request validation with configurable limits.
Features:
-
Global validation limits for all JSON requests
-
Route-specific limits that override global defaults for matching paths
-
Multiple validation modes: :enforced, :logging, :disabled
-
Configurable limits for depth, array size, hash size, total elements, and body size
Constant Summary collapse
- RACK_ENV_METADATA_KEY =
"gitlab.json.validation.metadata"- COLLECT_EVENTS_PATH =
%r{ \A/-/collect_events\z }xi
- TERRAFORM_STATE_PATH =
%r{ \A/api/v4/projects/ (?<id> [a-zA-Z0-9%-._]{1,255} )/terraform/state/ }xi
- NPM_INSTANCE_PACKAGES_PATH =
%r{ \A/api/v4/packages/npm/-/npm/v1/security/ (?:(?:advisories/bulk)|(?:audits/quick))\z }xi
- NPM_GROUP_PACKAGES_PATH =
%r{ \A/api/v4/groups/ (?<id> [a-zA-Z0-9%-._]{1,255} )/-/packages/npm/-/npm/v1/security/ (?:(?:advisories/bulk)|(?:audits/quick))\z }xi
- NPM_PROJECT_PACKAGES_PATH =
%r{ \A/api/v4/projects/ (?<id> [a-zA-Z0-9%-._]{1,255} )/packages/npm/-/npm/v1/security/ (?:(?:advisories/bulk)|(?:audits/quick))\z }xi
- INTERNAL_API_PATH =
%r{ \A/api/v4/internal/ }xi
- DUO_WORKFLOW_PATH =
%r{ \A/api/v4/ai/duo_workflows/workflows/ }xi
- DEFAULT_LIMITS =
{ # Rack::Utils uses a depth of 32 by default max_depth: ENV.fetch('GITLAB_JSON_MAX_DEPTH', 32).to_i, max_array_size: ENV.fetch('GITLAB_JSON_MAX_ARRAY_SIZE', 50000).to_i, max_hash_size: ENV.fetch('GITLAB_JSON_MAX_HASH_SIZE', 50000).to_i, max_total_elements: ENV.fetch('GITLAB_JSON_MAX_TOTAL_ELEMENTS', 100000).to_i, # Disabled by default because some endpoints upload large payloads max_json_size_bytes: ENV.fetch('GITLAB_JSON_MAX_JSON_SIZE_BYTES', 0).to_i, # Supported modes: enforced, disabled, logging mode: ENV.fetch('GITLAB_JSON_VALIDATION_MODE', 'enforced').downcase.to_sym }.freeze
- ROUTE_CONFIGS =
[ # Stricter limits for collect_events endpoint { regex: COLLECT_EVENTS_PATH, methods: i[post], limits: DEFAULT_LIMITS.merge({ max_json_size_bytes: 10.megabytes }) }, # The application setting max_terraform_state_size_bytes limits this file size already { regex: TERRAFORM_STATE_PATH, methods: i[post], limits: { max_depth: 64, max_array_size: 50000, max_hash_size: 50000, max_total_elements: 250000, max_json_size_bytes: 50.megabytes, mode: :logging } }, # CompressedJson middleware limits NPM sizes already { regex: NPM_INSTANCE_PACKAGES_PATH, methods: i[post], limits: { max_depth: 32, max_array_size: 50000, max_hash_size: 50000, max_total_elements: 250000, max_json_size_bytes: 50.megabytes, mode: :enforced } }, { regex: NPM_GROUP_PACKAGES_PATH, methods: i[post], limits: { max_depth: 32, max_array_size: 50000, max_hash_size: 50000, max_total_elements: 250000, max_json_size_bytes: 50.megabytes, mode: :enforced } }, { regex: NPM_PROJECT_PACKAGES_PATH, methods: i[post], limits: { max_depth: 32, max_array_size: 50000, max_hash_size: 50000, max_total_elements: 250000, max_json_size_bytes: 50.megabytes, mode: :enforced } }, # Internal APIs { regex: INTERNAL_API_PATH, methods: i[post], limits: { max_depth: 32, max_array_size: 50000, max_hash_size: 50000, max_total_elements: 0, # Regularly exceeds 10,000, disable for now max_json_size_bytes: 10.megabytes, mode: :enforced } }, # Duo Workflow API { regex: DUO_WORKFLOW_PATH, methods: i[post], limits: { max_depth: 32, max_array_size: 5000, max_hash_size: 5000, max_total_elements: 0, # Regularly exceeds 10,000, disable for now max_json_size_bytes: 25.megabytes, mode: :enforced } } ].freeze
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, options = {}) ⇒ JsonValidation
constructor
A new instance of JsonValidation.
Constructor Details
#initialize(app, options = {}) ⇒ JsonValidation
Returns a new instance of JsonValidation.
154 155 156 157 158 |
# File 'lib/gitlab/middleware/json_validation.rb', line 154 def initialize(app, = {}) @app = app @default_limits = [:default_limits] ? DEFAULT_LIMITS.merge([:default_limits]) : DEFAULT_LIMITS @route_config_map = build_route_config_map([:route_limits]) end |
Instance Method Details
#call(env) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/gitlab/middleware/json_validation.rb', line 160 def call(env) return @app.call(env) if global_disabled? request = Rack::Request.new(env) return @app.call(env) unless json_request?(request) limits = limits_for_request(request) return @app.call(env) if disabled_mode?(limits) allow_if_validated(env, request, limits) end |