以下の単純なJavaコードは、Fortifyパス操作エラーを取得します。これを解決するのを手伝ってください。私は長い間苦労しています。
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
Path Manipulation のOWASPページを見ると、
攻撃者は、ファイルシステムの操作で使用されるパスを指定できます
ユーザー指定の入力で定義されたとおりにファイルを開いています。あなたのコードは脆弱性のほぼ完璧な例です!どちらか
または、アプリケーションの設計を再考してください。
使用する前にURLを正規化してみてください
https://docs.Oracle.com/javase/7/docs/api/Java/net/URI.html#normalize()
Path path = Paths.get("/foo/../bar/../baz").normalize();
またはorg.Apache.commons.io.FilenameUtilsからnormalizeを使用します
Stirng path = FilenameUtils.normalize("/foo/../bar/../baz");
どちらの場合も、結果は\baz
になります
入力にはalnumとperiodのみを許可します。つまり、ファイルを脆弱にする制御文字「..」、「/」、「\」を除外します。たとえば、/ path /password.txtを入力できないようにする必要があります。
完了したら、再スキャンしてからFortifyAWBを実行します。
Fortifyは、パス/ファイルがプロパティファイルのようにユーザー入力からのものでなくても、コードにフラグを立てます。これらを処理する最良の方法は、最初にパスを正規化し、次に許可されたパスのホワイトリストに対して検証することです。
悪い:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
}
}
良い:
public class Test {
public static void main(String[] args) {
File file=new File(args[0]);
if (!isInSecureDir(file)) {
throw new IllegalArgumentException();
}
String canonicalPath = file.getCanonicalPath();
if (!canonicalPath.equals("/img/Java/file1.txt") &&
!canonicalPath.equals("/img/Java/file2.txt")) {
// Invalid file; handle error
}
FileInputStream fis = new FileInputStream(f);
}
Fortify PathManipulationの問題に対する解決策があります。
不平を言っているのは、外部ソースからデータを取得した場合、攻撃者はそのソースを使用してパスを操作できるということです。したがって、攻撃者がファイルを削除したり、システムを危険にさらしたりできるようにします。
この問題に対する推奨される解決策は、信頼できるディレクトリのホワイトリストを有効な入力として使用することです。そして、他のすべてを拒否します。
このソリューションは、実稼働環境で常に実行できるとは限りません。だから、私は別の解決策を提案します。受け入れ可能な文字のホワイトリストの入力を解析します。パスに不要な文字を入力から拒否します。取り外すか交換することができます。
以下に例を示します。これはFortifyのレビューに合格しています。チェックされている文字ではなくリテラルを返すことをここで覚えておくことが重要です。 Fortifyは、元の入力からのパーツを追跡します。元の入力のいずれかを使用した場合でも、エラーが発生する可能性があります。
public class CleanPath {
public static String cleanString(String aString) {
if (aString == null) return null;
String cleanString = "";
for (int i = 0; i < aString.length(); ++i) {
cleanString += cleanChar(aString.charAt(i));
}
return cleanString;
}
private static char cleanChar(char aChar) {
// 0 - 9
for (int i = 48; i < 58; ++i) {
if (aChar == i) return (char) i;
}
// 'A' - 'Z'
for (int i = 65; i < 91; ++i) {
if (aChar == i) return (char) i;
}
// 'a' - 'z'
for (int i = 97; i < 123; ++i) {
if (aChar == i) return (char) i;
}
// other valid characters
switch (aChar) {
case '/':
return '/';
case '.':
return '.';
case '-':
return '-';
case '_':
return '_';
case ' ':
return ' ';
}
return '%';
}
}
Webアプリケーションに対してFortifyを実行していると仮定すると、Fortifyの脆弱性のトリアージ中に、「問題ではない」とマークされる可能性があります。理由は、A)明らかにこれはテストコードであり、B)複数の人格障害がない限り、そのテストアプリを実行するときに自分自身に対してパス操作の悪用を行うことはありません。
このスタイルの誤検知を生成するリポジトリにコミットされたテストユーティリティがほとんどないことが非常に一般的である場合。
コンパイルエラーに関しては、それは一般的にクラスパスの問題に帰着します。