簡體   English   中英

如何在java中用integer類型替換字符串中的字符串?

[英]How to replace a string in a string with integer type in java?

我有一個要求。 該技術相當陳舊,根本不支持 spring。 它是帶有 jdbc 連接的純 java 應用程序。

要求是:假設

select * from employee where empid = <<empid>> and designation = 'Doctor'

我正在嘗試用 java 中的實際 int 值替換 <>。我該怎么做?

String query = "select * from employee where empid = <<empid>> and designation = 'Doctor'";
if(query.contains("<<empid>>"))
/// Here I want to replace <<empid>> with actual int value in java 

任何線索都會有所幫助

您沒有粘貼的實際執行 SQL 的代碼是 [A] 需要嚴重重寫的大規模安全漏洞,或者 [B] 正在使用PreparedStatement

這是問題所在:SQL 注入。 通過將模板或一堆字符串常量與一堆用戶輸入混合在一起來創建 SQL 字符串是一個安全漏洞。 例如,如果您嘗試通過例如String sql = "SELECT * FROM users WHERE email = '" + email + "'";制作SELECT * FROM users WHERE email = 'foo@bar.com' ; ,問題是,如果用戶在“電子郵件”字段中輸入 web 表單怎么辦: whatever@foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; -- whatever@foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; -- whatever@foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; -- 然后 SQL 變成:

SELECT * FROM users WHERE email = 'whatever@foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; --';

這是合法的 SQL 並且您真的、真的、真的不希望您的數據庫引擎執行它。

每個數據庫引擎對什么是真正合法的都有自己的想法,並且可能會做一些瘋狂的事情,例如將卷曲引號視為真實引號等。因此,您可以想到沒有可行的黑名單或白名單技術可以正確涵蓋所有基礎:你需要讓你的數據庫引擎為你做這件事,你不能自己修復這個漏洞。

Java 通過java.sql.PreparedStatement支持這一點。 相反,您總是將一個完全常量 SQL 字符串傳遞給引擎,然后填充空白,可以這么說:

PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE email = ?");
ps.setString(1, "foo@whatever.com");
ps.query();

這就是您的操作方式(並添加 try-with-resources 就像您應該在此處所做的那樣;語句和結果集是您必須始終關閉的資源)。 即使您調用.setString(1, "foo@whatever.com'; DROP TABLE users CASCADE; --") ,它也會簡單地在數據庫中查找email字段的一行。 它不會刪除整個用戶表。 消除了安全漏洞(這是消除它的唯一可行方法)。

因此,檢查該代碼。 是用preparedstatement嗎? 在那種情況下,代碼需要以一種或另一種方式調用:

ps.setInt(1, 999);

其中ps是使用connection.prepareStatement(...)創建的PreparedStatement object 其中...是 SQL 常量或至少是您的輸入字符串,其中<<empid>>被替換為問號並且從未被任何字符串輸入替換來自不受信任的來源。 ps.setInt( 1 ps.setInt(1, 999)中的1就是問號的position(1=第一題變成999), 999就是你的實際數字。 它可能看起來像:

if (input instanceof String) {
    ps.setString(idx++, (String) input);
} else if (input instanceof Integer) {
    ps.setInt(idx++, ((Integer) input).intValue());
} ...

等等。 如果您沒有看到它,請找到setInt調用並弄清楚如何到達那里。 如果您沒有看到任何setInt ,那么如果不對此代碼進行一些更新,您想要的是不可能的。

如果您在代碼中的任何地方都看不到PreparedStatement天啊! 立即使該服務器脫機,研究是否發生安全漏洞,如果該服務器存儲了歐洲數據,您有 72 小時的時間通知所有用戶是否存在,或者您無法通過檢查日志發現它沒有,或者您違反了 GDPR。 然后使用PreparedStatement重寫該部分以解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM