ENABLEDEBUGGER
and ENABLEDEBUGGER2
enables support for remote debugging and also contains a poorly salted MD5 password hash. The tag does not offer any security guarantees and can be easily circumvented by using any hex editor tool. Not only is the remote debugging protection easily bypassed, the password the developer used to secure the file is easily recoverable. Flash uses a 16-bit salt added to the password and applies the MD5 hash algorithm to it. This is a weak salt and the password can be recovered using password cracking programs.crossdomain.xml
configuration file. However, caution should be taken when changing the settings because an overly permissive cross-domain policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay, and other attacks.
flash.system.Security.allowDomain("*");
*
as the argument to allowDomain()
indicates that the application's data is accessible to other SWF applications from any domain.crossdomain.xml
configuration file. Starting with Flash Player 9,0,124,0, Adobe also introduced the capability to define which custom headers Flash Player can send across domains. However, caution should be taken when defining these settings because an overly permissive custom headers policy, when applied together with the overly permissive cross-domain policy, will allow a malicious application to send headers of their choosing to the target application, potentially leading to a variety of attacks or causing errors in the execution of the application that does not know how to handle received headers.
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
*
as the value of the headers
attribute indicates that any header will be sent across domains.crossdomain.xml
configuration file. However, caution should be taken when deciding who can influence the settings because an overly permissive cross-domain policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay, and other attacks. Policy restrictions bypass vulnerabilities occur when:Example 2: The following code uses the value of one of the parameters to the loaded SWF file to define the list of trusted domains.
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var url:String = String(params["url"]);
flash.system.Security.loadPolicyFile(url);
...
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var domain:String = String(params["domain"]);
flash.system.Security.allowDomain(domain);
...
crossdomain.xml
configuration file. However, caution should be taken when defining these settings because HTTP loaded SWF applications are subject to man-in-the-middle attacks, and thus should not be trusted.allowInsecureDomain()
, which turns off the restriction that prevents HTTP loaded SWF applications from accessing the data of HTTPS loaded SWF applications.
flash.system.Security.allowInsecureDomain("*");
allowBackup
attribute to true
(the default value) and defining the backupAgent
attribute on the <application>
tag.Environment.getExternalStorageDirectory()
returns a reference to the Android device's external storage.private void WriteToFile(String what_to_write) {
try{
File root = Environment.getExternalStorageDirectory();
if(root.canWrite()) {
File dir = new File(root + "write_to_the_SDcard");
File datafile = new File(dir, number + ".extension");
FileWriter datawriter = new FileWriter(datafile);
BufferedWriter out = new BufferedWriter(datawriter);
out.write(what_to_write);
out.close();
}
}
}
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:ThisDeviceOnly
will be backed up to iCloud and backed up to iTunes even if using unencrypted backups which can be restored to any device. Depending on how sensitive and private the stored data is, this may raise a privacy concern.
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlocked forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:ThisDeviceOnly
will be backed up to iCloud and backed up to iTunes even if using unencrypted backups which can be restored to any device. Depending on how sensitive and private the stored data is, this may raise a privacy concern.
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlocked
SecItemAdd(query as CFDictionary, nil)
...
protected void onCreate(Bundle savedInstanceState) {
...
try {
File httpCacheDir = new File(context.getExternalCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
}
protected void onStop() {
...
HttpResponseCache cache = HttpResponseCache.getInstalled();
if (cache != null) {
cache.flush();
}
}
{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
files.{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
files.{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
files. diskCapacity
or memoryCapacity
properties of the URLCache
class to 0, they may be effectively disabling the HTTP(S) response cache system. However, the NSURLCache
documentation states that both the on-disk and in-memory caches will be truncated to the configured sizes only if the device runs low on memory or disk space. Both settings are meant to be used by the system to free system resources and improve performance, not as a security control.{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
files. diskCapacity
or memoryCapacity
properties of the URLCache
class to 0, they may be effectively disabling the HTTP(S) response cache system. However, the NSURLCache
documentation states that both the on-disk and in-memory caches will be truncated to the configured sizes only if the device runs low on memory or disk space. Both settings are meant to be used by the system to free system resources and improve performance, not as a security control.NSFileManager
as constants meant to be assigned as the value for the NSFileProtectionKey
key in an NSDictionary
associated with the NSFileManager
instance, and files can be created or have their data protection class modified through use of NSFileManager
functions including setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
, and createFileAtPath:contents:attributes:
. In addition, corresponding Data Protection constants are defined for NSData
objects as NSDataWritingOptions
that can be passed as the options
argument to NSData
functions writeToURL:options:error:
and writeToFile:options:error:
. The definitions for the various Data Protection class constants for NSFileManager
and NSData
are as follows:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
or NSFileProtectionCompleteUntilFirstUserAuthentication
will afford it encryption using a key derived from the user's passcode and the device's UID, the data will still remain accessible under certain circumstances. As such, usages of NSFileProtectionCompleteUnlessOpen
or NSFileProtectionCompleteUntilFirstUserAuthentication
should be carefully reviewed to determine if further protection with NSFileProtectionComplete
is warranted.Example 2: In the following example, the given data is only protected until the user powers on the device and provides their passcode for the first time (until the next reboot):
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication error:&err];
...
NSFileManager
as constants meant to be assigned as the value for the NSFileProtectionKey
key in a Dictionary
associated with the NSFileManager
instance, and files can be created or have their data protection class modified through use of NSFileManager
functions including setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
, and createFileAtPath(_:contents:attributes:)
. In addition, corresponding Data Protection constants are defined for NSData
objects in the NSDataWritingOptions
enum that can be passed as the options
argument to NSData
functions
writeToFile(_:options:)
. The definitions for the various Data Protection class constants for NSFileManager
and NSData
are as follows:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
or NSFileProtectionCompleteUntilFirstUserAuthentication
will afford it encryption using a key derived from the user's passcode and the device's UID, the data will still remain accessible under certain circumstances. As such, usages of NSFileProtectionCompleteUnlessOpen
or NSFileProtectionCompleteUntilFirstUserAuthentication
should be carefully reviewed to determine if further protection with NSFileProtectionComplete
is warranted.Example 2: In the following example, the given data is only protected until the user powers on the device and provides their passcode for the first time (until the next reboot):
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionCompleteUntilFirstUserAuthentication);
...
kSecAttrAccessible
key in the Keychain attribute dictionary. The definitions for the various Keychain accessibility constants are as follows:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
will afford it encryption using a key derived from the user's passcode and the device's UID, the data will still remain accessible under certain circumstances. As such, usages of kSecAttrAccessibleAfterFirstUnlock
should be carefully reviewed to determine if further protection is warranted.
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
key in the Keychain attribute dictionary. The definitions for the various Keychain accessibility constants are as follows:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
will afford it encryption using a key derived from the user's passcode and the device's UID, the data will still remain accessible under certain circumstances. As such, usages of kSecAttrAccessibleAfterFirstUnlock
should be carefully reviewed to determine if further protection is warranted.
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
SecItemAdd(query as CFDictionary, nil)
...
NSFileManager
as constants meant to be assigned as the value for the NSFileProtectionKey
key in an NSDictionary
associated with the NSFileManager
instance, and files can be created or have their data protection class modified through use of NSFileManager
functions including setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
, and createFileAtPath:contents:attributes:
. In addition, corresponding Data Protection constants are defined for NSData
objects as NSDataWritingOptions
that can be passed as the options
argument to NSData
functions writeToURL:options:error:
and writeToFile:options:error:
. The definitions for the various Data Protection class constants for NSFileManager
and NSData
are as follows:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
results in encryption using a key derived solely based on the device's UID. This leaves such files accessible any time the device is powered on, including when locked with a passcode or when booting. As such, usages of NSFileProtectionNone
should be carefully reviewed to determine if further protection with a stricter Data Protection class is warranted.Example 2: In the following example, the given data is not protected (accessible anytime the device is powered on):
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionNone error:&err];
...
NSFileManager
as constants meant to be assigned as the value for the NSFileProtectionKey
key in a Dictionary
associated with the NSFileManager
instance. Files can be created or have their data protection class modified through use of NSFileManager
functions including setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
, and createFileAtPath(_:contents:attributes:)
. In addition, corresponding Data Protection constants are defined for NSData
objects in the NSDataWritingOptions
enum that can be passed as the options
argument to NSData
functions such as
writeToFile(_:options:)
. The definitions for the various Data Protection class constants for NSFileManager
and NSData
are as follows:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
results in encryption using a key derived solely based on the device's UID. This leaves such files accessible any time the device is powered on, including when locked with a passcode or when booting. As such, usages of NSFileProtectionNone
should be carefully reviewed to determine if further protection with a stricter Data Protection class is warranted.Example 2: In the following example, the given data is not protected (accessible anytime the device is powered on):
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionNone]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionNone);
...
kSecAttrAccessible
key in the Keychain attribute dictionary. The definitions for the various Keychain accessibility constants are as follows:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
results in encryption using a key derived solely based on the device's UID. This leaves such files accessible any time the device is powered on, including when locked with a passcode or when booting. As such, usages of kSecAttrAccessibleAlways
should be carefully reviewed to determine if further protection with a stricter Keychain accessibility level is warranted.
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
key in the Keychain attribute dictionary. The definitions for the various Keychain accessibility constants are as follows:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
results in encryption using a key derived solely based on the device's UID. This leaves such files accessible any time the device is powered on, including when locked with a passcode or when booting. As such, usages of kSecAttrAccessibleAlways
should be carefully reviewed to determine if further protection with a stricter Keychain accessibility level is warranted.
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
SecItemAdd(query as CFDictionary, nil)
...
Realm
database:
Realm realm = Realm.getDefaultInstance();
Realm
database:
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
Realm
database:
let realm = try! Realm()
UIImageWriteToSavedPhotosAlbum
to save images to the photo album:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
...
}
UIImageWriteToSavedPhotosAlbum
to save images to the photo album:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
// Save image
UIImageWriteToSavedPhotosAlbum(pickedImage!, self, nil, nil)
dismissViewControllerAnimated(true, completion: nil)
}
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
, then if your device gets stolen and a passcode is set, the theft will need to unlock the device in order for the Keychain items to be decrypted. Failing to enter the right passcode will block the theft from decrypting the Keychain items. However, if the passcode is not set, the attacker just needs to slide his finger to unlock the device and get the Keychain to decrypt its items. Therefore, failing to enforce a passcode in the device may weaken the Keychain encryption mechanism.
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
, then if your device gets stolen and a passcode is set, the theft will need to unlock the device in order for the Keychain items to be decrypted. Failing to enter the right passcode will block the theft from decrypting the Keychain items. However, if the passcode is not set, the attacker just needs to slide his finger to unlock the device and get the Keychain to decrypt its items. Therefore, failing to enforce a passcode in the device may weaken the Keychain encryption mechanism.
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
SecItemAdd(query as CFDictionary, nil)
...