Re: [ogpx] type-system : guidance for binary serialization implementers
"Robert G. Jakabosky" <bobby@sharedrealm.com> Mon, 29 March 2010 02:43 UTC
Return-Path: <bobby@sharedrealm.com>
X-Original-To: ogpx@core3.amsl.com
Delivered-To: ogpx@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id ECDE93A68BE for <ogpx@core3.amsl.com>; Sun, 28 Mar 2010 19:43:24 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 1.131
X-Spam-Level: *
X-Spam-Status: No, score=1.131 tagged_above=-999 required=5 tests=[BAYES_50=0.001, DNS_FROM_OPENWHOIS=1.13]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qEMQbxmifAR9 for <ogpx@core3.amsl.com>; Sun, 28 Mar 2010 19:43:23 -0700 (PDT)
Received: from mail.neoawareness.com (ns2.sharedrealm.com [IPv6:2001:470:1f05:4f4::13]) by core3.amsl.com (Postfix) with ESMTP id 6958D3A6892 for <ogpx@ietf.org>; Sun, 28 Mar 2010 19:43:23 -0700 (PDT)
Received: from localhost ([127.0.0.1] helo=[10.200.0.30]) by mail.neoawareness.com with esmtpa (Exim 4.69) (envelope-from <bobby@sharedrealm.com>) id 1Nw4xA-0002Oe-4K for ogpx@ietf.org; Sun, 28 Mar 2010 19:43:48 -0700
From: "Robert G. Jakabosky" <bobby@sharedrealm.com>
To: ogpx@ietf.org
Date: Sun, 28 Mar 2010 18:43:42 -0800
User-Agent: KMail/1.9.10
References: <b325928b1003281034s55fae732n7be979446759bd12@mail.gmail.com>
In-Reply-To: <b325928b1003281034s55fae732n7be979446759bd12@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Message-Id: <201003281943.42481.bobby@sharedrealm.com>
X-SA-Exim-Connect-IP: 127.0.0.1
X-SA-Exim-Mail-From: bobby@sharedrealm.com
X-SA-Exim-Scanned: No (on mail.neoawareness.com); SAEximRunCond expanded to false
Subject: Re: [ogpx] type-system : guidance for binary serialization implementers
X-BeenThere: ogpx@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Virtual World Region Agent Protocol - IETF working group <ogpx.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/ogpx>, <mailto:ogpx-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/ogpx>
List-Post: <mailto:ogpx@ietf.org>
List-Help: <mailto:ogpx-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/ogpx>, <mailto:ogpx-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 29 Mar 2010 02:43:25 -0000
On Sunday 28, Meadhbh Hamrick wrote: > one of the things we were trying to do was make a type system and > serialization schemes that were resilient in the face of error. so i > think there's a strong preference that we recover as best we can from > an error instead of throwing up our hands and just saying "error!" One primary source of decoding errors (i.e. LLSD message that doesn't follow the spec) will be from attackers (DOS attacks, remote code execution). There is a big difference between handling unknown tags (to support future extentions) vs. trying to recover from a bad LLSD message and passing it on. The spec should allow for future extentions to be ignored by old implementations, but bad LLSD messages shouldn't be ignored, it will just hide normal bugs and make it harder to create new implementations (since you will not get useful decoding errors). > here's a list of encoding / decoding errors i think about, along with > suggestions for how to handle them. > > 1. the object count following the opening tag ('{' or '[') is less > than the actual number of objects in the collection. (that is, the > closing tag is not found after iterating through "object count" number > of elements, but is found later in the stream.) If closing tags are kept in the spec, then just reject the LLSD message as malformed. What would you do if the same LLSD message was serialized in the XML format and the ending </array> or </map> tags where missing? If the object count doesn't match the number of objects before the closing tag is found, then the LLSD message should be rejected with some error sent back to the sender. > 2. the object count following the opening tag ('{' or '[') is greater > than the actual number of objects in the collection. (that is, you get > a closing tag before "object count" number of elements) Same as case 1, just reject the LLSD message. > 3. there is no closing tag. (that is, after "object count" number of > elements, you find a tag that is not a '}' or a ']'.) > > this is more or less the same as error case number 1 above. > > though i wonder if it makes sense to differentiate the two cases. if > we were, we would have to have the smarts enough to look forward in > the stream, count the number of opening tags, then count the number of > closing tags and see if they're unbalanced. ugh. Doing this type of analysis would be fine for a verification tool, but not for a protocol decoder in a client/server program. The more complex the decoder logic is the more likely it will have bugs that an attacker can exploit. Also if the decoder should continue parsing the array/map until it finds the closing tag, then the "object count" is completely redundant and a waste of bandwidth. Either drop the "object count" or the closing tags. I would prefer the "object count" over the closing tags, also it would be nice if the "object count" was a "Base 128 Varint" instead of a fixed length 32bit integer: http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints > 4. lack of 'k' elements in a map. (that is, you haven't reached the > "object count" number of elements and are expecting a 'k' but get > something else.) > > my druthers would be to say, if you encounter a type that can be > converted to a string, you just do the conversion and use the result > as the key. Then why not just allow any type that can be converted to a string be used as a key in the maps? How would you handle this for the XML encoding formats? > another way to handle it would be to ignore it. It should be a malformed error (with details about why it is malformed for easier debugging). > 5. you encounter a bare 'k'. (that is, you encounter a 'k' tag outside > the context of a map.) > > i vote for "convert to string" This would just hide errors caused by a bad implementation of the LLSD binary encoder. If you find a 'k' tag outside a map, then there might be some bigger problem. Maybe the last map had more objects then the "object count" said. > 6. duplicate keys in a map. (actually this applies to all serializations) > > i vote for "the last key in the map with the same name wins." that is, > if you have two or more keys with the same name, the one found > furthest in the stream is the one that's used. This issue is not unique to the binary format, both the XML & JSON formats will have this issue too. The JSON specs RFC4627 section 2.2 says that the names of object members SHOULD be unique, but it doesn't say how duplicate names are to be handled. Section "2.2.2. Map" of the LLSD draft says "Within a given Map value, each key must be unique, each with one value. ....". Either that should be changed to a "each key MUST be unique", in which case duplicate keys would generate a malformed error with the whole LLSD message being rejected, or it should be changed to a "MUST"/"REQUIRED" rule on how to handle duplicates. Having strict rules in the spec on how to handle malformed LLSD message is important, since a security hole can exist if two LLSD implementations interpret/decode the same LLSD message differently. There has been a similar issue with HTTP proxies (sneaking a second HTTP request passed the proxy to a backend HTTP server). Lets say you have a proxy/authenticator in front of a set of backend servers that will consume LLSD messages: "VWRAP client(attacker)" -> "public frontend proxy/authenticator" -> "private backend server" The "public frontend" proxy server would decode the LLSD message to apply some routing or authentication rules (i.e. check user id & credentials) before passing the original (not a re-encoded message) LLSD message to a "private backend" server for handling. The attacker could trick the frontend server into routing a LLSD message with any user id they want to the backend server. This could easily happend if the proxy server was written/made by a different company (i.e. Cisco VWRAP load balancer), then the backend server and the two implementations of LLSD used different rules for how to handle duplicate keys ("user id" or "credential" keys). The same thing can happen if one of the two implementations ignore incorrect "object counts" or missing closing tags. I will be commenting more on the other "type-system" e-mails soon. P.S. will this mailling list change it's name to "vwrap" soon? I know the vwrap jabber.ietf.org channel has already been created. -- Robert G. Jakabosky
- [ogpx] type-system : guidance for binary serializ… Meadhbh Hamrick
- Re: [ogpx] type-system : guidance for binary seri… Robert G. Jakabosky
- Re: [ogpx] type-system : guidance for binary seri… Dahlia Trimble
- Re: [ogpx] type-system : guidance for binary seri… Robert G. Jakabosky
- Re: [ogpx] type-system : guidance for binary seri… Meadhbh Hamrick
- Re: [ogpx] type-system : guidance for binary seri… Hurliman, John