Module: Vmpooler::API::InputValidator
- Included in:
- Helpers
- Defined in:
- lib/vmpooler/api/input_validator.rb
Overview
Input validation helpers to enhance security
Defined Under Namespace
Classes: ValidationError
Constant Summary collapse
- MAX_HOSTNAME_LENGTH =
Maximum lengths to prevent abuse
253- MAX_TAG_KEY_LENGTH =
50- MAX_TAG_VALUE_LENGTH =
255- MAX_REASON_LENGTH =
500- MAX_POOL_NAME_LENGTH =
100- MAX_TOKEN_LENGTH =
64- HOSTNAME_PATTERN =
Valid patterns
/\A[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)* \z/ix.freeze
- POOL_NAME_PATTERN =
/\A[a-zA-Z0-9_-]+\z/.freeze
- TAG_KEY_PATTERN =
/\A[a-zA-Z0-9_\-.]+\z/.freeze
- TOKEN_PATTERN =
/\A[a-zA-Z0-9\-_]+\z/.freeze
- INTEGER_PATTERN =
/\A\d+\z/.freeze
Instance Method Summary collapse
-
#sanitize_json_body(body) ⇒ Object
Sanitize JSON body to prevent injection.
-
#validate_disk_size(size) ⇒ Object
Validate disk size.
-
#validate_hostname(hostname) ⇒ Object
Validate hostname format and length.
-
#validate_integer(value, name = 'value', min: nil, max: nil) ⇒ Object
Validate integer parameter.
-
#validate_lifetime(lifetime) ⇒ Object
Validate lifetime (TTL) in hours.
-
#validate_pool_name(pool_name) ⇒ Object
Validate pool/template name.
-
#validate_reason(reason) ⇒ Object
Validate reason text.
-
#validate_tag(key, value) ⇒ Object
Validate tag key and value.
-
#validate_token_format(token) ⇒ Object
Validate token format.
-
#validate_vm_count(count) ⇒ Object
Validate VM request count.
-
#validation_error?(result) ⇒ Boolean
Check if validation result is an error.
Instance Method Details
#sanitize_json_body(body) ⇒ Object
Sanitize JSON body to prevent injection
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/vmpooler/api/input_validator.rb', line 119 def sanitize_json_body(body) return {} if body.nil? || body.empty? begin parsed = JSON.parse(body) return error_response('Request body must be a JSON object') unless parsed.is_a?(Hash) # Limit depth and size to prevent DoS return error_response('Request body too complex') if json_depth(parsed) > 5 return error_response('Request body too large') if body.length > 10_240 # 10KB max parsed rescue JSON::ParserError => e error_response("Invalid JSON: #{e.}") end end |
#validate_disk_size(size) ⇒ Object
Validate disk size
91 92 93 94 95 96 |
# File 'lib/vmpooler/api/input_validator.rb', line 91 def validate_disk_size(size) validated = validate_integer(size, 'Disk size', min: 1, max: 2048) return validated if validated.is_a?(Hash) # error response validated end |
#validate_hostname(hostname) ⇒ Object
Validate hostname format and length
25 26 27 28 29 30 31 |
# File 'lib/vmpooler/api/input_validator.rb', line 25 def validate_hostname(hostname) return error_response('Hostname is required') if hostname.nil? || hostname.empty? return error_response('Hostname too long') if hostname.length > MAX_HOSTNAME_LENGTH return error_response('Invalid hostname format') unless hostname.match?(HOSTNAME_PATTERN) true end |
#validate_integer(value, name = 'value', min: nil, max: nil) ⇒ Object
Validate integer parameter
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/vmpooler/api/input_validator.rb', line 69 def validate_integer(value, name = 'value', min: nil, max: nil) return error_response("#{name} is required") if value.nil? value_str = value.to_s return error_response("#{name} must be a valid integer") unless value_str.match?(INTEGER_PATTERN) int_value = value.to_i return error_response("#{name} must be at least #{min}") if min && int_value < min return error_response("#{name} must be at most #{max}") if max && int_value > max int_value end |
#validate_lifetime(lifetime) ⇒ Object
Validate lifetime (TTL) in hours
99 100 101 102 103 104 |
# File 'lib/vmpooler/api/input_validator.rb', line 99 def validate_lifetime(lifetime) validated = validate_integer(lifetime, 'Lifetime', min: 1, max: 168) # max 1 week return validated if validated.is_a?(Hash) # error response validated end |
#validate_pool_name(pool_name) ⇒ Object
Validate pool/template name
34 35 36 37 38 39 40 |
# File 'lib/vmpooler/api/input_validator.rb', line 34 def validate_pool_name(pool_name) return error_response('Pool name is required') if pool_name.nil? || pool_name.empty? return error_response('Pool name too long') if pool_name.length > MAX_POOL_NAME_LENGTH return error_response('Invalid pool name format') unless pool_name.match?(POOL_NAME_PATTERN) true end |
#validate_reason(reason) ⇒ Object
Validate reason text
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/vmpooler/api/input_validator.rb', line 107 def validate_reason(reason) return true if reason.nil? || reason.empty? return error_response('Reason too long') if reason.length > MAX_REASON_LENGTH # Sanitize to prevent XSS/injection sanitized = reason.gsub(/[<>"']/, '') return error_response('Reason contains invalid characters') if sanitized != reason true end |
#validate_tag(key, value) ⇒ Object
Validate tag key and value
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/vmpooler/api/input_validator.rb', line 43 def validate_tag(key, value) return error_response('Tag key is required') if key.nil? || key.empty? return error_response('Tag key too long') if key.length > MAX_TAG_KEY_LENGTH return error_response('Invalid tag key format') unless key.match?(TAG_KEY_PATTERN) if value return error_response('Tag value too long') if value.length > MAX_TAG_VALUE_LENGTH # Sanitize value to prevent injection attacks sanitized_value = value.gsub(/[^\w\s\-.@:\/]/, '') return error_response('Tag value contains invalid characters') if sanitized_value != value end true end |
#validate_token_format(token) ⇒ Object
Validate token format
60 61 62 63 64 65 66 |
# File 'lib/vmpooler/api/input_validator.rb', line 60 def validate_token_format(token) return error_response('Token is required') if token.nil? || token.empty? return error_response('Token too long') if token.length > MAX_TOKEN_LENGTH return error_response('Invalid token format') unless token.match?(TOKEN_PATTERN) true end |
#validate_vm_count(count) ⇒ Object
Validate VM request count
83 84 85 86 87 88 |
# File 'lib/vmpooler/api/input_validator.rb', line 83 def validate_vm_count(count) validated = validate_integer(count, 'VM count', min: 1, max: 100) return validated if validated.is_a?(Hash) # error response validated end |
#validation_error?(result) ⇒ Boolean
Check if validation result is an error
137 138 139 |
# File 'lib/vmpooler/api/input_validator.rb', line 137 def validation_error?(result) result.is_a?(Hash) && result['ok'] == false end |