permissions := strconv.Atoi(os.Getenv("filePermissions"));
fMode := os.FileMode(permissions)
os.chmod(filePath, fMode);
...
String permissionMask = System.getProperty("defaultFileMask");
Path filePath = userFile.toPath();
...
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(permissionMask);
Files.setPosixFilePermissions(filePath, perms);
...
$rName = $_GET['publicReport'];
chmod("/home/". authenticateUser . "/public_html/" . rName,"0755");
...
publicReport
提供恶意值(例如,../../localuser/public_html/.htpasswd
),那么应用程序将允许攻击者读取指定文件。
...
$mask = $CONFIG_TXT['perms'];
chmod($filename,$mask);
...
permissions = os.getenv("filePermissions");
os.chmod(filePath, permissions);
...
...
rName = req['publicReport']
File.chmod("/home/#{authenticatedUser}/public_html/#{rName}", "0755")
...
publicReport
提供恶意值(例如,../../localuser/public_html/.htpasswd
),那么应用程序将允许攻击者读取指定文件。
...
mask = config_params['perms']
File.chmod(filename, mask)
...
services-config.xml
描述符文件会指定一个“Logging”XML 元素来描述日志记录的不同方面。它类似于以下内容:
<logging>
<target class="flex.messaging.log.ConsoleTarget" level="Debug">
<properties>
<prefix>[BlazeDS]</prefix>
<includeDate>false</includeDate>
<includeTime>false</includeTime>
<includeLevel>false</includeLevel>
<includeCategory>false</includeCategory>
</properties>
<filters>
<pattern>Endpoint.*</pattern>
<pattern>Service.*</pattern>
<pattern>Configuration</pattern>
</filters>
</target>
</logging>
target
标签可采用一个名为 level
的可选属性,用来指示日志级别。如果调试级别设置为太详细的级别,您的应用程序可能会将敏感数据写入日志文件。sprintf()
、FormatMessageW()
或 syslog()
。snprintf()
将一个命令行参数复制到缓冲区中。
int main(int argc, char **argv){
char buf[128];
...
snprintf(buf,128,argv[1]);
}
%x
)来读取堆栈中的内容,然后函数会作为即将格式化的参数使用。(在本例中,函数没有采用任何即将格式化的参数。)通过使用 %n
格式化指令,攻击者能够对堆栈进行写入,进而使 snprintf()
记下迄今为止输出的字节数,并将其传送给指定的参数(而不是直接从参数中读取数值,这是程序员最初设计的行为)。对于这种攻击,更为的复杂的形式是使用四条交错的写入来完全控制堆栈中某个指针的值。
printf("%d %d %1$d %1$d\n", 5, 9);
5 9 5 5
Example 1
中所述。syslog()
函数有时候可以这样使用:
...
syslog(LOG_ERR, cmdBuf);
...
syslog()
的第二个参数是格式字符串,因此 cmdBuf
中的任何格式化指令都会按照Example 1
中所述进行解释。syslog()
的正确使用方式:
...
syslog(LOG_ERR, "%s", cmdBuf);
...
sprintf()
、FormatMessageW()
、syslog()
、NSLog
或 NSString.stringWithFormat
示例 1:下面的代码将命令行参数作为 NSString.stringWithFormat:
中的 format string。
int main(int argc, char **argv){
char buf[128];
...
[NSString stringWithFormat:argv[1], argv[2] ];
}
%x
)来读取堆栈中的内容,然后函数会作为即将格式化的参数使用。(在本例中,函数没有采用任何即将格式化的参数。)
printf("%d %d %1$d %1$d\n", 5, 9);
5 9 5 5
Example 1
中所述。syslog()
函数有时候可以这样使用:
...
syslog(LOG_ERR, cmdBuf);
...
syslog()
的第二个参数是格式字符串,因此 cmdBuf
中的任何格式化指令都会按照Example 1
中所述进行解释。syslog()
的正确使用方式:示例 4:Apple 核心类提供了利用 format string 漏洞的有趣途径。
...
syslog(LOG_ERR, "%s", cmdBuf);
...
String.stringByAppendingFormat()
函数有时候可以这样使用:
...
NSString test = @"Sample Text.";
test = [test stringByAppendingFormat:[MyClass
formatInput:inputControl.text]];
...
stringByAppendingFormat()
的正确使用方式:
...
NSString test = @"Sample Text.";
test = [test stringByAppendingFormat:@"%@", [MyClass
formatInput:inputControl.text]];
...
strncpy()
),使用方式不正确也会引发漏洞。对内存的处理加之有关数据段大小和结构方面所存在种种错误假设,是导致大多数 buffer overflow 漏洞产生的根源。
void wrongNumberArgs(char *s, float f, int d) {
char buf[1024];
sprintf(buf, "Wrong number of %.512s");
}
strncpy()
),使用方式不正确也会引发漏洞。对内存的处理加之有关数据段大小和结构方面所存在种种错误假设,是导致大多数 buffer overflow 漏洞产生的根源。%d
格式说明符将一个浮点转换为 f
。
void ArgTypeMismatch(float f, int d, char *s, wchar *ws) {
char buf[1024];
sprintf(buf, "Wrong type of %d", f);
...
}
script
标签。
<script src="http://www.example.com/js/fancyWidget.js"></script>
www.example.com
以外的网站中,则该站点将依赖 www.example.com
来运行正确的非恶意代码。如果攻击者可以入侵 www.example.com
,则他们可以篡改 fancyWidget.js
的内容,损害站点安全。例如,他们可以将代码添加到 fancyWidget.js
中,窃取用户的机密数据。allowBackup
属性设置为 true
(默认值),并在 <application>
标签上定义 backupAgent
属性。Environment.getExternalStorageDirectory()
会返回对 Android 设备的外部存储的引用。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
,那么该项目将备份到 iCloud,并且即便在使用可恢复到任意设备的未加密备份的情况下仍然会备份到 iTunes。这可能会导致隐私问题,具体取决于所存储数据的敏感和私密程度。
...
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
,那么该项目将备份到 iCloud,并且即便在使用可恢复到任意设备的未加密备份的情况下仍然会备份到 iTunes。这可能会导致隐私问题,具体取决于所存储数据的敏感和私密程度。
...
// 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*
文件中。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
文件中。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
文件中。 URLCache
类的 diskCapacity
或 memoryCapacity
属性设置为 0,就能成功禁用 HTTP(S) 响应缓存系统。但是,NSURLCache
文档指出,只有在设备的内存或磁盘空间不足的情况下,才会将磁盘和内存缓存缩减到配置的大小。这两项设置都是系统用来释放其资源以提高性能的,而非用于安全控制。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
文件中。 URLCache
类的 diskCapacity
或 memoryCapacity
属性设置为 0,就能成功禁用 HTTP(S) 响应缓存系统。但是,NSURLCache
文档指出,只有在设备的内存或磁盘空间不足的情况下,才会将磁盘和内存缓存缩减到配置的大小。这两项设置都是系统用来释放其资源以提高性能的,而非用于安全控制。NSFileManager
的数据保护类会定义为常量,以便在与 NSFileManager
实例相关联的 NSDictionary
中指定为 NSFileProtectionKey
键的值,并可通过使用 NSFileManager
函数(包括 setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
和 createFileAtPath:contents:attributes:
)创建文件或修改其数据保护类。此外,NSData
对象的相应数据保护常量会定义为 NSDataWritingOptions
,并可将其作为 options
参数传递到 NSData
函数 writeToURL:options:error:
和 writeToFile:options:error:
。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
标记一个文件,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
的用法进行仔细审核,以确定是否需要使用 NSFileProtectionComplete
执行进一步保护。例 2:以下例子中,给定的数据仅在用户首次打开设备和提供密码前受保护(直到下次重新引导):
...
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
中定义为常量,以便在与 NSFileManager
实例相关联的 Dictionary
中指定为 NSFileProtectionKey
密钥的值,而且通过使用 NSFileManager
函数(包括 setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
和 createFileAtPath(_:contents:attributes:)
),可以创建文件或者修改其数据保护级别。此外,已在 NSDataWritingOptions
枚举中定义了 NSData
对象的相应数据保护常量,它可以作为 options
参数传递到 NSData
函数(
writeToFile(_:options:)
)。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
标记一个文件,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 NSFileProtectionCompleteUnlessOpen
或 NSFileProtectionCompleteUntilFirstUserAuthentication
的用法进行仔细审核,以确定是否需要使用 NSFileProtectionComplete
执行进一步保护。示例 2:在以下示例中,给定数据仅在用户首次打开设备和提供密码前受保护(直到下次重新引导):
...
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
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
标记一个密钥链项目,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 kSecAttrAccessibleAfterFirstUnlock
的用法进行仔细审核,以确定是否需要执行进一步保护。
...
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
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
标记一个密钥链项目,就会使用从用户密码或设备 UID 派生的密钥对其进行加密,但在某些情况下依然可以访问数据。因此,应该对 kSecAttrAccessibleAfterFirstUnlock
的用法进行仔细审核,以确定是否需要执行进一步保护。
...
// 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
的数据保护类会定义为常量,以便在与 NSFileManager
实例相关联的 NSDictionary
中指定为 NSFileProtectionKey
键的值,并可通过使用 NSFileManager
函数(包括 setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
和 createFileAtPath:contents:attributes:
)创建文件或修改其数据保护类。此外,NSData
对象的相应数据保护常量会定义为 NSDataWritingOptions
,并可将其作为 options
参数传递到 NSData
函数 writeToURL:options:error:
和 writeToFile:options:error:
。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 NSFileProtectionNone
的用法进行仔细审核,以确定是否需要执行更严格的数据保护。例 2:在以下例子中,给定数据不受保护(设备打开时可随时访问):
...
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
中定义为常量,以便在与 NSFileManager
实例相关联的 Dictionary
中指定为 NSFileProtectionKey
密钥的值。通过使用 NSFileManager
函数(包括 setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
和 createFileAtPath(_:contents:attributes:)
),可以创建文件或者修改其数据保护级别。此外,已在 NSDataWritingOptions
枚举中定义了 NSData
对象的相应数据保护常量,它可以作为 options
参数传递到 NSData
函数(例如
writeToFile(_:options:)
)。NSFileManager
和 NSData
的各种数据保护类常量定义如下:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 NSFileProtectionNone
的用法进行仔细审核,以确定是否需要执行更严格的数据保护。示例 2:在以下示例中,给定数据不受保护(设备打开时可随时访问):
...
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
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 kSecAttrAccessibleAlways
的用法进行仔细审核,以确定是否需要执行更严格的密钥链可访问性级别。
...
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
键的值。下面列出了各种密钥链可访问性常量的定义:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
结果。这使此文件在设备打开时随时可以进行访问,包括用密码锁定或正在引导时。因此,应该对 kSecAttrAccessibleAlways
的用法进行仔细审核,以确定是否需要执行更严格的密钥链可访问性级别。
...
// 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
数据库的连接:
Realm realm = Realm.getDefaultInstance();
Realm
数据库的连接:
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
Realm
数据库的连接:
let realm = try! Realm()
UIImageWriteToSavedPhotosAlbum
将图像保存到相册:
- (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
将图像保存到相册:
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
等较安全的策略存储,那么如果您的设备在设置了密码的情况下被盗,则盗窃者需要解锁设备才能将密钥链项目解除锁定。如果无法输入正确的密码,盗窃者便无法解密密钥链项目。但是,如果没有设置密码,则攻击者只需滑动手指即可对设备解除锁定,并获得密钥链来解密其项目。因此,如果不强制要求为设备设置密码,则可能会削弱密钥链加密机制的安全性。
...
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
等较安全的策略存储,那么如果您的设备在设置了密码的情况下被盗,则盗窃者需要解锁设备才能将密钥链项目解除锁定。如果无法输入正确的密码,盗窃者便无法解密密钥链项目。但是,如果没有设置密码,则攻击者只需滑动手指即可对设备解除锁定,并获得密钥链来解密其项目。因此,如果不强制要求为设备设置密码,则可能会削弱密钥链加密机制的安全性。
...
// 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)
...
setPersistent:YES
创建命名粘贴板并将其配置为永久。
...
UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:@"myPasteboard" create:YES];
[pasteboard setPersistent:YES];
...
setPersistent(true)
创建命名粘贴板并将其配置为永久。
...
let pasteboard = UIPasteboard(name: UIPasteboard.Name(rawValue: "myPasteboard"), create: true)!
pasteboard.setPersistent(true)
...