以下のコードでセキュアコーディングの観点から、問題点があれば指摘してください。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) {
List<String> lines = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line;
while ((line = br.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
解答
このコードは、ファイルを読み込んで全ての行をリストに格納しますが、ファイルが非常に大きい場合、ヒープメモリが不足してOutOfMemoryError
が発生する可能性があります。
適合コード例
以下のコードは、ファイルサイズを制限し、メモリの枯渇を防ぐための改善例です。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Example {
public static final long FILE_SIZE_LIMIT = 10 * 1024 * 1024; // 10 MB
public static void main(String[] args) {
try {
long fileSize = Files.size(Paths.get("sample.txt"));
if (fileSize > FILE_SIZE_LIMIT) {
throw new IOException("File too large to process");
}
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line;
while ((line = br.readLine()) != null) {
processLine(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void processLine(String line) {
// 必要な処理をここで行う
System.out.println(line);
}
}
指摘1
この適合コードでは、ファイルサイズが10MBを超える場合には処理を中止し、メモリの過剰使用を防いでいます。また、リストに全ての行を格納するのではなく、行ごとに必要な処理を行うことで、メモリ使用量を最小限に抑えることができます。
指摘2
ファイルパスのハードコード
ファイルパスがコード内でハードコードされています。これにより、パスの変更や環境の違いに対応する際にコードの修正が必要となります。ファイルパスを外部から設定できるようにすることで、柔軟性が向上し、セキュリティ上のリスクも軽減されます(例えば、ユーザー入力を慎重に検証することで、任意のファイルが開かれるリスクを低減できます)。