Submitted for your approval, JSOX

Mike Samuel mikesamuel at gmail.com
Wed Sep 19 19:07:53 UTC 2018


On Wed, Sep 19, 2018 at 12:01 PM J Decker <d3ck0r at gmail.com> wrote:

> Again I think it's a matter of introduction; I am just fishing for
> knowledge from the more knowledgable; maybe what other JS types are
> important.
> I did include a discussion link https://gitter.im/sack-vfs/jsox .
>
> On Wed, Sep 19, 2018 at 8:14 AM Mike Samuel <mikesamuel at gmail.com> wrote:
>
>> TC39 is not really a place to spec out new transport formats.
>>
>> You proposed builtin support for JSON5
>> <https://esdiscuss.org/topic/json5> last year.
>> JSON5 was speced and had some adoption but that was controversial because
>> JSON5 was not nearly as widely used as JSON.
>> This seems to offer more obvious benefits over JSON than JSON5, but it
>> doesn't yet approach the adoption threshold.
>>
>
> Yes, but JSON5 also won't handle bigint (other than as a string). (pure
> speculation).
> I'm not really proposing JSOX into the standard, but it is highly
> dependent on the standard (and yes, the subject doesn't say that at all)
>

Understood.


>
>> -----
>>
>> IIUC, type tags can only reference builtin types with well-understood
>> semantics like Date and typed arrays or structs with default values defined
>> in the same JSON input.
>> No type referenced by JSON can be or extend a type defined by application
>> code.
>>
>
> (I am assuming you mean JSOX?) Yes types specified, (without the
> application registering information about that type) are not really 'types'
> they work more like macros.
> And there are lots of ways to instantiate types; for which, just sharing
> the same prototype isn't enough; a use case for that would be a 3D model
> which has lots of 'vector' and some 'matrix'es (and have bone structures
> which may be cyclic).
> that interface probably needs work;
>

Sorry, JSOX.  Thanks for explaining.


>
>> If that's not the case, please keep in mind though that deserialization
>> schemes that allow an external input to specify which types to construct
>> makes it easy for an attacker to forge objects that code might treat as
>> privileged because it assumes all instances are created internally.
>> https://www.owasp.org/index.php/Deserialization_of_untrusted_data
>> "Malformed data or unexpected data could be used to abuse application
>> logic, deny service, or execute arbitrary code, when deserialized."
>> See also "History of Java deserialization vulnerabilities" at
>> https://www.slideshare.net/codewhitesec/java-deserialization-vulnerabilitesruhrseceditionv10
>>
>
> Prototype binding is entirely controlled by the application; if registers
> objects of a certain type should use a certain prototype(or other
> construction method?), they will be that type alone, and not some arbitrary
> type... if some new macro was used the object will just get a blank
> prototype; which would be shared by others of that 'type'.
>


> And yes, the security note from JSON re eval() does still apply for a
> subset of valid input (since all JSON is valid),
>
> I know of no exploits; all resulting strings should be shorter than the
> input (because of escapes \\ ).  The C version allocates a output buffer
> that is the same size as the input, and moves decoded strings into it.
> Structure characters [ { } ] , " ' `  don't transfer either.
>

Not a vulnerability in your JSOX implementation per se, but have you looked
into whether there's exploitable ambiguity between JSOX and runs of ES
BlockStatements and ExpressionStatements?

JSON used to be vulnerable
<https://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/>
to cross-site snooping.

<script>// In attacker page
Array = function () { alert('Got ' + arguments[0]) };
</script>
<script src="
http://other-origin/some-web-service-that-responds-with-a-json-array
"></script>

This allowed piggybacking on HTTP credentials if an attacker could get a
victim to visit their page.

The problem was that the meaning of [...] and {...} were specified in terms
of global.Array and global.Object
which could be replaced

That's been fixed, but JSOX should probably be careful about any ambiguity
with BlockStatement.
IIUC,
  { keyword: [] }
is valid as a statement so there is some ambiguity there.

Then I see examples like

//-- the following...
a { firstField, secondField }
[ a { 1, 2 }, a(5,6), a("val1","val2") ]

I haven't worked through your grammar, but I wonder whether a naive JSOX
encoder might produce output like
    { looksLikeAStatementLabel: a("val1", "val2") }
or
    a
    { onlyField }
    [ a(5), a("val1") ]
allowing an attacker to do
    <script>
    let onlyField = null;
    function a(...data) {
      alert(`Got ${ data }`);
    }
    </script>
    <script src="http://other-origin/jsox-web-service"></script>

There's a lot of "ifs" in this scenario,
AND CORS solves a lot of these problems for origins that use it
AND browsers are less trusting of script srcs with
Content-types:text/x-jsox than they were in 2008
BUT
    // attacker setup
    let onlyField = null;
    function a(...data) {
      alert(`Got ${ data }`);
    }
    // victim responds
    a
    { onlyField }
    [ a(5), a("val1") ]
does alert twice in Chrome and JSON hijacking was exploited in the wild,
serializers have been known to
line wrap in attacker-controllable ways, and there may still be many JSON
webservices that respect ambient
credentials on cross-origin requests.



> This does stick to JSON's spirit of only transporting data.  The parser is
> very similar to a JSON parser, except many places that would previously
> throw are accepted....
> And references can only link to other objects/arrays within the current
> outermost object/array.
>



>
>> This already happens with plain JSON
>> <https://medium.com/@mikesamuel/protecting-against-object-forgery-2d0fd930a7a9>,
>> so anything that allows external inputs to specify which internal types to
>> construct would have to include a "Security Considerations" section that
>> explains how this could be safely used by code that assumes that `if (x
>> instanceof InternalType)` then x came from internal code that made a
>> good-faith effort to only pass appropriate inputs to `new
>> InternalType(...)`.
>>
>> On Tue, Sep 18, 2018 at 5:22 PM J Decker <d3ck0r at gmail.com> wrote:
>>
>>> (Thank you Rod Sterling)
>>>
>>> But seriously, I'd like to submit, for serious consideration, JSOX -
>>> JavaScript Object eXchange format.  It inherits all JSON syntax such that
>>> it is able to process any existing JSON.
>>>
>>> I'm, at this point, open to changing anything (or even omitting things),
>>> including the name.
>>>
>>> JSON is great.  JSON has some limits, and criticisms... JS/ES Grew , but
>>> JSON has to stay the same, similarly with whatever comes next I'd imagine.
>>>
>>> So a primary goal is to encode and decode ES6 objects for transport with
>>> a simple API such as JSOX.parse( object ), and JSOX.stringify( jsoxString
>>> ).  But also keep with the simplicity of JSON,
>>> so it can be used in human readable circumstances.
>>>
>>> Types that are now (or soon) native to ES such as TypedArrays (binary
>>> data), BigInt types, and even the existing Date type, do not transport with
>>> JSON very well.  They become a non-identifable string, that requires extra
>>> code involving knowledge of the structure of the data being transferred to
>>> be able to restore the values to Date(), BigInt(), et al.
>>>
>>> So a few weeks ago I started considering what else, beyond these simple
>>> modifications might also be useful, or address criticisms of JSON.
>>> Handling the above types is really a trivial modification to most JSON
>>> parsers.  Each of the following modifications is really only a very slight
>>> change to behavior; although implementing typed-objects does initially
>>> involve changing error handling into identifer-fallback handling.
>>>
>>> I initially argued, that defining a object prototype
>>> 'card(name,address,zipcode,created)' which removes the redundant data for
>>> every following reference, (and is good, just for data reduction, which was
>>> argued 'gzip').  A JSON representation might be
>>> `{"name":"bob","address":"123
>>> street","zipcode":"55555","created":1537304820} where if have a large
>>> number of the same record the same 'name':,'address':, etc is repeated in
>>> every record.  Where a typed-object's value in JSOX could be
>>> `card{:"bob","123 street","55555",2018-09-18T21:07:00Z}`.  All objects that
>>> are revived as typed-objects share the same prototype, and before parsing,
>>> the prototypes to be used may be specified.  The amount of data to process
>>> is reduced, perhaps to a significant degree.
>>>
>>> So <Identifer> '{' is about typed-objects.  This construct is not
>>> allowed in JSON.  But that then leads to <Identifier> '['  - typed arrays,
>>> arrays don't really have redundant data potential like objects, but there
>>> are TypedArrays in ES.  There is no way to define a type of an array, but
>>> hardcoded types like 'ab', 'u8', 'ref' are used to revive binary data.  The
>>> bytes of the backing ArrayBuffer are encoded to base64, and included within
>>> '[' and ']' without quotes; using the brackets as quotes.
>>>
>>> A JSOX typed array is the 'ref' type.  A reference to another location
>>> in the current object can be specified, which allows encoding cyclic
>>> structures.
>>>
>>>
>>>
>>> https://github.com/d3x0r/jsox
>>> https://npmjs.com/package/jsox
>>>
>>> (Initial public reaction was not very helpful, but probably that's the
>>> fault of how it was introduced?)
>>>
>>> https://www.reddit.com/r/javascript/comments/9f8wml/jsox_javascript_object_exchange_format_preview/
>>>
>>> There was plenty of 'why not [YAML/BSON/protobufs/(I don't think anyone
>>> said XML)/...]'  and the answer is simply, because none of those read JSON,
>>> or have as simple of an API. (amongst other reasons that JSON is already a
>>> solution for compared to those mentioned)
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180919/9a0d0d69/attachment-0001.html>


More information about the es-discuss mailing list