2017-01-09 84 views
1

我有以下枚舉:的Java枚舉值和SQL注入

public enum AccountStatus { 

    ENABLED, 
    CONFIRMATION_PENDING, 
    EXPIRED, 
    LOCKED, 
    DISABLED, 
    CREDENTIALS_EXPIRED, 
} 

那我結合複選框在JSP形式:

<li><form:checkbox path="accountStatus" value="ENABLED" label="Enabled" /></li> 
<li><form:checkbox path="accountStatus" value="CONFIRMATION_PENDING" label="Confirmation Pending" /></li> 
... 
<li><form:checkbox path="accountStatus" value="CREDENTIALS_EXPIRED" label="Credentials Expired" /></li> 

在我的控制器時,我得到的選擇複選框值我將字符串轉換爲一個枚舉如下:

AccountStatus accountStatus = AccountStatus.valueOf("selected string here"); 

然後在我的DAO(使用Spring JdbcTemplate)我查詢我的數據基地使用選擇的值:通過使用AccountStatus.valueOf(...)

String SQL = "SELECT * FROM TABLE_A WHERE column = \'" + accountStatus.name() + "\'"; 

jdbcTemplate.query(SQL, new MyMapper()); 

由於我選擇了驗證複選框每個用戶,從SQL注入做安全的這種方式?

+2

爲什麼你不使用參數化查詢? – cubrr

+0

我的SQL查詢比較複雜,我只寫了一個簡單的例子。所以我必須根據用戶輸入的值動態生成SQL查詢。 – karim

+1

所以你仍然可以參數化。 – OldProgrammer

回答

1

您不必爲如何你展示這個枚舉值越來越設置某人注入任意SQL的危險。攻擊者可能會發送無效的枚舉名稱,但valueOf在無法將其與有效值相匹配時會拋出IllegalArgumentException。

如果出於某種原因不應輸入有效的枚舉值(例如,某個特定角色沒有權限查找帶有DISABLED值的條目),那麼在缺少其他服務器端驗證的情況下攻擊者可以將條目更改爲有效但未被允許的值。所以這可能是一種可能的攻擊,您可以通過添加更多驗證來補救(在我的示例中,檢查是否允許爲用戶角色使用枚舉值)。

它會改善此SQL的可讀性,以重寫它以使用參數(最好是named parameters)。此外,這將繼續在每個代碼審查,靜態代碼分析和代碼審計中顯示出來,我不得不不斷回答關於它的問題。但我明白,要避免觸摸複雜的工作。