ソフトウェアのセキュリティは、セキュリティ ソフトウェアではありません。ここでは、認証、アクセス制御、機密性、暗号化、権限管理などのトピックについて説明します。
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
オブジェクトは不変であるため、メモリから String
の値を削除できるのは JVM ガベージ コレクターのみです。JVM のメモリが不足しない限り、ガベージ コレクターを実行する必要はありません。そのため、ガベージ コレクションがいつ行われるかについては保証されません。アプリケーションがクラッシュすると、アプリケーションのメモリ ダンプによって重要データが明らかになる場合があります。String
にパスワードを変換しています。
private JPasswordField pf;
...
final char[] password = pf.getPassword();
...
String passwordAsString = new String(password);
String
オブジェクトに重要なデータを保存すると、メモリからデータを確実に消去できません。String
は機密データを保管するために使用されますが、String
オブジェクトは不変であるため、それらに新しい値を割り当てると新しいString
が作成され、割り当てられているオブジェクトにその参照が割り当てられます。ARC
(Automatic Reference Counting) がオブジェクトの割り当てを解除してそのメモリを解放するまで、元の値はメモリに残ります。Swift は、最も近い周囲のスコープが終了するまで、オブジェクトの存続期間について保証しません。オブジェクトの割り当てが解除される前に攻撃者がメモリの内容をダンプすると、その内容を読み取ることができます。String
を使用してパスワードをメモリに保管します。
let password = passwordTextField.text!
// use the password
POST
メソッドの代わりに HTTP GET
を使用して、サーバーにデータを送信します。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 {
...
POST
メソッドの代わりに HTTP GET
を使用して、サーバーにデータを送信します。GET
メソッドを使用する HTTP リクエストは、URL およびリクエスト パラメーターがブラウザの URL キャッシュ、中間プロキシ、およびサーバー ログに保存されることを許可しています。その結果、データに対して適切な権限を付与されていない個人に重要な情報が開示される可能性があります。
...
$client = new Zend_Http_Client('https://www.example.com/fetchdata.php');
$client->request(Zend_Http_Client::GET);
...
POST
メソッドの代わりに HTTP GET
を使用して、サーバーにデータを送信します。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
ディレクトリは、ユーザー作成コンテンツやローカル情報などの常駐アプリケーション データを格納することを目的としており、アプリケーションをオフライン モードで実行できます。UIFileSharingEnabled
がアプリケーションの Info.plist
ファイルに設定されている場合、ここのファイルに 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
ディレクトリは、ユーザー作成コンテンツやローカル情報などの常駐アプリケーション データを格納することを目的としており、アプリケーションをオフライン モードで実行できます。UIFileSharingEnabled
がアプリケーションの Info.plist
ファイルに設定されている場合、ここのファイルに 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
を指定していないため、UI に表示された際にデフォルトで表示状態になります。
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
は 2 番目のパラメーター 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
のコードは、secret
が False
に設定されているため、admin_password
を平文 (難読化なし) に書き込んでログに出力します。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。