SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaセキュアコーディング入門

AndroidアプリにおけるDBファイルの正しい使い方

Javaセキュアコーディング入門(5)


  • X ポスト
  • このエントリーをはてなブックマークに追加

 AndroidアプリにはSQLiteを使用する方法がいくつか用意されていますが、これらの挙動を十分に理解していないと思わぬ脆弱性を作りこんでしまう可能性があります。本稿ではこのバックグラウンドと正しい使い方のガイドラインを紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 Androidアプリケーションを作成する上でSQLiteを使用してデータベースを扱うことは多々あります。データの永続化や検索といった処理を容易に実装することができるので、多くのアプリケーションで使用されています。しかし、AndroidにはSQLiteを使用するための方法が以下のようにいくつか用意され、それぞれファイル作成時のパーミッションの挙動が異なっています。

  • SQLiteDatabase#openOrCreateDatabaseを使用して作成する
  • Context#openOrCreateDatabaseを使用して作成する
  • SQLiteOpenHelperクラスを使用して作成する

 もし、開発者がこれら方法の挙動を十分に理解していない場合、知らずのうちに脆弱性を作り込んでしまいます。

 実際に、いくつかのアプリケーションではSQLiteDatabase#openOrCreateDatabaseを起因とするファイルパーミッションに関する脆弱性が発見されています。

 Androidのアプリケーションは、基本的に他のアプリケーションで管理されているファイルにはアクセスできません。しかし、方法によっては他のアプリケーションからもアクセスできるファイルが作成されてしまいます。今回はこれらDBファイルを作成する方法について、それぞれDBファイルのパーミッションはどのようになっているのか、その挙動について解説します。

SQLiteDatabase#openOrCreateDatabase

 まず、SQLiteDatabase#openOrCreateDatabaseですが、以下のサンプルコードではdatabasesディレクトリ以下にapp.dbというファイル名でDBファイルが作成されます。

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(new File(
    "/data/data/" + getContext().getPackageName() + "/databases/",
    "app.db"), null);

 作成されたDBファイルのパーミッションを確認すると644となっており、他のアプリケーションからもアクセスできるようになっています。では、実際にこのメソッドの内部ではどのようなことが行われているのでしょうか。

 openOrCreateDatabaseメソッドの内部ではopenDatabaseメソッドが呼ばれています。

SQLiteDatabase#openOrCreateDatabaseの中身
/**
 * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
 */
public static SQLiteDatabase openOrCreateDatabase(String path,  CursorFactory factory) {
    return openDatabase(path, factory, CREATE_IF_NECESSARY);
}

省略 ...

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
    return openDatabase(path, factory, flags, new DefaultDatabaseErrorHandler());
}

省略 ...

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
    DatabaseErrorHandler errorHandler) {
    SQLiteDatabase sqliteDatabase = openDatabase(path, factory, flags, errorHandler,
        (short) 0 /* the main connection handle */);

省略 ...

private static SQLiteDatabase openDatabase(String path,
    CursorFactory factory, int flags,
    DatabaseErrorHandler errorHandler, short connectionNum) {
    SQLiteDatabase db = new SQLiteDatabase(path, factory, flags,
        errorHandler, connectionNum);
    try {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.i(TAG, "opening the db : " + path);
        }
        // Open the database.
        db.dbopen(path, flags);
        db.setLocale(Locale.getDefault());

 openDatabaseメソッドではネイティブメソッドのdbopenが呼ばれ、その中でSQLiteの関数の一つであるsqlite3_open_v2関数を使用してDBファイルが作成されるようになっています。

android_database_SQLiteDatabase.cppの中身
/* public native void dbopen(String path, int flags, String locale); */
static void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
{

省略 ...

    err = sqlite3_open_v2(path8, &handle, sqliteFlags, NULL);
    if (err != SQLITE_OK) {
        LOGE("sqlite3_open_v2(\"%s\", &handle, %d, NULL) failed\n", path8, sqliteFlags);

 この付近のコードを確認する限り、作成されるファイルのパーミッションを設定したり変更したりという処理は見当たりません。よってデフォルトのumaskで作成され、その結果、ファイルのパーミッションは644になっているのではないかと推測します。

次のページ
Context#openOrCreateDatabase

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Javaセキュアコーディング入門連載記事一覧

もっと読む

この記事の著者

熊谷 裕志(JPCERTコーディネーションセンター)(クマガイ ヒロシ(JPCERTコーディネーションセンター))

情報セキュリティアナリスト JPCERTコーディネーションセンターベンチャ企業にてWEBサイトのデザインやシステム開発、Androidアプリケーションの開発などに従事したのち、2011年4月よりJPCERTコーディネーションセンターにて、脆弱性情報の分析やセキュアコーディングの普及活動に携わってい...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6495 2012/06/22 18:05

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング