脆弱性対策方法

開発者の不注意や確認不足が、脆弱性につながることが理解できたと思います。
次は、サンプルコードを基に対策方法を学んでいきましょう。

脆弱性の原因

本シナリオでの脆弱性の原因は以下となります。
  • ファイルの保存先にSDを指定している
    アプリを設計する際に、ファイルの保存先をSDカードにしたことが原因です。
    対策はファイルを作成する場所を変更すれば良いことになります。

対策方法の概要

実際に脆弱性のあるソースコードを確認し、修正してみましょう。
まず、「ソースコードを開く」ボタンをクリックし、「MainActivity.java」を開いてください。

ソースコードを開く

修正前:
プロジェクト FileaccessSd
ソースファイル MainActivity.java
public void onClickSave(View v) {
	// 入力内容の取得
	String data = csvData.toString();
	FileOutputStream fileOutputStream = null;

	// 既存のファイルを一度削除した後、新たにファイルを作成
	File file = new File(SD_FILE_PATH);
	file.delete();

	file.getParentFile().mkdir();

	try {
           
	// ▼▼▼脆弱性のあるソースコード▼▼▼
    // 書き込み処理を行う
    fileOutputStream = new FileOutputStream(file, true);
    fileOutputStream.write(data.getBytes());
	// ▲▲▲脆弱性のあるソースコード▲▲▲

	// 完了メッセージ表示
	Toast.makeText(this, String.format("%s\r\nにバックアップが完了しました。", file.getAbsolutePath()), Toast.LENGTH_LONG).show();

    public void onClickDelete(View v) {
        File file = new File(SD_FILE_PATH);
        file.delete();
        Toast.makeText(this, "ファイルを削除しました", Toast.LENGTH_LONG).show();
    }

このアプリには脆弱性対策を行うべき箇所が3箇所あります。
  • 86~91行目
    SDカードのパスを指定してファイルを作成する処理を削除します。

  • 96行目
    SDカードではなく、内部ストレージにファイルを作成するように修正します。
    内部ストレージにMODE_PRIVATEでファイルを作成することで、他アプリからファイルにアクセスすることができなくなります。
    96行目のFileOutputStream()の呼び出し方法を変更し、MODE_PRIVATEを指定するようにします(赤文字部分)。
    fileOutputStream = openFileOutput(FILE_NAME,  MODE_PRIVATE);
    修正後のコードでは90行目にあたります。

    87行目で削除したfileオブジェクトは、後のToastの表示で使用されているので、このタイミングで作成しておきます。
    File file = getFileStreamPath(FILE_NAME);
    修正後のコードでは92行目にあたります。


  • 126,127行目
    ファイルの作成先をSDカードから内部ストレージに変更したことに伴い、削除処理も修正します。
    126行目を削除し、127行目を以下のように修正します。
    deleteFile(FILE_NAME);
    修正後のコードでは121行目にあたります。


全ての修正が完了した例は以下の通りです。

修正後:
プロジェクト FileaccessSd
ソースファイル MainActivity.java
public void onClickSave(View v) {
	// 入力内容の取得
	String data = csvData.toString();
	FileOutputStream fileOutputStream = null;

	try {

		// ▼▼▼脆弱性を修正したソースコード▼▼▼
		// 書き込み処理を行う
		fileOutputStream = openFileOutput(FILE_NAME,  MODE_PRIVATE);
		fileOutputStream.write(data.getBytes());
		File file = getFileStreamPath(FILE_NAME);
		// ▲▲▲脆弱性を修正したソースコード▲▲▲
	
		// 完了メッセージ表示
		Toast.makeText(this, String.format("%s\r\nにバックアップが完了しました。", file.getAbsolutePath()), Toast.LENGTH_LONG).show();

    public void onClickDelete(View v) {
		deleteFile(FILE_NAME);
		Toast.makeText(this, "ファイルを削除しました", Toast.LENGTH_LONG).show();
    }

対策のまとめ

「SDカードのファイルアクセス制限の理解不足」による脆弱性について、対策は以下のとおりです。
  • 対策
    SDカード内に重要な情報を保存しないようにする。
  • 修正方法
    重要な情報はSDカードではなく内部ストレージに保存し、適切なアクセス権を設定する。
開発者は、ファイルをSDカード上に作成する場合には、重要な情報を保存する事がないように注意しましょう。