Github: Understanding Unsafe Deserialization Vulnerabilities in Ruby Projects


Github: Understanding Unsafe Deserialization Vulnerabilities in Ruby Projects

Unsafe
deserialization
vulnerabilities
in
Ruby
projects
can
enable
attackers
to
execute
arbitrary
commands
on
remote
servers
by
sending
JSON
data.
According
to

The
GitHub
Blog
,
these
vulnerabilities
occur
when
the
deserialization
process
allows
the
instantiation
of
arbitrary
classes
or
class-like
structures
specified
in
the
serialized
data.

How
Unsafe
Deserialization
Works

In
Ruby,
unsafe
deserialization
vulnerabilities
are
often
exploited
through
libraries
that
support
polymorphism,
such
as
the
Oj
JSON
serialization
library.
Attackers
can
chain
multiple
classes
together
to
execute
code
on
the
system
under
attack.
These
classes,
known
as
gadgets,
are
combined
into
a
gadget
chain
to
form
a
larger
exploit.

For
instance,
when
using
the
Oj
library
for
deserializing
JSON,
a
project
can
be
vulnerable
if
it
includes
a
construct
like:

data = Oj.load(untrusted_json)

The
Oj
library,
by
default,
supports
the
instantiation
of
classes
specified
in
JSON,
which
can
be
disabled
by
using

Oj.safe_load

instead.

To
demonstrate
how
this
works,
consider
a
class
named

SimpleClass

with
a

hash

method
that
executes
a
command:

class SimpleClass def initialize(cmd) @cmd = cmd end def hash system(@cmd) end
end

A
JSON
payload
to
instantiate
this
class
might
look
like:

{ "^o": "SimpleClass", "cmd": "open -a calculator"
}

Loading
this
JSON
with

Oj.load

would
not
trigger
the

hash

method
directly,
but
placing
the
class
inside
a
hash
as
the
key
can
trigger
the
method:

Oj.load(json_payload)

This
would
execute
the
command
specified
in
the

@cmd

member
variable.

Building
a
Detection
Gadget

To
detect
unsafe
deserialization
vulnerabilities,
one
can
build
a
detection
gadget
chain.
For
example,
a
class
like

Gem::Requirement

can
be
used,
which
has
a

hash

method
that
calls

to_s

on
an
internal
member.
By
creating
a
suitable
JSON
payload,
one
can
trigger
this
chain
to
detect
vulnerabilities.

The
detection
gadget
can
also
be
extended
to
a
full-fledged
remote
code
execution
(RCE)
chain.
This
involves
using
classes
and
methods
that
are
part
of
Ruby
or
its
dependencies
to
execute
arbitrary
commands.

Preventing
Unsafe
Deserialization

To
prevent
such
vulnerabilities,
it
is
crucial
to
use
safe
deserialization
methods.
For
example,
using

Oj.safe_load

instead
of

Oj.load

can
prevent
the
instantiation
of
arbitrary
classes.
Additionally,
tools
like
CodeQL
can
help
detect
unsafe
deserialization
by
analyzing
the
source
code
for
vulnerable
patterns.

For
developers
with
access
to
the
source
code,
GitHub’s
code
scanning
with
CodeQL
can
identify
unsafe
deserialization
sinks.
If
the
source
code
is
not
accessible,
detection
gadgets
can
be
used
to
identify
vulnerabilities
remotely.

Understanding
how
unsafe
deserialization
works
and
implementing
secure
coding
practices
can
help
avoid
these
vulnerabilities.
For
more
detailed
examples
and
detection
methodologies,
refer
to
the

original
blog
post

by
The
GitHub
Blog.

Image
source:
Shutterstock

Comments are closed.