软件安全不是安全软件。此处我们关注的主题包括身份验证、Access Control、机密性、加密和权限管理。
pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = credentials[0];
String password = credentials[1];
Intent i = new Intent();
i.setAction("SEND_CREDENTIALS");
i.putExtra("username", username);
i.putExtra("password", password);
view.getContext().sendBroadcast(i);
}
});
...
SEND_CREDENTIALS
收听的注册接收者都将收到消息。即使权限限制接收者人数,广播也不会受到保护;既然这样,我们也不建议将权限作为修复方式使用。FileIOPermissions
。
...
String permissionsXml = GetPermissionsFromXmlFile();
FileIOPermission perm = new FileIOPermission(PermissionState.None);
perm.FromXml(permissionsXml);
perm.Demand();
...
...
CrytoKeyAuditRule auditRule = new CryptoKeyAuditRule(IdRef, (CryptoKeyRights) input, AuditFlags.Success);
...
input
,则他们可以指定能够记录的操作类型。如果用户可以将此操纵到 CryptoKeyRights.Delete
,则他们也许能够读取加密密钥而不记录它,这样您不会意识到攻击者已盗取您的加密密钥。
...
uid = 'scott'.
password = 'tiger'.
WRITE: / 'Default username for FTP connection is: ', uid.
WRITE: / 'Default password for FTP connection is: ', password.
...
pass = getPassword();
...
trace(id+":"+pass+":"+type+":"+tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
...
ResetPasswordResult passRes = System.resetPassword(id1, true);
System.Debug('New password: '+passRes.getPassword());
...
pass = GetPassword();
...
dbmsLog.WriteLine(id+":"+pass+":"+type+":"+tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。get_password()
函数可以从存储的其他值中返回一个由用户提供的、与该用户帐户相关的明文密码。
pass = get_password();
...
fprintf(dbms_log, "%d:%s:%s:%s", id, pass, type, tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储所有数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
...
MOVE "scott" TO UID.
MOVE "tiger" TO PASSWORD.
DISPLAY "Default username for database connection is: ", UID.
DISPLAY "Default password for database connection is: ", PASSWORD.
...
Session.pword
变量还包含与该帐户相关的明文密码。
<cflog file="app_log" application="No" Thread="No"
text="#Session.uname#:#Session.pword#:#type#:#Now()#">
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
var pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。GetPassword()
函数的返回值,该函数会返回与该帐户关联且由用户提供的明文密码。
pass = GetPassword();
...
if err != nil {
log.Printf('%s: %s %s %s', id, pass, type, tsstamp)
}
Example 1
中的代码会将明文密码记录到应用程序的事件日志中。虽然许多开发人员认为事件日志是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
pass = getPassword();
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp);
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
...
webview.setWebViewClient(new WebViewClient() {
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
String username = credentials[0];
String password = credentials[1];
Intent i = new Intent();
i.setAction("SEND_CREDENTIALS");
i.putExtra("username", username);
i.putExtra("password", password);
view.getContext().sendBroadcast(i);
}
});
...
SEND_CREDENTIALS
收听的注册接收者都将收到消息。即使权限限制接收者人数,广播也不会受到保护;既然这样,我们也不建议将权限作为修复方式使用。
localStorage.setItem('password', password);
pass = getPassword()
...
dbmsLog.println("$id:$pass:$type:$tstamp")
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
...
webview.webViewClient = object : WebViewClient() {
override fun onReceivedHttpAuthRequest(view: WebView,
handler: HttpAuthHandler, host: String, realm: String
) {
val credentials = view.getHttpAuthUsernamePassword(host, realm)
val username = credentials!![0]
val password = credentials[1]
val i = Intent()
i.action = "SEND_CREDENTIALS"
i.putExtra("username", username)
i.putExtra("password", password)
view.context.sendBroadcast(i)
}
}
...
SEND_CREDENTIALS
收听的注册接收者都将收到消息。即使权限限制接收者人数,广播也不会受到保护;既然这样,我们也不建议将权限作为修复方式使用。
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
// Configure the new event with information from the location
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *latitude = [NSString stringWithFormat:@"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:@"%f", coordinate.longitude];
NSLog(@"dLatitude : %@", latitude);
NSLog(@"dLongitude : %@",longitude);
NSString *urlWithParams = [NSString stringWithFormat:TOKEN_URL, latitude, longitude];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlWithParams]];
[request setHTTPMethod:@"GET"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Add password to user defaults
[defaults setObject:@"Super Secret" forKey:@"passwd"];
[defaults synchronize];
getPassword()
函数的返回值,该函数会返回与该帐户关联且由用户提供的明文密码。
<?php
$pass = getPassword();
trigger_error($id . ":" . $pass . ":" . $type . ":" . $tstamp);
?>
Example 1
中的代码会将明文密码记录到应用程序的事件日志中。虽然许多开发人员认为事件日志是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。OWA_SEC.get_password()
函数会返回一个与用户帐户相关并且由用户提供的明文密码,这个密码将输出给 HTTP 响应。
...
HTP.htmlOpen;
HTP.headOpen;
HTP.title (.Account Information.);
HTP.headClose;
HTP.bodyOpen;
HTP.br;
HTP.print('User ID: ' ||
OWA_SEC.get_user_id || '');
HTP.print('User Password: ' ||
OWA_SEC.get_password || '');
HTP.br;
HTP.bodyClose;
HTP.htmlClose;
...
getPassword()
函数的返回值,该函数会返回与该帐户关联且由用户提供的明文密码。
pass = getPassword();
logger.warning('%s: %s %s %s', id, pass, type, tsstamp)
Example 1
中的代码会将明文密码记录到应用程序的事件日志中。虽然许多开发人员认为事件日志是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。get_password()
函数可以返回一个由用户提供的、与用户帐号相关的明文密码。
pass = get_password()
...
dbms_logger.warn("#{id}:#{pass}:#{type}:#{tstamp}")
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
val pass = getPassword()
...
dbmsLog.println(id+":"+pass+":"+type+":"+tstamp)
Example 1
中的代码会将明文密码记录到文件系统中。虽然许多开发人员认为文件系统是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。
import CoreLocation
...
var locationManager : CLLocationManager!
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"
seenError = false
locationFixAchieved = false
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
...
if let location: CLLocation! = locationManager.location {
var coordinate : CLLocationCoordinate2D = location.coordinate
let latitude = NSString(format:@"%f", coordinate.latitude)
let longitude = NSString(format:@"%f", coordinate.longitude)
NSLog("dLatitude : %@", latitude)
NSLog("dLongitude : %@",longitude)
let urlString : String = "http://myserver.com/?lat=\(latitude)&lon=\(longitude)"
let url : NSURL = NSURL(string:urlString)
let request : NSURLRequest = NSURLRequest(URL:url)
var err : NSError?
var response : NSURLResponse?
var data : NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&err)
} else {
println("no location...")
}
let defaults : NSUserDefaults = NSUserDefaults.standardUserDefaults()
// Add password to user defaults
defaults.setObject("Super Secret" forKey:"passwd")
defaults.synchronize()
getPassword
函数可以从存储的其他值中返回一个由用户提供的、与该用户帐户相关的明文密码。
pass = getPassword
...
App.EventLog id & ":" & pass & ":" & type & ":" &tstamp, 4
...
Example 1
中的代码会将明文密码记录到应用程序的事件日志中。虽然许多开发人员认为事件日志是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。AppSearch
代码访问。
...
// Document object to index
val doc = Doc(
namespace="user1",
id="noteId",
score=10,
text="This document contains private data"
)
// Adding document object to AppSearch index
val putRequest = PutDocumentsRequest.Builder().addDocuments(doc).build()
SharedPreferences
类保存在物理 Android 设备上。password
以明文形式存储在设备上。
SharedPreferences userPreferences = this.getSharedPreferences("userPreferences", MODE_WORLD_READABLE);
SharedPreferences.Editor editor = userPreferences.editor();
editor.putString("username", userName);
editor.putString("password", password);
...
editor.language("language", language);
...
SharedPreferences
实例是应用程序专用的,无法由其他应用程序访问,但对该设备进行物理访问时可能会允许访问这些文件。此外,在Example 1
中,如果将模式设为 MODE_WORLD_READABLE
,则会使首选项文件可供其他应用程序使用,从而会进一步侵犯用户隐私。
MIDDLEWARE = (
...
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.gzip.GZipMiddleware',
...
)
...
HKHealthStore healthStore = new HKHealthStore();
HKBloodTypeObject blood = healthStore.GetBloodType(null);
NSLog("%@", blood.BloodType);
var urlWithParams = String.format(TOKEN_URL, block.BloodType);
var responseString = await client.GetStringAsync(urlWithParams);
...
NSLog
函数所处的等级更低,开发人员可借助前者创建能够读取设备上所有日志的应用程序,即便他们并不拥有其他应用程序也是如此。
...
HKHealthStore healthStore = new HKHealthStore();
HKBloodTypeObject blood = healthStore.GetBloodType(null);
// Add blood type to user defaults
NSUserDefaults.StandardUserDefaults.SetString(blood.BloodType, "bloodType");
...
...
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
HKBloodTypeObject *blood = [healthStore bloodTypeWithError:nil];
NSLog(@"%@", [blood bloodType]);
NSString *urlWithParams = [NSString stringWithFormat:TOKEN_URL, [blood bloodType]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlWithParams]];
[request setHTTPMethod:@"GET"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
...
NSLog
函数位于更底层的位置,开发者可借助前者创建能够读取设备上所有日志的应用程序,即便他们并不拥有其他应用程序。
...
HKHealthStore *healthStore = [[HKHealthStore alloc] init];
HKBloodTypeObject *blood = [healthStore bloodTypeWithError:nil];
// Add blood type to user defaults
[defaults setObject:[blood bloodType] forKey:@"bloodType"];
[defaults synchronize];
...
...
let healthStore = HKHealthStore()
let blood = try healthStore.bloodType()
print(blood.bloodType)
let urlString : String = "http://myserver.com/?data=\(blood.bloodType)"
let url : NSURL = NSURL(string:urlString)
let request : NSURLRequest = NSURLRequest(URL:url)
var err : NSError?
var response : NSURLResponse?
var data : NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error:&err)
...
NSLog
函数位于更底层的位置,开发者可借助前者创建能够读取设备上所有日志的应用程序,即便他们并不拥有其他应用程序。
...
let healthStore = HKHealthStore()
let blood = try healthStore.bloodType()
print(blood.bloodType)
// Add blood type to user defaults
defaults.setObject("BloodType" forKey:blood.bloodType)
defaults.synchronize()
...
String
对象中。
public static String getPassword() {
String inputPassword = "";
ConsoleKeyInfo nextKey = Console.ReadKey(true);
while (nextKey.Key != Console.ReadKey(true)) {
inputPassword.AppendChar(nextKey.KeyChar);
Console.Write("*");
nextKey = Console.ReadKey(true);
}
return inputPassword;
}
String
是一个不可改变的对象,所以无法使内容失效,这意味着在进行垃圾回收之前能够检查堆的任何人都可以获得敏感数据。String
对象中使系统无法从内存中可靠地清除数据。String
存储敏感数据,因为 String
对象不可改变,只有 JVM 垃圾收集器才能从内存中删除 String
的值,只能由 JVM 垃圾收集器完成。由于除非 JVM 内存不足,否则不需要运行垃圾收集器,因此无法保证垃圾收集何时发生。如果应用程序崩溃,则应用程序的内存转储可能会泄露敏感数据。String
。
private JPasswordField pf;
...
final char[] password = pf.getPassword();
...
String passwordAsString = new String(password);
String
对象中使系统无法从内存中可靠地清除数据。String
用于存储敏感数据,但是因为 String
对象不可改变,所以为其指定新值将创建新的String
并为所指定对象分配新对象的引用。原始值将保留在内存中,直到ARC
(自动引用计数)取消分配对象并释放其内存。Swift 在对象的生命周期方面不作保证,其在最近的周边作用域结束时完成。如果攻击者在取消分配对象之前转储内存内容,则可以读取内容。String
在内存中存储密码。
let password = passwordTextField.text!
// use the password
GET
(而非 POST
)方法将数据发送到服务器。GET
方法的 HTTP 请求允许将 URL 和请求参数缓存到浏览器的 URL 缓存、中间代理和服务器日志中。这可能将敏感信息泄露给不具备相应数据权限的人。示例 2:如果应用程序使用 NSURLRequest,则默认的 HTTP 方法为 GET。
...
NSString * const USER_URL = @"https://www.somesvr.com/someapp/user";
...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:USER_URL]];
[request setHTTPMethod:@"GET"];
...
...
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [[NSMutableData data] retain];
} else {
...
GET
(而非 POST
)方法将数据发送到服务器。GET
方法的 HTTP 请求允许将 URL 和请求参数缓存到浏览器的 URL 缓存、中间代理和服务器日志中。这可能将敏感信息泄露给不具备相应数据权限的人。
...
$client = new Zend_Http_Client('https://www.example.com/fetchdata.php');
$client->request(Zend_Http_Client::GET);
...
GET
(而非 POST
)方法将数据发送到服务器。GET
方法的 HTTP 请求允许将 URL 和请求参数缓存到浏览器的 URL 缓存、中间代理和服务器日志中。这可能将敏感信息泄露给不具备相应数据权限的人。示例 2:如果应用程序使用 NSURLRequest,则默认的 HTTP 方法为 GET。
...
let url = NSURL(string: "https://www.somesvr.com/someapp/user")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
let connection = NSURLConnection(request:request, delegate:self)
...
...
let url = NSURL(string: "https://www.somesvr.com/someapp/user")
let request = NSURLRequest(URL: url!)
let connection = NSURLConnection(request:request, delegate:self)
...
NSURLCredential
,该凭据会分发到所有已同步的设备并存储到 Apple 的 iCloud 环境中。NSURLCredential
实例时,需要定义持久性属性。该属性可能的值如下:NSURLCredentialPersistenceNone
:不应保存凭据。NSURLCredentialPersistenceForSession
:只应为此会话存储凭据。NSURLCredentialPersistencePermanent
:应将凭据存储在密钥链中。NSURLCredentialPersistenceSynchronizable
:应将凭据永久存储在密钥链中,此外还应根据所拥有的 Apple ID 分配给其他设备。NSURLCredentialPersistenceSynchronizable
属性说明凭据将会分发,并且会存储到 Apple 的云环境中。将凭据存储在 Apple 的云环境中可能并不是可接受的情况,具体取决于应用程序的隐私要求。
...
NSURLCredential *credential = [NSURLCredential credentialWithUser:user password:password persistence:NSURLCredentialPersistenceSynchronizable];
NSURLCredentialStorage *shared = [NSURLCredentialStorage sharedCredentialStorage];
[shared setDefaultCredential:credential forProtectionSpace:protectionSpace];
...
NSURLCredential
,该凭据会分发到所有已同步的设备并存储到 Apple 的 iCloud 环境中。NSURLCredential
实例时,需要定义持久性属性。该属性可能的值如下:NSURLCredentialPersistenceNone
:不应保存凭据。NSURLCredentialPersistenceForSession
:只应为此会话存储凭据。NSURLCredentialPersistencePermanent
:应将凭据存储在密钥链中。NSURLCredentialPersistenceSynchronizable
:应将凭据永久存储在密钥链中,此外还应根据所拥有的 Apple ID 分配给其他设备。NSURLCredentialPersistenceSynchronizable
属性说明凭据将会分发,并且会存储到 Apple 的云环境中。将凭据存储在 Apple 的云环境中可能并不是可接受的情况,具体取决于应用程序的隐私要求。
...
let credential = NSURLCredential(user:foo, password:password, persistence:.Synchronizable)
let shared = NSURLCredentialStorage.sharedCredentialStorage()
shared.setCredential(credential, forProtectionSpace:protectionSpace)
...
SensitiveXMLData
生成敏感财务信息图表的 DataVisualization
控件实例化:
<asp:Chart ID="Chart1" runat="server" ImageLocation="~/Temporary/Graph"
ImageType="Jpeg" DataSourceID="SensitiveXMLData" ImageStorageMode="UseImageLocation">
<series>
.
.
.
</series>
<chartareas>
<asp:ChartArea Name="ChartArea1">
</asp:ChartArea>
</chartareas>
</asp:Chart>
Example 1
中的代码会指示 Chart
控件生成柱状图的 JPEG 图像,并将其写入临时目录 ~/Temporary/Graph
中。在该控件将此图像写入磁盘后,用户浏览器随后会对该文件发起一次请求,并将其显示给用户。该图像未安全写入磁盘。此外,该代码会假定底层基础架构会保护该文件,使其免受其他用户未经授权的访问。NSURLCredential
实例,但未能删除存储在其他设备和 iCloud 上的副本。NSURLCredential
实例时,需要定义持久性属性。该属性可能的值如下:NSURLCredentialPersistenceNone
:不应保存凭据。NSURLCredentialPersistenceForSession
:只应为此会话存储凭据。NSURLCredentialPersistencePermanent
:应将凭据存储在密钥链中。NSURLCredentialPersistenceSynchronizable
:应将凭据永久存储在密钥链中,此外还应根据所拥有的 Apple ID 分配给其他设备。NSURLCredentialPersistenceSynchronizable
凭据会分发到其他设备和 iCloud,如果未能从所有位置完全删除该凭据,将留下可能会泄露的实例。
...
// Create the credential
NSURLCredential *credential = [NSURLCredential credentialWithUser:user password:password persistence:NSURLCredentialPersistenceSynchronizable];
NSURLCredentialStorage *shared = [NSURLCredentialStorage sharedCredentialStorage];
[shared setDefaultCredential:credential forProtectionSpace:protectionSpace];
// Use the credential as needed
...
// Removes the credential
[shared removeCredential:credential forProtectionSpace:protectionSpace];
...
NSURLCredential
实例,但未能删除存储在其他设备和 iCloud 上的副本。NSURLCredential
实例时,需要定义持久性属性。该属性可能的值如下:NSURLCredentialPersistenceNone
:不应保存凭据。NSURLCredentialPersistenceForSession
:只应为此会话存储凭据。NSURLCredentialPersistencePermanent
:应将凭据存储在密钥链中。NSURLCredentialPersistenceSynchronizable
:应将凭据永久存储在密钥链中,此外还应根据所拥有的 Apple ID 分配给其他设备。NSURLCredentialPersistenceSynchronizable
凭据会分发到其他设备和 iCloud,如果未能从所有位置完全删除该凭据,将留下可能会泄露的实例。
...
// Create the credential
let credential = NSURLCredential(user:foo, password:password, persistence:.Synchronizable)
let shared = NSURLCredentialStorage.sharedCredentialStorage()
shared.setCredential(credential, forProtectionSpace:protectionSpace)
// Use the credential as needed
...
// Removes the credential
shared.removeCredential(credential, forProtectionSpace:protectionSpace)
...
MyCreditCard
键还会存储由用户提供的、与该帐户相关的纯文本信用卡卡号。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>password</key>
<string>BASICSECRET</string>
<key>credentials</key>
<dict>
<key>pin</key>
<string>2345</string>
<key>MyCreditCard</key>
<string>1111 11 2321 1112</string>
<key>MysSn</key>
<string>1111-22-3333</string>
<key>ssn</key>
<string>2345-22-3345</string>
<key>userid</key>
<string>12345</string>
</dict>
</dict>
</plist>
Example 1
中的代码会将移动设备中的私人信息存储在该设备上的一个不受支持的 plist 文件中。虽然许多开发人员认为 plist 文件是存储所有数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时,因为 plist 文件可被持有该设备的任何人读取。
ViewController.h
...
@property (nonatomic, retain) IBOutlet UITextField *ssnField;
...
Example 1
中的代码指示该应用程序使用了收集敏感信息的输入控件。由于 iOS 会将输入缓存到文本字段以改善其自动更正功能的性能,因此最近输入到此类输入控件中的任何信息可能会被缓存到保存到文件系统的键盘缓存文件中。由于键盘缓存文件存储在设备上,因此如果该设备丢失,该文件可能被恢复,从而导致泄露其中包含的任何敏感信息。
...
@IBOutlet weak var ssnField: UITextField!
...
Example 1
中的代码指示该应用程序使用了收集敏感信息的输入控件。由于 iOS 会将输入缓存到文本字段以改善其自动更正功能的性能,因此最近输入到此类输入控件中的任何信息可能会被缓存到保存到文件系统的键盘缓存文件中。由于键盘缓存文件存储在设备上,因此如果该设备丢失,该文件可能被恢复,从而导致泄露其中包含的任何敏感信息。
ViewController.h
...
@property (nonatomic, retain) IBOutlet UITextField *ssnField;
...
Example 1
中的代码指示该应用程序使用了收集敏感信息的输入控件。由于 iOS 会捕获应用程序在后台运行时其活动视图的屏幕截图以改善动画性能,因此在后台事件期间在此类输入控件中显示的任何信息都可能会被缓存在保存到文件系统的图像内。由于这些屏幕缓存屏幕截图存储在设备上,因此如果该设备丢失,这些屏幕截图可能被恢复,从而导致泄露其中包含的任何敏感信息。
...
@IBOutlet weak var ssnField: UITextField!
...
Example 1
中的代码指示该应用程序使用了收集敏感信息的输入控件。由于 iOS 会捕获应用程序在后台运行时其活动视图的屏幕截图以改善动画性能,因此在后台事件期间在此类输入控件中显示的任何信息都可能会被缓存在保存到文件系统的图像内。由于这些屏幕缓存屏幕截图存储在设备上,因此如果该设备丢失,这些屏幕截图可能被恢复,从而导致泄露其中包含的任何敏感信息。Documents
目录。Documents
目录用于存储非瞬态的应用程序数据,例如用户创建的内容或本地信息,以便使应用程序能够以离线模式运行。如果在应用程序的 Info.plist
文件中设置了 UIFileSharingEnabled
,那么该目录中的文件便可以通过 iTunes 访问。如果将敏感数据写入 Documents
目录,这些数据可能会通过未加密的备份或 iTunes 接口泄露。Documents
目录中:
...
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *passwd_path = [docsDirectory stringByAppendingPathComponent:@"passwords.txt"];
NSString *password = [user password];
[password writeToFile:passwd_path atomically:YES encoding:NSUTF8StringEncoding error:nil];
...
Documents
目录。Documents
目录用于存储非瞬态的应用程序数据,例如用户创建的内容或本地信息,以便使应用程序能够以离线模式运行。如果在应用程序的 Info.plist
文件中设置了 UIFileSharingEnabled
,那么该目录中的文件便可以通过 iTunes 访问。如果将敏感数据写入 Documents
目录,这些数据可能会通过未加密的备份或 iTunes 接口泄露。Documents
目录中:
let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let passwd_path = NSURL(fileURLWithPath: documents).URLByAppendingPathComponent("secret.txt")
let password = getUserPassword()
try password.writeToURL(passwd_path, atomically:true, encoding: NSUTF8StringEncoding)
DataType
指定为密码,这表示在显示时,系统会默认显示该属性:
public class User
{
[Required]
public int ID { get; set; }
public string Title { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime DateOfEmployment { get; set; }
[DataType(DataType.Currency)]
public decimal Salary { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
...
}
Example 1
中的 Password
属性未指定 [DataType(DataType.Password)]
属性,因此默认情况下在 UI 中显示不会隐藏它。TextField
小组件在用户在输入提示符处输入密码时不会对用户密码进行模糊处理:
class SelectionContainerDisabledExampleApp extends StatelessWidget {
const SelectionContainerDisabledExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: "Please enter your password",
),
),
],
),
),
),
);
}
}
Example 1
中的 TextField
小组件是在 obscureText
属性设置为 true
的情况下进行实例化的,因此,当用户在“请输入您的密码:”提示符处输入密码时,该密码不会进行模糊显示。PasswordCallback pc = new PasswordCallback("Please enter your password: ", true);
Example 1
中的 pc
是在其第二个参数 onEcho
设置为 true
的情况下进行实例化的,因此,当用户在“请输入您的密码:”提示下输入密码时,该密码不会进行模糊显示。
ViewController.h:
...
@property (nonatomic, retain) IBOutlet UITextField *passwordField;
...
ViewController.m:
...
NSString *password = _passwordField.text;
...
Example 1
中的 passwordField
未将其 secureTextEntry
属性设置为 true
,因此当用户向文本字段中键入密码时,其密码不会进行模糊显示。
...
@IBOutlet weak var passwordField: UITextField!
...
let password = passwordField.text
...
Example 1
中的 passwordField
未将其 secureTextEntry
属性设置为 true
,因此当用户向文本字段中键入密码时,其密码不会进行模糊显示。
from oslo_config import cfg
...
opts = [
cfg.StrOpt('admin_password',secret=False,
help="User's password")]
...
grp = cfg.OptGroup('mygroup')
cfg.CONF.register_opts(opts, group=grp)
...
logger.warning("Adding %s" % cfg.CONF.mygroup.admin_password)
Example 1
中的代码将 admin_password
以明文(未屏蔽)形式写入日志输出,因为 secret
的值设置为 False
。虽然许多开发人员认为事件日志是存储数据的安全位置,但这不是绝对的,特别是涉及到隐私问题时。