{"action":"created","issue":{"url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/363","labels_url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/363/labels{/name}","comments_url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/363/comments","events_url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/363/events","html_url":"https://github.com/sparkle-project/Sparkle/issues/363","id":36945601,"number":363,"title":"Secure architecture for updating in a sandboxed environment","user":{"login":"pornel","id":72159,"avatar_url":"https://avatars.githubusercontent.com/u/72159?v=3","gravatar_id":"","url":"https://api.github.com/users/pornel","html_url":"https://github.com/pornel","followers_url":"https://api.github.com/users/pornel/followers","following_url":"https://api.github.com/users/pornel/following{/other_user}","gists_url":"https://api.github.com/users/pornel/gists{/gist_id}","starred_url":"https://api.github.com/users/pornel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pornel/subscriptions","organizations_url":"https://api.github.com/users/pornel/orgs","repos_url":"https://api.github.com/users/pornel/repos","events_url":"https://api.github.com/users/pornel/events{/privacy}","received_events_url":"https://api.github.com/users/pornel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/sparkle-project/Sparkle/milestones/2","html_url":"https://github.com/sparkle-project/Sparkle/milestones/2.0","labels_url":"https://api.github.com/repos/sparkle-project/Sparkle/milestones/2/labels","id":935983,"number":2,"title":"2.0","description":null,"creator":{"login":"pornel","id":72159,"avatar_url":"https://avatars.githubusercontent.com/u/72159?v=3","gravatar_id":"","url":"https://api.github.com/users/pornel","html_url":"https://github.com/pornel","followers_url":"https://api.github.com/users/pornel/followers","following_url":"https://api.github.com/users/pornel/following{/other_user}","gists_url":"https://api.github.com/users/pornel/gists{/gist_id}","starred_url":"https://api.github.com/users/pornel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pornel/subscriptions","organizations_url":"https://api.github.com/users/pornel/orgs","repos_url":"https://api.github.com/users/pornel/repos","events_url":"https://api.github.com/users/pornel/events{/privacy}","received_events_url":"https://api.github.com/users/pornel/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":0,"state":"open","created_at":"2015-01-14T23:13:39Z","updated_at":"2015-07-27T18:35:03Z","due_on":null,"closed_at":null},"comments":102,"created_at":"2014-07-02T01:33:07Z","updated_at":"2015-08-19T21:21:59Z","closed_at":null,"body":"For some Sparkle users sandboxing is very high on priority list.\r\n\r\nThere has been one branch with a sandbox support, but Andy has [rejected it](https://github.com/sparkle-project/Sparkle/pull/165#issuecomment-13295505) due to unresolved security issues.\r\n\r\nSo I'm opening an issue here to start a discussion how we can support sandboxed applications in Sparkle while keeping the sandbox as tight as possible.\r\n\r\nI think minimal requirements are:\r\n\r\n* The XPC helper *must not* trust the host app at all, so it *must* verify integrity of downloaded update and unpack it by itself. The current approach of telling XPC helper \"hey, install this path, I've unpacked it and checked it's ok\" can't be secure.\r\n* the XPC can't trust the host to supply a valid DSA key (a compromised host could give a valid and signed update, but signed by the wrong person). The XPC helper *must* find the trusted DSA key by itself (i.e. find the app's path and read Info.plist from there) and refuse to update any other path. \r\n* Apple Code Signing verification code needs to be refactored (or not supported in sandboxed environment), because the host app checks against its own signature, but the host app is not supposed to be doing the checking.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/comments/132789594","html_url":"https://github.com/sparkle-project/Sparkle/issues/363#issuecomment-132789594","issue_url":"https://api.github.com/repos/sparkle-project/Sparkle/issues/363","id":132789594,"user":{"login":"SevenBits","id":2482736,"avatar_url":"https://avatars.githubusercontent.com/u/2482736?v=3","gravatar_id":"","url":"https://api.github.com/users/SevenBits","html_url":"https://github.com/SevenBits","followers_url":"https://api.github.com/users/SevenBits/followers","following_url":"https://api.github.com/users/SevenBits/following{/other_user}","gists_url":"https://api.github.com/users/SevenBits/gists{/gist_id}","starred_url":"https://api.github.com/users/SevenBits/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SevenBits/subscriptions","organizations_url":"https://api.github.com/users/SevenBits/orgs","repos_url":"https://api.github.com/users/SevenBits/repos","events_url":"https://api.github.com/users/SevenBits/events{/privacy}","received_events_url":"https://api.github.com/users/SevenBits/received_events","type":"User","site_admin":false},"created_at":"2015-08-19T21:21:59Z","updated_at":"2015-08-19T21:21:59Z","body":"@zorgiepoo Okay, so I've done more testing. I've looked at some of the issues you've pointed out to me. Firstly, it appears that the auto-updater can't be launched. After the update is downloaded, Sparkle tries to launch the auto-updater, which fails with this error reported to the console:\r\n\r\n> 8/19/15 5:11:46.000 PM kernel[0]: exec of /Users/user/Library/Containers/com.sevenbits.Mac-Linux-USB-Loader/Data/Library/Caches/com.sevenbits.Mac-Linux-USB-Loader/Sparkle/Autoupdate.app/Contents/MacOS/Autoupdate denied since it was quarantined by Mac Linux USB Loader and created without user consent, qtn-flags was 0x00000006\r\n\r\nTo try to remove the remove the quarantine bit, I use this code in `SUBasicUpdateDriver.m`:\r\n\r\n```objective-c\r\n    // Get autoupdater out of quarantine!!\r\n    NSLog(@\"Attempting to un-quarantine %@!\", relaunchToolPath);\r\n    NSURL *file = [NSURL fileURLWithPath:relaunchToolPath];\r\n    __autoreleasing id value;\r\n    NSError *error;\r\n    if ([file getResourceValue:&value forKey:NSURLQuarantinePropertiesKey error:NULL]) {\r\n        NSDictionary *dict = (NSDictionary *)value;\r\n\r\n        // Remove the attribute\r\n        if (dict) {\r\n            if (![file setResourceValue:[NSNull null] forKey:NSURLQuarantinePropertiesKey error:&error]) {\r\n                NSLog(@\"Couldn't remove quarantine bit for %@: %@\", file, error);\r\n            } else { NSLog(@\"Un-quarantined %@\", file); }\r\n        } else NSLog(@\"Value for dict: %@\", dict);\r\n```\r\n\r\nThis fails, though, still showing the error above. Any ideas?"}}