PostgreSQLのCOPY JDBCと防止SQLインジェクション

アミット・ゴールドスタイン:

私は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);
    }
}

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=187793&siteId=1