アミット・ゴールドスタイン:
私はPG使用して、ファイルとしてテーブルをダウンロードするには、次のコードを持ってCOPYを:
public void download(String table, Writer responseWriter) throws SQLException, IOException {
try (Connection conn = dataSource.getConnection()) {
CopyManager copyManager = new CopyManager(conn.unwrap(BaseConnection.class));
// SQL Injection can happen here!
String statement = "COPY " + table + " TO STDOUT WITH NULL ''";
copyManager.copyOut(statement, responseWriter);
}
}
明らかに、このコードは、SQLインジェクションする傾向がある(表パラメータがスプリングRESTコントローラから送られます)。もちろん私はいくつかの手動衛生を行うことができますが、CopyManagerでこれを行うには、「PreparedStatementの」方法がある場合、私はそれを好むだろう。SpringのJdbcTemplateを使用するためのボーナスポイント。
ティムBiegeleisen:
追加のような何かをする悪質な試みブランケットSQLインジェクション、に加えて、DELETE
あなたに文をCOPY
コマンドを、別の問題があります。あなたのコードは、することができますので任意の実行するには、有効なテーブル名、それはまだあなたのスキーマ内の任意のテーブルに含まれるデータを明らかにするリスクを実行します。
だから、ここで行うには安全な事はあなたがアクセスをユーザーに許可するテーブルのホワイトリストを維持するかもしれません。リストと一致しませんでした任意の入力テーブル名が拒否されるだろう。テーブルが存在するのリストを想定するとList
、我々はあなたのコードに以下の変更を行うことができます:
public void download(String table, Writer responseWriter) throws SQLException, IOException {
// get list of all allowed tables
List<String> fileList = getAllowedTables();
if (!fileList.contains(table)) {
throw new IllegalAccessException("Someone tried to access a forbidden table.");
}
try (Connection conn = dataSource.getConnection()) {
CopyManager copyManager = new CopyManager(conn.unwrap(BaseConnection.class));
// SQL Injection can happen here!
String statement = "COPY " + table + " TO STDOUT WITH NULL ''";
copyManager.copyOut(statement, responseWriter);
}
}