Class: Msf::DBManager::Import::MarshalValidator
- Inherits:
-
Object
- Object
- Msf::DBManager::Import::MarshalValidator
- Defined in:
- lib/msf/core/db_manager/import/marshal_validator.rb
Overview
Walks a Marshal byte stream structurally, reading type bytes only in type positions and skipping over data payloads. Rejects any stream that attempts to instantiate a named class (object, struct, custom marshal, module extension, etc.).
This runs BEFORE Marshal.load so no objects are ever instantiated from an unsafe payload.
Reference: ruby-doc.org/3.3/Marshal.html Reference: github.com/ruby/ruby/blob/master/doc/marshal/marshal.md
Constant Summary collapse
- UNSAFE_TYPES =
Type bytes that always instantiate named classes — unconditionally blocked.
Set.new(%w[o c m C S e U d].map(&:ord)).freeze
- DEFAULT_PERMITTED_CLASSES =
Default classes permitted for the ‘u’ (_dump/_load) serialization type.
%w[].freeze
Class Method Summary collapse
-
.marshalled_data?(data) ⇒ Boolean
Check whether the given data starts with the Marshal 4.8 version header, indicating it is a Marshal-serialized payload.
-
.safe_load(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) ⇒ Object
Convenience method: validate and then load.
Instance Method Summary collapse
-
#initialize(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) ⇒ MarshalValidator
constructor
A new instance of MarshalValidator.
-
#validate! ⇒ true
Validate the entire stream.
Constructor Details
#initialize(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) ⇒ MarshalValidator
Returns a new instance of MarshalValidator.
32 33 34 35 36 |
# File 'lib/msf/core/db_manager/import/marshal_validator.rb', line 32 def initialize(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) @bytes = data.bytes @pos = 0 @permitted_classes = Set.new(permitted_classes) end |
Class Method Details
.marshalled_data?(data) ⇒ Boolean
Check whether the given data starts with the Marshal 4.8 version header, indicating it is a Marshal-serialized payload.
62 63 64 |
# File 'lib/msf/core/db_manager/import/marshal_validator.rb', line 62 def self.marshalled_data?(data) data.length >= 2 && data.getbyte(0) == 4 && data.getbyte(1) == 8 end |
.safe_load(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) ⇒ Object
Convenience method: validate and then load.
52 53 54 55 |
# File 'lib/msf/core/db_manager/import/marshal_validator.rb', line 52 def self.safe_load(data, permitted_classes: DEFAULT_PERMITTED_CLASSES) new(data, permitted_classes: permitted_classes).validate! Marshal.load(data) end |
Instance Method Details
#validate! ⇒ true
Validate the entire stream. Raises MarshalValidationError if unsafe.
40 41 42 43 44 |
# File 'lib/msf/core/db_manager/import/marshal_validator.rb', line 40 def validate! read_version validate_value true end |