Class: WSDL::Limits

Inherits:
Object
  • Object
show all
Defined in:
lib/wsdl/limits.rb

Overview

Configuration for resource limits to prevent denial-of-service attacks.

This class provides sensible defaults that work for most WSDL documents while protecting against malicious or malformed documents that could exhaust system resources.

The library already protects against XXE, SSRF, and path traversal attacks. These limits add protection against resource exhaustion attacks.

Examples:

Using default limits

client = WSDL::Client.new('http://example.com/service?wsdl')
# Uses WSDL.limits by default

Customizing limits globally

WSDL.limits = WSDL::Limits.new(max_document_size: 20 * 1024 * 1024)

Customizing limits per-client

custom_limits = WSDL.limits.with(max_schemas: 100)
client = WSDL::Client.new('http://example.com/service?wsdl', limits: custom_limits)

Disabling a specific limit

unlimited_schemas = WSDL.limits.with(max_schemas: nil)

Constant Summary collapse

DEFAULT_MAX_DOCUMENT_SIZE =

Default maximum size for a single WSDL or schema document (10 MB).

10 * 1024 * 1024
DEFAULT_MAX_TOTAL_DOWNLOAD_SIZE =

Default maximum cumulative bytes downloaded across all documents (50 MB).

50 * 1024 * 1024
DEFAULT_MAX_SCHEMAS =

Default maximum number of schema definitions allowed.

50
DEFAULT_MAX_ELEMENTS_PER_TYPE =

Default maximum child elements in a complex type.

500
DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT =

Default maximum attributes on an XML element.

100
DEFAULT_MAX_TYPE_NESTING_DEPTH =

Default maximum depth of type inheritance/nesting.

50
DEFAULT_MAX_REQUEST_ELEMENTS =

Default maximum total elements in request envelope construction.

10_000
DEFAULT_MAX_REQUEST_DEPTH =

Default maximum request envelope nesting depth.

100
DEFAULT_MAX_REQUEST_ATTRIBUTES =

Default maximum total attributes in request envelope construction.

1_000
DEFAULT_MAX_SCHEMA_IMPORT_ITERATIONS =

Default maximum iterations for resolving schema imports and includes.

100
DEFAULT_MAX_RESPONSE_SIZE =

Default maximum size for a SOAP response body (10 MB).

10 * 1024 * 1024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_document_size: DEFAULT_MAX_DOCUMENT_SIZE, max_total_download_size: DEFAULT_MAX_TOTAL_DOWNLOAD_SIZE, max_schemas: DEFAULT_MAX_SCHEMAS, max_elements_per_type: DEFAULT_MAX_ELEMENTS_PER_TYPE, max_attributes_per_element: DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT, max_type_nesting_depth: DEFAULT_MAX_TYPE_NESTING_DEPTH, max_request_elements: DEFAULT_MAX_REQUEST_ELEMENTS, max_request_depth: DEFAULT_MAX_REQUEST_DEPTH, max_request_attributes: DEFAULT_MAX_REQUEST_ATTRIBUTES, max_schema_import_iterations: DEFAULT_MAX_SCHEMA_IMPORT_ITERATIONS, max_response_size: DEFAULT_MAX_RESPONSE_SIZE) ⇒ Limits

Creates a new Limits instance with the specified resource limits.

rubocop:disable Metrics/ParameterLists

Parameters:

  • max_document_size (Integer, nil) (defaults to: DEFAULT_MAX_DOCUMENT_SIZE)

    maximum size in bytes for a single WSDL/schema document. Set to nil to disable this limit. Default: 10 MB.

  • max_total_download_size (Integer, nil) (defaults to: DEFAULT_MAX_TOTAL_DOWNLOAD_SIZE)

    maximum cumulative bytes downloaded across all WSDL and schema documents. Set to nil to disable. Default: 50 MB.

  • max_schemas (Integer, nil) (defaults to: DEFAULT_MAX_SCHEMAS)

    maximum number of schema definitions allowed. Set to nil to disable. Default: 50.

  • max_elements_per_type (Integer, nil) (defaults to: DEFAULT_MAX_ELEMENTS_PER_TYPE)

    maximum child elements in a complex type. Set to nil to disable. Default: 500.

  • max_attributes_per_element (Integer, nil) (defaults to: DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT)

    maximum attributes on an XML element. Set to nil to disable. Default: 100.

  • max_type_nesting_depth (Integer, nil) (defaults to: DEFAULT_MAX_TYPE_NESTING_DEPTH)

    maximum depth of type inheritance/nesting. Set to nil to disable. Default: 50.

  • max_request_elements (Integer, nil) (defaults to: DEFAULT_MAX_REQUEST_ELEMENTS)

    maximum total elements allowed in request envelope. Set to nil to disable. Default: 10,000.

  • max_request_depth (Integer, nil) (defaults to: DEFAULT_MAX_REQUEST_DEPTH)

    maximum request envelope nesting depth. Set to nil to disable. Default: 100.

  • max_request_attributes (Integer, nil) (defaults to: DEFAULT_MAX_REQUEST_ATTRIBUTES)

    maximum total attributes in request envelope. Set to nil to disable. Default: 1,000.

  • max_schema_import_iterations (Integer, nil) (defaults to: DEFAULT_MAX_SCHEMA_IMPORT_ITERATIONS)

    maximum iterations for resolving schema imports and includes. Set to nil to disable. Default: 100.

  • max_response_size (Integer, nil) (defaults to: DEFAULT_MAX_RESPONSE_SIZE)

    maximum size in bytes for a SOAP response body. Set to nil to disable this limit. Default: 10 MB.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/wsdl/limits.rb', line 87

def initialize(
  max_document_size: DEFAULT_MAX_DOCUMENT_SIZE,
  max_total_download_size: DEFAULT_MAX_TOTAL_DOWNLOAD_SIZE,
  max_schemas: DEFAULT_MAX_SCHEMAS,
  max_elements_per_type: DEFAULT_MAX_ELEMENTS_PER_TYPE,
  max_attributes_per_element: DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT,
  max_type_nesting_depth: DEFAULT_MAX_TYPE_NESTING_DEPTH,
  max_request_elements: DEFAULT_MAX_REQUEST_ELEMENTS,
  max_request_depth: DEFAULT_MAX_REQUEST_DEPTH,
  max_request_attributes: DEFAULT_MAX_REQUEST_ATTRIBUTES,
  max_schema_import_iterations: DEFAULT_MAX_SCHEMA_IMPORT_ITERATIONS,
  max_response_size: DEFAULT_MAX_RESPONSE_SIZE
)
  # rubocop:enable Metrics/ParameterLists
  @max_document_size = max_document_size
  @max_total_download_size = max_total_download_size
  @max_schemas = max_schemas
  @max_elements_per_type = max_elements_per_type
  @max_attributes_per_element = max_attributes_per_element
  @max_type_nesting_depth = max_type_nesting_depth
  @max_request_elements = max_request_elements
  @max_request_depth = max_request_depth
  @max_request_attributes = max_request_attributes
  @max_schema_import_iterations = max_schema_import_iterations
  @max_response_size = max_response_size

  freeze
end

Instance Attribute Details

#max_attributes_per_elementInteger? (readonly)

Returns maximum attributes on an XML element.

Returns:

  • (Integer, nil)

    maximum attributes on an XML element



129
130
131
# File 'lib/wsdl/limits.rb', line 129

def max_attributes_per_element
  @max_attributes_per_element
end

#max_document_sizeInteger? (readonly)

Returns maximum size in bytes for a single WSDL/schema document.

Returns:

  • (Integer, nil)

    maximum size in bytes for a single WSDL/schema document



117
118
119
# File 'lib/wsdl/limits.rb', line 117

def max_document_size
  @max_document_size
end

#max_elements_per_typeInteger? (readonly)

Returns maximum child elements in a complex type.

Returns:

  • (Integer, nil)

    maximum child elements in a complex type



126
127
128
# File 'lib/wsdl/limits.rb', line 126

def max_elements_per_type
  @max_elements_per_type
end

#max_request_attributesInteger? (readonly)

Returns maximum total attributes in request envelope.

Returns:

  • (Integer, nil)

    maximum total attributes in request envelope



141
142
143
# File 'lib/wsdl/limits.rb', line 141

def max_request_attributes
  @max_request_attributes
end

#max_request_depthInteger? (readonly)

Returns maximum request envelope nesting depth.

Returns:

  • (Integer, nil)

    maximum request envelope nesting depth



138
139
140
# File 'lib/wsdl/limits.rb', line 138

def max_request_depth
  @max_request_depth
end

#max_request_elementsInteger? (readonly)

Returns maximum total elements in request envelope.

Returns:

  • (Integer, nil)

    maximum total elements in request envelope



135
136
137
# File 'lib/wsdl/limits.rb', line 135

def max_request_elements
  @max_request_elements
end

#max_response_sizeInteger? (readonly)

Returns maximum size in bytes for a SOAP response body.

Returns:

  • (Integer, nil)

    maximum size in bytes for a SOAP response body



147
148
149
# File 'lib/wsdl/limits.rb', line 147

def max_response_size
  @max_response_size
end

#max_schema_import_iterationsInteger? (readonly)

Returns maximum iterations for resolving schema imports and includes.

Returns:

  • (Integer, nil)

    maximum iterations for resolving schema imports and includes



144
145
146
# File 'lib/wsdl/limits.rb', line 144

def max_schema_import_iterations
  @max_schema_import_iterations
end

#max_schemasInteger? (readonly)

Returns maximum number of schema definitions.

Returns:

  • (Integer, nil)

    maximum number of schema definitions



123
124
125
# File 'lib/wsdl/limits.rb', line 123

def max_schemas
  @max_schemas
end

#max_total_download_sizeInteger? (readonly)

Returns maximum cumulative bytes downloaded.

Returns:

  • (Integer, nil)

    maximum cumulative bytes downloaded



120
121
122
# File 'lib/wsdl/limits.rb', line 120

def max_total_download_size
  @max_total_download_size
end

#max_type_nesting_depthInteger? (readonly)

Returns maximum depth of type inheritance/nesting.

Returns:

  • (Integer, nil)

    maximum depth of type inheritance/nesting



132
133
134
# File 'lib/wsdl/limits.rb', line 132

def max_type_nesting_depth
  @max_type_nesting_depth
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Checks equality with another Limits instance.

Parameters:

  • other (Object)

    the object to compare

Returns:

  • (Boolean)

    true if equal



234
235
236
237
238
# File 'lib/wsdl/limits.rb', line 234

def ==(other)
  return false unless other.is_a?(Limits)

  to_h == other.to_h
end

#hashInteger

Returns a hash code for use in Hash keys.

Returns:

  • (Integer)

    the hash code



246
247
248
# File 'lib/wsdl/limits.rb', line 246

def hash
  to_h.hash
end

#inspectString

Returns a human-readable string representation.

Returns:

  • (String)

    the limits formatted for display



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/wsdl/limits.rb', line 211

def inspect
  parts = {
    max_document_size: Formatting.format_bytes(@max_document_size),
    max_total_download_size: Formatting.format_bytes(@max_total_download_size),
    max_schemas: limit_value(@max_schemas),
    max_elements_per_type: limit_value(@max_elements_per_type),
    max_attributes_per_element: limit_value(@max_attributes_per_element),
    max_type_nesting_depth: limit_value(@max_type_nesting_depth),
    max_request_elements: limit_value(@max_request_elements),
    max_request_depth: limit_value(@max_request_depth),
    max_request_attributes: limit_value(@max_request_attributes),
    max_schema_import_iterations: limit_value(@max_schema_import_iterations),
    max_response_size: Formatting.format_bytes(@max_response_size)
  }.map { |key, value| "#{key}=#{value}" }.join(' ')

  "#<#{self.class.name} #{parts}>"
end

#to_hHash{Symbol => Integer, nil}

Returns a hash representation of the limits.

Returns:

  • (Hash{Symbol => Integer, nil})

    the limits as a hash



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/wsdl/limits.rb', line 191

def to_h
  {
    max_document_size: @max_document_size,
    max_total_download_size: @max_total_download_size,
    max_schemas: @max_schemas,
    max_elements_per_type: @max_elements_per_type,
    max_attributes_per_element: @max_attributes_per_element,
    max_type_nesting_depth: @max_type_nesting_depth,
    max_request_elements: @max_request_elements,
    max_request_depth: @max_request_depth,
    max_request_attributes: @max_request_attributes,
    max_schema_import_iterations: @max_schema_import_iterations,
    max_response_size: @max_response_size
  }
end

#with(**options) ⇒ Limits

Creates a new Limits instance with some values changed.

Examples:

Increase document size limit

new_limits = limits.with(max_document_size: 20 * 1024 * 1024)

Disable schema count limit

new_limits = limits.with(max_schemas: nil)

Parameters:

  • options (Hash)

    the limits to override

Options Hash (**options):

  • :max_document_size (Integer, nil)
  • :max_total_download_size (Integer, nil)
  • :max_schemas (Integer, nil)
  • :max_elements_per_type (Integer, nil)
  • :max_attributes_per_element (Integer, nil)
  • :max_type_nesting_depth (Integer, nil)
  • :max_request_elements (Integer, nil)
  • :max_request_depth (Integer, nil)
  • :max_request_attributes (Integer, nil)
  • :max_schema_import_iterations (Integer, nil)
  • :max_response_size (Integer, nil)

Returns:

  • (Limits)

    a new Limits instance with the specified changes



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/wsdl/limits.rb', line 171

def with(**options)
  self.class.new(
    max_document_size: options.fetch(:max_document_size, @max_document_size),
    max_total_download_size: options.fetch(:max_total_download_size, @max_total_download_size),
    max_schemas: options.fetch(:max_schemas, @max_schemas),
    max_elements_per_type: options.fetch(:max_elements_per_type, @max_elements_per_type),
    max_attributes_per_element: options.fetch(:max_attributes_per_element, @max_attributes_per_element),
    max_type_nesting_depth: options.fetch(:max_type_nesting_depth, @max_type_nesting_depth),
    max_request_elements: options.fetch(:max_request_elements, @max_request_elements),
    max_request_depth: options.fetch(:max_request_depth, @max_request_depth),
    max_request_attributes: options.fetch(:max_request_attributes, @max_request_attributes),
    max_schema_import_iterations: options.fetch(:max_schema_import_iterations, @max_schema_import_iterations),
    max_response_size: options.fetch(:max_response_size, @max_response_size)
  )
end