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
を平文 (難読化なし) に書き込んでログに出力します。多くの開発者がイベントログをデータの安全な格納先として信頼しがちですが、特にプライバシーに関わる場合は盲目的に信頼しないでください。<uses-permission .../>
要素では、ACTIVITY_RECOGNITION
権限の使用を宣言しています。この権限により、アプリケーションがユーザーの身体活動を認識できるようになります。<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission .../>
要素では、READ_CALENDAR
権限の使用を宣言しています。この権限により、アプリケーションはユーザーのカレンダー データを読み取ることができます。<uses-permission android:name="android.permission.READ_CALENDAR"/>例 2: AndroidManifest.xml の
<uses-permission .../>
要素では、WRITE_CALENDAR
権限の使用を宣言しており、これにより、アプリケーションがユーザーのカレンダー データに書き込むことが可能になります。<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission .../>
要素では、READ_CALL_LOG
権限の使用を宣言しています。この権限により、アプリケーションはユーザーの通話ログを読み取ることができます。<uses-permission android:name="android.permission.READ_CALL_LOG"/>例 2: AndroidManifest.xml の
<uses-permission .../>
要素では、WRITE_CALL_LOG
権限の使用を宣言しています。この権限により、アプリケーションがユーザーの通話ログに書き込むことができるようになります。<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission .../>
要素では、アプリケーションがデバイスのカメラにアクセスすることを可能にする CAMERA
権限の使用を宣言しています。<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission .../>
要素では、READ_CONTACTS
権限の使用を宣言しています。この権限により、アプリケーションはユーザーの連絡先データを読み取ることができます。<uses-permission android:name="android.permission.READ_CONTACTS"/>例 2: AndroidManifest.xml の
<uses-permission .../>
要素では、WRITE_CONTACTS
権限の使用を宣言しています。この権限により、アプリケーションはユーザーの連絡先データへの書き込みが可能になります。<uses-permission android:name="android.permission.WRITE_CONTACTS"/>例 3: AndroidManifest.xml の
<uses-permission .../>
要素では、GET_ACCOUNTS
権限の使用を宣言しています。この権限により、アプリケーションは、Account Manager に保存されているユーザーのメール アカウントやオンライン アカウントにアクセスできるようになります。この権限により、アカウント ID、電子メールアドレス、電話番号などの機密データにアクセスすることができます。<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission .../>
要素では、WRITE_EXTERNAL_STORAGE
権限の使用を宣言しています。この権限により、アプリケーションが外部ストレージに書き込むことができるようになります。<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>例 2: AndroidManifest.xml の
<uses-permission .../>
要素では、READ_EXTERNAL_STORAGE
権限の使用を宣言しています。この権限により、アプリケーションが外部ストレージから読み取ることができるようになります。<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>