mybatis 學習筆記:mybatis SQL註入問題
SQL 註入攻擊
首先了解下概念,什麽叫SQL 註入:
SQL註入攻擊,簡稱SQL攻擊或註入攻擊,是發生於應用程序之數據庫層的安全漏洞。簡而言之,是在輸入的字符串之中註入SQL指令,在設計不良的程序當中忽略了檢查,那麽這些註入進去的指令就會被數據庫服務器誤認為是正常的SQL指令而運行,因此遭到破壞或是入侵。
最常見的就是我們在應用程序中使用字符串聯結方式組合 SQL 指令,有心之人就會寫一些特殊的符號,惡意篡改原本的 SQL 語法的作用,達到註入攻擊的目的。
舉個栗子:
比如驗證用戶登錄需要 username 和 password,編寫的 SQL 語句如下:
select * from user where (name = ‘"+ username +"‘) and (pw = ‘"+ password +"‘);
username 和 password 字段被惡意填入
username = "1‘ OR ‘1‘=‘1";
與
password = "1‘ OR ‘1‘=‘1";
將導致原本的 SQL 字符串被填為:
select * from user where (name = ‘1‘ or ‘1‘=‘1‘) and (pw = ‘1‘ or ‘1‘=‘1‘);
實際上運行的 SQL 語句將變成:
select * from user;
也就是不再需要 username 和 password 賬密即達到登錄的目的,結果不言而喻。
mybatis 解決 SQL 註入問題
我們使用 mybatis 編寫 SQL 語句時,難免會使用模糊查詢的方法,mybatis 提供了兩種方式 #{}
${}
。
#{value}
在預處理時,會把參數部分用一個占位符 ? 替代,其中 value 表示接受輸入參數的名稱。能有效解決 SQL 註入問題${}
表示使用拼接字符串,將接受到參數的內容不加任何修飾符拼接在 SQL 中,使用${}
拼接 sql,將引起 SQL 註入問題。
舉個例子:
1 查詢數據庫 sample 表 user 中的記錄,我們故意使用特殊符號,看能否引起 SQL 註入。使用 mybatis 在 mapper.xml 配置文件中編寫 SQL 語句,我們先采用拼接字符串形式,看看結果如何:
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
<!-- 拼接 MySQL,引起 SQL 註入 -->
SELECT * FROM user WHERE username LIKE ‘%${value}%‘
</select>
註意在配置文件中編寫 SQL 語句時,後邊不需要加分號。
調用配置文件,編寫測試文件,查詢數據庫內容,采用特殊符號,引起 SQL 註入:
@Test
public void testFindUserByName() throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
//創建UserMapper代理對象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//調用userMapper的方法
List<User> list=userMapper.findUserByName("‘ or ‘1‘=‘1");
sqlSession.close();
System.out.println(list);
}
}
運行結果如下圖所示:
可以看到執行語句其實變為了
select * from user
將user 表中的全部記錄打印出來了。發生了 SQL 註入。
2 如果將配置文件中的 SQL 語句改成 #{}
形式,可避免 SQL 註入。
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
<!-- 使用 SQL concat 語句,拼接字符串,防止 SQL 註入 -->
SELECT * FROM USER WHERE username LIKE CONCAT(‘%‘,#{value},‘%‘ )
</select>
再次運行測試程序,控制臺輸出如下:
可以看到程序中參數部分用 ? 替代了,很好地解決了 SQL 語句的問題,防止了 SQL 註入。查詢結果將為空。
mybatis 學習筆記:mybatis SQL註入問題