CBOR-XS
view release on metacpan or search on metacpan
CBOR integers, and others into positive/negative CBOR bignums.
4, 5, 264, 265 (decimal fraction/bigfloat)
Both decimal fractions and bigfloats are decoded into Math::BigFloat
objects. The corresponding "Math::BigFloat::TO_CBOR" method *always*
encodes into a decimal fraction (either tag 4 or 264).
NaN and infinities are not encoded properly, as they cannot be
represented in CBOR.
See "BIGNUM SECURITY CONSIDERATIONS" for more info.
30 (rational numbers)
These tags are decoded into Math::BigRat objects. The corresponding
"Math::BigRat::TO_CBOR" method encodes rational numbers with
denominator 1 via their numerator only, i.e., they become normal
integers or "bignums".
See "BIGNUM SECURITY CONSIDERATIONS" for more info.
21, 22, 23 (expected later JSON conversion)
CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore
these tags.
32 (URI)
These objects decode into URI objects. The corresponding
"URI::TO_CBOR" method again results in a CBOR URI value.
CBOR and JSON
CBOR is supposed to implement a superset of the JSON data model, and is,
with some coercion, able to represent all JSON texts (something that
other "binary JSON" formats such as BSON generally do not support).
CBOR implements some extra hints and support for JSON interoperability,
and the spec offers further guidance for conversion between CBOR and
JSON. None of this is currently implemented in CBOR, and the guidelines
in the spec do not result in correct round-tripping of data. If JSON
interoperability is improved in the future, then the goal will be to
ensure that decoded JSON data will round-trip encoding and decoding to
CBOR intact.
SECURITY CONSIDERATIONS
Tl;dr... if you want to decode or encode CBOR from untrusted sources,
you should start with a coder object created via "new_safe" (which
implements the mitigations explained below):
my $coder = CBOR::XS->new_safe;
my $data = $coder->decode ($cbor_text);
my $cbor = $coder->encode ($data);
Longer version: When you are using CBOR in a protocol, talking to
untrusted potentially hostile creatures requires some thought:
Security of the CBOR decoder itself
First and foremost, your CBOR decoder should be secure, that is,
should not have any buffer overflows or similar bugs that could
potentially be exploited. Obviously, this module should ensure that
and I am trying hard on making that true, but you never know.
CBOR::XS can invoke almost arbitrary callbacks during decoding
CBOR::XS supports object serialisation - decoding CBOR can cause
calls to *any* "THAW" method in *any* package that exists in your
process (that is, CBOR::XS will not try to load modules, but any
existing "THAW" method or function can be called, so they all have
to be secure).
Less obviously, it will also invoke "TO_CBOR" and "FREEZE" methods -
even if all your "THAW" methods are secure, encoding data structures
from untrusted sources can invoke those and trigger bugs in those.
So, if you are not sure about the security of all the modules you
have loaded (you shouldn't), you should disable this part using
"forbid_objects" or using "new_safe".
CBOR can be extended with tags that call library code
CBOR can be extended with tags, and "CBOR::XS" has a registry of
conversion functions for many existing tags that can be extended via
third-party modules (see the "filter" method).
If you don't trust these, you should configure the "safe" filter
function, "CBOR::XS::safe_filter" ("new_safe" does this), which by
default only includes conversion functions that are considered
"safe" by the author (but again, they can be extended by third party
modules).
Depending on your level of paranoia, you can use the "safe" filter:
$cbor->filter (\&CBOR::XS::safe_filter);
... your own filter...
$cbor->filter (sub { ... do your stuffs here ... });
... or even no filter at all, disabling all tag decoding:
$cbor->filter (sub { });
This is never a problem for encoding, as the tag mechanism only
exists in CBOR texts.
Resource-starving attacks: object memory usage
You need to avoid resource-starving attacks. That means you should
limit the size of CBOR data you accept, or make sure then when your
resources run out, that's just fine (e.g. by using a separate
process that can crash safely). The size of a CBOR string in octets
is usually a good indication of the size of the resources required
to decode it into a Perl structure. While CBOR::XS can check the
size of the CBOR text (using "max_size" - done by "new_safe"), it
might be too late when you already have it in memory, so you might
want to check the size before you accept the string.
As for encoding, it is possible to construct data structures that
are relatively small but result in large CBOR texts (for example by
having an array full of references to the same big data structure,
which will all be deep-cloned during encoding by default). This is
rarely an actual issue (and the worst case is still just running out
of memory), but you can reduce this risk by using "allow_sharing".
Resource-starving attacks: stack overflows
CBOR::XS recurses using the C stack when decoding objects and
( run in 1.161 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )