{ "id": "126671", "key": "TIMOB-16488", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "16723", "description": "Windows Platform Support, ListView updates, Vector overlays in maps", "name": "Release 4.1.0", "archived": false, "released": true, "releaseDate": "2015-07-08" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2015-06-03T03:01:07.000+0000", "created": "2014-02-20T23:05:26.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "supportTeam" ], "versions": [ { "id": "14982", "description": "Release 3.2.0", "name": "Release 3.2.0", "archived": false, "released": true, "releaseDate": "2013-12-19" } ], "issuelinks": [], "assignee": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2015-07-07T20:37:31.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "h3. Issue\r\n\r\nAfter a revision from customer Vulnerability assessment team they have raised a low priority issue in reference that the Property List lacks of Secure Class Protection - NSFileProtectionKey\r\n\r\nThe list of files they are referring to is basically everything in the installed package on the device (Cache.db, Cookies.binarycookies, etc.)\r\n\r\nh3. Description\r\n\r\nOn iOS, every file is encrypted with an unique encryption key as illustrated in the image. The content of a file is encrypted with a per-file key, which is wrapped with a class key (data protection class key) and stored in a file metadata, which is in turn encrypted with the file system key (EMF key). The file system key is generated from the hardware UID. UID is unique per device and it is embedded in hardware and inaccessible to code running on CPU.\r\n\r\nA file which is encrypted only with the file system key, upon physical access to the device custom ramdisk techniques can be used to steal the file from passcode protected devices. To overcome this problem Data protection was introduced. Data protection protects the data at rest on iOS devices using encryption keys that are tied to the device passcode and UID. So if the file is protected with a data protection class and the user sets a passcode for the device, an attacker cannot access the file using custom ram disk technique until he knows the passcode. Data protection provides another layer of security to files by encrypting them with a passcode generated key. File protection is enabled by setting an accessibility constant to NSFileProtectionKey file attribute. Later the files are encrypted with a protection class key respective to the accessibility constant marked for that file.\r\n\r\nEx: If a file is marked with NSProtectionComplete accessibility constant then the file is encrypted with Class 1 protection class key and it is available only when the user unlocks the device. If a file is created without specifying any accessibility constant then the file is marked as NSProtectionNone and it is accessible even the device is locked . List of accessibility constants available for files are shown in the below table.\r\n\r\nh3. iOS Reference\r\n\r\nhttps://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html\r\n\r\n", "attachment": [], "flagged": false, "summary": "iOS: Property List lacks of Secure Class Protection - NSFileProtectionKey", "creator": { "name": "mcota", "key": "mcota", "displayName": "Marco Cota", "active": false, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "mcota", "key": "mcota", "displayName": "Marco Cota", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "Product: Titanium SDK\r\nTitanium SDK: Mobile 3.2GA\r\nPlatform OS: iOS\r\nPlatform OS Version: 7", "closedSprints": [ { "id": 407, "state": "closed", "name": "2015 Sprint 11 SDK", "startDate": "2015-05-23T00:00:08.253Z", "endDate": "2015-06-06T00:00:00.000Z", "completeDate": "2015-06-08T16:18:16.381Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "297730", "author": { "name": "mcota", "key": "mcota", "displayName": "Marco Cota", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~ingo] Do we have any updates on this? ", "updateAuthor": { "name": "mcota", "key": "mcota", "displayName": "Marco Cota", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-03-18T17:56:05.000+0000", "updated": "2014-03-18T17:56:05.000+0000" }, { "id": "297965", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~ingo] From my initial looks. In our SDK whenever we create a Directory or a File we do not pass in any kind of FIleProtection attribute to it. By default as files are created with NSProtectionNone by OS. This would be a new feature to be added to the SDK.", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-03-19T21:41:56.000+0000", "updated": "2014-03-19T21:41:56.000+0000" }, { "id": "313253", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Removing due date as this would appear in the next major release. Considering it for 3.4.0.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-07-10T16:07:08.000+0000", "updated": "2014-07-10T16:07:08.000+0000" }, { "id": "353592", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "PR here: https://github.com/appcelerator/titanium_mobile/pull/6875\r\nAdded 2 new methods:\r\n*setProtectionKey()*\r\n*getProtectionKey()*\r\nTo allow setting of NSFileProtectionKey to individual files for iOS.\r\n*Note* Setting of NSFileProtectionKey only works on iOS device, not simulator.\r\n\r\nh4. Sample Code:\r\n{code}\r\n\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: 'white',\r\n layout: 'vertical'\r\n});\r\n \r\nvar button1 = Ti.UI.createButton({\r\n title: 'create File',\r\n top: 100\r\n});\r\nvar button2 = Ti.UI.createButton({\r\n title: 'set file attributes',\r\n top: 100\r\n});\r\nvar button3 = Ti.UI.createButton({\r\n title: 'get file attributes',\r\n top: 100\r\n});\r\n \r\nbutton1.addEventListener('click', function(e) {\r\n //create file\r\n var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"textfile.txt\");\r\n file.write('test');\r\n});\r\n \r\nbutton2.addEventListener('click', function(e) {\r\n //file attributes\r\n file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"textfile.txt\");\r\n var result = file.setProtectionKey(Ti.Filesystem.IOS_FILE_PROTECTION_NONE);\r\n// var result = file.setProtectionKey(Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE);\r\n// var result = file.setProtectionKey(Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNLESS_OPEN);\r\n// var result = file.setProtectionKey(Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNTIL_FIRST_USER_AUTHENTICATION);\r\n if (result === true) {\r\n alert('success');\r\n }\r\n else {\r\n alert('failed');\r\n }\r\n});\r\n \r\nbutton3.addEventListener('click', function(e) {\r\n //file attributes\r\n file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"textfile.txt\");\r\n var currentProtectionKey = file.getProtectionKey();\r\n if (currentProtectionKey == null) {\r\n alert('error getting protection key.');\r\n };\r\n if (currentProtectionKey == Ti.Filesystem.IOS_FILE_PROTECTION_NONE) {\r\n alert('None');\r\n };\r\n if (currentProtectionKey == Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE) {\r\n alert('Complete');\r\n };\r\n if (currentProtectionKey == Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNLESS_OPEN) {\r\n alert('Complete unless open');\r\n };\r\n if (currentProtectionKey == Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNTIL_FIRST_USER_AUTHENTICATION) {\r\n alert('Complete until first user authentication');\r\n };\r\n\r\n});\r\n \r\nwin.add(button1);\r\nwin.add(button2);\r\nwin.add(button3);\r\nwin.open();\r\n{code}\r\n\r\nh4. Steps to test:\r\n1. Run sample code on device\r\n2. *create file*\r\n3. *set file attributes*\r\n4. *get file attributes*\r\n5. Repeat steps 3-4, using different protectionKey listed below:\r\n- Ti.Filesystem.IOS_FILE_PROTECTION_NONE\r\n- Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE\r\n- Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNLESS_OPEN\r\n- Ti.Filesystem.IOS_FILE_PROTECTION_COMPLETE_UNTIL_FIRST_USER_AUTHENTICATION\r\n\r\nh4. Expected Result:\r\nSee alert dialog displaying the corresponding fileProtectionKey set\r\n", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-27T02:07:35.000+0000", "updated": "2015-05-28T02:22:08.000+0000" }, { "id": "354196", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "PR reviewed and merged by Pedro.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-06-03T03:01:07.000+0000", "updated": "2015-06-03T03:01:07.000+0000" }, { "id": "357200", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified fixed, using:\r\n\r\nMacOS 10.11\r\nStudio 4.1.0.201507061821\r\nTi SDK 4.2.0\r\nAppc NPM 4.1.0-1\r\nAppc CLI 4.1.0-5\r\nTi CLI 4.0.1\r\nAlloy 1.6.2\r\nNode v0.10.37\r\nJava 1.7.0_45\r\npreproduction\r\n\r\nAble to correctly get the file protection key of the created file.", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-07-07T20:37:31.000+0000", "updated": "2015-07-07T20:37:31.000+0000" } ], "maxResults": 8, "total": 8, "startAt": 0 } } }