{"id":12764,"date":"2015-11-08T10:29:39","date_gmt":"2015-11-08T15:29:39","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=12764"},"modified":"2015-11-10T11:30:37","modified_gmt":"2015-11-10T16:30:37","slug":"the-java-deserialization-bug-and-nssecurecoding","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2015\/11\/08\/the-java-deserialization-bug-and-nssecurecoding\/","title":{"rendered":"The Java Deserialization Bug and NSSecureCoding"},"content":{"rendered":"<p><a href=\"http:\/\/fishbowl.pastiche.org\/2015\/11\/09\/java_serialization_bug\/\">Charles Miller<\/a>:<\/p>\n<blockquote cite=\"http:\/\/fishbowl.pastiche.org\/2015\/11\/09\/java_serialization_bug\/\"><p>The problem, described in the talk the exploit was first raised in &mdash;\n  <a href=\"http:\/\/www.slideshare.net\/frohoff1\/appseccali-2015-marshalling-pickles\">Marshalling\n  Pickles<\/a> &mdash; is that arbitrary object deserialization (or marshalling, or\n  un-pickling, whatever your language calls it) is inherently unsafe, and\n  should never be performed on untrusted data.<\/p><p>[&#8230;]<\/p><p>This means that if there is <i>any object reachable from your runtime<\/i>\n  that declares itself serializable and could be fooled into doing something\n  bad by malicious data, then it can be exploited through deserialization. This\n  is a mind-bogglingly enormous amount of potentially vulnerable and mostly\n  un-audited code.<\/p><\/blockquote>\n<p>In Cocoa land, this is why <a href=\"http:\/\/nshipster.com\/nssecurecoding\/\">we have<\/a> <a href=\"https:\/\/developer.apple.com\/library\/mac\/documentation\/Foundation\/Reference\/NSSecureCoding_Protocol_Ref\/\">NSSecureCoding<\/a>. Some things to be aware of:<\/p>\n<ul><li><p>If you&rsquo;re decoding a collection containing custom classes, it&rsquo;s <a href=\"http:\/\/stackoverflow.com\/questions\/24376746\/nssecurecoding-trouble-with-collections-of-custom-class\">not enough<\/a> for them to conform to <code>NSSecureCoding<\/code>. You also have to use <code>-[NSCoder decodeObjectOfClasses:forKey:]<\/code> and add your classes to the set.<\/p><\/li><li>Even when using <code>NSSecureCoding<\/code> to check that you are decoding objects with the proper classes, you should still verify that the structure of the objects is correct.<\/li><li><p>There&rsquo;s a special (rather inconvenient) way that you need to <a href=\"https:\/\/github.com\/rentzsch\/NSKeyedArchiver-butWithNSError\">create your archiver and unarchiver<\/a>:<\/p><blockquote cite=\"https:\/\/github.com\/rentzsch\/NSKeyedArchiver-butWithNSError\"><p><strong>tl;dr<\/strong>: don&rsquo;t use <code>-[NSKeyedArchiver encodeRootObject:]<\/code> or <code>-[NSKeyedUnarchiver decodeObject]<\/code> in new code unless you need compatibility with Format 1 archives.<\/p><p>Since <code>+[NSKeyedArchiver archivedDataWithRootObject:]<\/code> and <code>+[NSKeyedUnarchiver unarchiveObjectWithData:]<\/code> don&rsquo;t give you an opportunity to call <code>-setRequiresSecureCoding:YES<\/code>, they&rsquo;re out of the party as well.<\/p><p>That leaves us with <code>-[NSKeyedArchiver encodeObject:forKey:NSKeyedArchiveRootObjectKey]<\/code> and <code>-[NSKeyedUnarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]<\/code>.<\/p><\/blockquote><\/li><li>Especially if you&rsquo;re using Swift, you&rsquo;ll need a top-level Objective-C wrapper to catch exceptions because <code>NSCoder<\/code> still doesn&rsquo;t support <code>NSError<\/code>.  [Update (2015-11-08): See the comments below.] I have not tested what happens if a Swift class implements <code>init(coder:)<\/code> and an exception is raised.<\/li>\n<\/ul>\n<p>Update (2015-11-10): <a href=\"http:\/\/www.noodlesoft.com\/blog\/2015\/11\/09\/nssecurecoding\/\">Paul Kim<\/a>:<\/p>\n<blockquote cite=\"http:\/\/www.noodlesoft.com\/blog\/2015\/11\/09\/nssecurecoding\/\"><p>Even if you don&rsquo;t call <code>-decodeObject:<\/code>&#8230; in your <code>-initWithCoder:<\/code> you still have to implement <code>+supportsSecureCoding<\/code>  and return YES in your class, even if a superclass already did it.<\/p><p>[&#8230;]<\/p><p>Objects like NSPredicate and NSSortDescriptor can take in key paths or selectors making them potentially unsafe. As a result, they are disabled after being securely decoded. To re-enable them, you have to call <code>-allowEvaluation<\/code> (presumably after doing some sort of check).<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Charles Miller: The problem, described in the talk the exploit was first raised in &mdash; Marshalling Pickles &mdash; is that arbitrary object deserialization (or marshalling, or un-pickling, whatever your language calls it) is inherently unsafe, and should never be performed on untrusted data.[&#8230;]This means that if there is any object reachable from your runtime that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[69,31,84,30,857,54,71,232,48,901],"class_list":["post-12764","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-cocoa","tag-ios","tag-java","tag-mac","tag-nserror","tag-objective-c","tag-programming","tag-python","tag-security","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/12764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=12764"}],"version-history":[{"count":5,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/12764\/revisions"}],"predecessor-version":[{"id":12772,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/12764\/revisions\/12772"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=12764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=12764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=12764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}