web-dev-qa-db-ja.com

機密データをReact Native

Reactネイティブアプリケーションを構築しています。トークンや更新トークンなどの機密データを保存する必要があります。明らかな解決策は、 AsyncStorage を使用してその情報を保存することです問題は、AsyncStorageのセキュリティレベルです。

AsyncStorageは、トークンとデータをローカルに保存する方法を提供します。 LocalStorageオプションと比較すると、いくつかの点で異なります。完全な実稼働アプリケーションでは、AsyncStorageに直接アクセスしないことをお勧めしますが、AsyncStorageは同じブラウザーを使用して他のアプリと共有されるため、抽象レイヤーを使用することをお勧めします。近隣のアプリの機能。

https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/

ネイティブアプリでは、KeychainiOSShared Preferences inprivate modein Android

React Native:

IOSでは、AsyncStorageはネイティブコードによってサポートされており、シリアルコード化された辞書に小さな値を格納し、別のファイルに大きな値を格納します。 Androidでは、AsyncStorageは利用可能なものに基づいてRocksDBまたはSQLiteを使用します。

https://facebook.github.io/react-native/docs/asyncstorage.html

彼らはそのデータのセキュリティについて決して話しません。

Androidのモジュールを作成する最適なソリューションです(Shared Preferences inprivate mode)および別のiOSKeychainを使用)が賢明なデータを保存しますか?または、提供されているAsyncStorageメソッドを使用しても安全ですか?

41
Sandro Machado

React Nativeコードを掘り下げて、答えを見つけました。

Android

React NativeAsyncStoragemoduleの実装は、SQLiteOpenHelperに基づいています。すべてのデータクラスが処理されるパッケージ: https://github.com/facebook/react-native/tree/master/ReactAndroid/src/main/Java/com/facebook/react/modules/storage

データベースを作成する手順を含むクラス: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/Java/com/facebook/react/modules/storage/ ReactDatabaseSupplier.Java

Androidドキュメンテーションにより、アプリケーションによって作成されたデータベースは、関連付けられたアプリケーションのプライベートディスク領域に保存されるため、安全です。

デバイスの内部ストレージに保存するファイルと同様に、Androidはデータベースを関連アプリケーションのプライベートディスクスペースに保存します。デフォルトではこの領域は他のアプリケーションからアクセスできないため、データは安全です。

ソース

iOS

IOSでは、AsyncStorage値はシリアル化された辞書ファイルに保存されます。これらのファイルはアプリケーションNSDocumentDirectoryに保存されます。 iOSでは、すべてのアプリケーションは独自のサンドボックスにあるため、1つのアプリケーションのすべてのファイルは保護され、他のアプリケーションからはアクセスできません。

AsyncStorageモジュールを処理するiOSのコードは、次の場所にあります。 https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.m =

ご覧のとおり、 hereAsyncStorageによって保存された値を保存するために使用されるファイルは、NSDocumentDirectory(アプリケーションサンドボックス環境内)の下に保存されます。

すべてのアプリは島ですiOSアプリのファイルシステムとのやり取りは、アプリのサンドボックス内のディレクトリにほとんど制限されています。新しいアプリのインストール中に、インストーラーはアプリ用のコンテナをいくつか作成します。各コンテナには特定の役割があります。バンドルコンテナはアプリのバンドルを保持しますが、データコンテナはアプリケーションとユーザーの両方のデータを保持します。データコンテナーは、アプリがデータの並べ替えと整理に使用できるいくつかのディレクトリにさらに分割されます。アプリは、実行時に追加のコンテナ(iCloudコンテナなど)へのアクセスを要求することもあります。

ソース

結論

ユーザートークンは安全なコンテキストで保存されるため、AsyncStorageを使用してユーザートークンを保存しても安全です。

これはAndroidデバイスがrootなしで、iOSデバイスがjailbreak。また、攻撃者がデバイスに物理アクセスを持ち、デバイスが保護されていない場合、デバイスをMacラップトップに接続し、 抽出するdocuments ディレクトリとドキュメントディレクトリの下に保存されているすべてのコンテンツを参照してください。

75
Sandro Machado

AsyncStorageは、キーと値のペアをプレーンテキストJSONファイルとしてDocumentsディレクトリに保存します。 コンテンツを暗号化しません

これはセキュリティの問題です(少なくともiOSでは)。デバイスにアクセスできる攻撃者は、サンドボックスの内容のダンプを取得し、AsyncStorageを介して保存されたデータを簡単に抽出できるためです。

これは、AsyncStorage.jsのドキュメントに明確に記載されていませんでしたが、現在は https://github.com/facebook/react-native/pull/8809 です。

参照: https://stackoverflow.com/a/38398114/1072846

5
Eric

誰かがデータを暗号化するという追加のステップが必要な場合は、次をご覧ください。 https://github.com/oblador/react-native-keychain

内部で facebook conceal を使用します。

4
flaky

react-native-keychain のようなライブラリを使用して react-native にプライベートデータを保存することをお勧めします

Android APIレベル:

  • 16-22 Facebook Concealを使用する
  • 23+ use Android Keystore

次のように使用できます。

// Generic Password, service argument optional
Keychain
  .setGenericPassword(username, password)
  .then(function() {
    console.log('Credentials saved successfully!');
  });

// service argument optional
Keychain
  .getGenericPassword()
  .then(function(credentials) {
    console.log('Credentials successfully loaded for user ' + credentials.username);
  }).catch(function(error) {
    console.log('Keychain couldn\'t be accessed! Maybe no value set?', error);
  });
2
Julien Kode