{"record":{"id":"29bd4f4b24569b5d","repo":"puppetlabs/puppet","slug":"invalid-sid-29bd4f","errorCode":null,"errorMessage":"Invalid SID","messagePattern":"Invalid SID","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/sid.rb","lineNumber":163,"sourceCode":"          sid_bytes = ptr.read_array_of_uchar(get_length_sid(ptr))\n        end\n      rescue Puppet::Util::Windows::Error => e\n        raise if e.code != ERROR_INVALID_SID_STRUCTURE\n      end\n\n      Principal.lookup_account_sid(sid_bytes).domain_account\n    rescue\n      nil\n    end\n    module_function :sid_to_name\n\n    # https://stackoverflow.com/a/1792930 - 68 bytes, 184 characters in a string\n    MAXIMUM_SID_STRING_LENGTH = 184\n\n    # Convert a SID pointer to a SID string, e.g. \"S-1-5-32-544\".\n    def sid_ptr_to_string(psid)\n      if !psid.is_a?(FFI::Pointer) || IsValidSid(psid) == FFI::WIN32_FALSE\n        raise Puppet::Util::Windows::Error, _(\"Invalid SID\")\n      end\n\n      sid_string = nil\n      FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr|\n        if ConvertSidToStringSidW(psid, buffer_ptr) == FFI::WIN32_FALSE\n          raise Puppet::Util::Windows::Error, _(\"Failed to convert binary SID\")\n        end\n\n        buffer_ptr.read_win32_local_pointer do |wide_string_ptr|\n          if wide_string_ptr.null?\n            raise Puppet::Error, _(\"ConvertSidToStringSidW failed to allocate buffer for sid\")\n          end\n\n          sid_string = wide_string_ptr.read_arbitrary_wide_string_up_to(MAXIMUM_SID_STRING_LENGTH)\n        end\n      end\n\n      sid_string","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/sid.rb#L145-L181","documentation":"Raised by Puppet::Util::Windows::SID.sid_ptr_to_string when the argument is not an FFI::Pointer or IsValidSid rejects the binary SID at that address (malformed Revision, SubAuthorityCount, or IdentifierAuthority). The method otherwise converts the binary SID to string form ('S-1-5-32-544') via ConvertSidToStringSidW. This is a data validation failure on the in-memory SID structure.","triggerScenarios":"Passing a Ruby String or Array of bytes instead of an FFI::Pointer; reading a SID from a struct/buffer with the wrong offset or truncated length so the bytes at the address are not a valid SID; using a freed FFI::MemoryPointer after its block exited (dangling pointer).","commonSituations":"Hand-rolled FFI code parsing TOKEN_USER or SECURITY_DESCRIPTOR buffers with wrong offsets; SIDs copied byte-wise into an undersized buffer; memory blocks used after the MemoryPointer block closes; misuse where octet_string_to_sid_string (which takes byte arrays) was the intended entry point.","solutions":["Use the higher-level helper for byte arrays: Puppet::Util::Windows::SID.octet_string_to_sid_string(bytes) instead of a raw pointer.","Ensure the pointer is an FFI::Pointer still alive in scope (keep the MemoryPointer block open while reading).","Verify offset/length when extracting SIDs from structs (GetSidSubAuthorityCount, GetLengthSid) before converting.","Dump the bytes (ptr.read_bytes(GetLengthSid(ptr))) and check Revision (first byte == 1) and sane SubAuthorityCount (<= 15)."],"exampleFix":"# before\nsid_string = Puppet::Util::Windows::SID.sid_ptr_to_string(sid_bytes) # sid_bytes is an Array\n\n# after\nsid_string = Puppet::Util::Windows::SID.octet_string_to_sid_string(sid_bytes)","handlingStrategy":"type-guard","validationCode":"# simplest pre-check: pointer is alive and the bytes look like a SID\nok = ptr.is_a?(FFI::Pointer) && !ptr.null? && ptr.read_uint8 == 1 && ptr.get_uint8(1) <= 15\nraise ArgumentError, 'not a valid SID pointer' unless ok","typeGuard":"def sid_pointer?(obj)\n  obj.is_a?(FFI::Pointer) && !obj.null?\nend\n\nraise TypeError, 'expected FFI::Pointer to a SID' unless sid_pointer?(ptr)","tryCatchPattern":"begin\n  Puppet::Util::Windows::SID.sid_ptr_to_string(ptr)\nrescue Puppet::Util::Windows::Error => e\n  raise unless e.code == 1337 # ERROR_INVALID_SID_STRUCTURE\n  raise 'SID buffer malformed - check offsets and buffer lifetime'\nend","preventionTips":["Keep FFI::MemoryPointer blocks open for the whole duration you read from them — pointers outlive their blocks only as dangling addresses.","Prefer octet_string_to_sid_string for Array-of-bytes input instead of hand-managing pointers.","Validate Revision (byte 0 == 1) and SubAuthorityCount (byte 1 <= 15) when walking raw SID buffers."],"tags":["windows","sid","ffi","memory","validation","puppet"],"backgroundTag":"invalid-sid","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}