中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

報表的SQL植入的概念

發布時間:2021-09-09 11:15:34 來源:億速云 閱讀:143 作者:chen 欄目:編程語言

這篇文章主要介紹“報表的SQL植入的概念”,在日常操作中,相信很多人在報表的SQL植入的概念問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”報表的SQL植入的概念”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

SQL 植入的概念

首先,認識一下什么是 sql 植入?

Sql 植入也常被叫做 SQL 注入,具體的做法是通過把 SQL 命令插入到 Web 表單項或頁面請求(Url)的查詢字符串中提交,最終達到欺騙服務器執行惡意操作的目的。

常見案例包括通過植入 SQL 騙過登錄驗證。而之前很多影視網站泄露 VIP 會員密碼的事件,很多就是通過 sql 植入到 WEB 表單暴出的,并且這類表單特別容易受到攻擊。通過 SQL 植入,不僅可以非法獲取賬號信息,嚴重的還能夠篡改、刪除重要數據信息。

為什么存在 SQL 植入呢?

知道了 sql 植入的概念,我們也應該了解為什么會出現 SQL 植入,問題出現在哪個環節?

報表的SQL植入的概念

上圖是一個最簡單的三層架構的應用結構,包括業務展現層、 數據處理層、數據源。也可以理解成我們常說的前端、后臺、后臺數據源。

其中,數據源里有個叫數據庫的東西,這是最常見的數據管理和存儲方式,而關系型數據庫那就更常見了,比如 oracle、db2、mysql 等。

開發的應用(數據處理層,也就是后臺)為了和操作數據庫(增刪改查),必須和數據庫之間有交流的接口,例如 jdbc 或 odbc,這對于技術人員或是 IT 銷售人員也是耳熟能詳的。

對于數據庫的操作,尤其關系型的,普遍使用的就是 sql 語言。SQL 是一種高級的非過程化語言,只描述做什么而不需要告訴數據庫怎么做。 SQL 腳本通過 api 以字符串方式傳入數據庫,數據庫收到 sql 后只管執行然后將結果返回。對于數據庫本身來說,它是不知道傳來的 sql 是合法還是不合法的,而正是這種完全的信任,導致出現了 sql 植入的風險。

歸根結底,SQL 植入利用了應用程序的漏洞,如果編寫數據處理的代碼時沒有充分考慮 sql 植入風險,攻擊者將很容易將 sql 命令植入后臺數據庫引擎執行。而這些不是按照設計者或開發者的意圖去執行的 sql 命令都會被視為惡意代碼。

如何攻擊?

了解了 sql 植入攻擊的基本原理,我們就來看看具體怎么攻擊。多種多樣的攻擊方式中比較常見的包括:

1、特殊的輸入參數

2、未處理特殊字符“–”、“#”

3、利用不合理的數據庫配置

案例 1、特殊的輸入參數

常見的如 union 或 or,這是 sql 內的關鍵字,一個用作多 sql 的歸并,另一個則常用在 where 條件中。

以 Union 為例,如果攻擊者在一條正常可執行的 sql 后,通過猜表名的方式拼入“union select … from user”,那么 user 表信息就完全暴露了。

Or 呢?可以使得 where 條件變的恒真,以“騙過登錄驗證”為例:

在程序中我們一般拼 sql 為:strSQL = “SELECT * FROM users WHERE userID = ’” + userID + “’ and pw = ’”+ passWord +“’;”

如果此時 userID 傳入 1 or 1=1 ,passWord 傳入 ‘1’ or 1=1, 完整的 strSQL 就變成了:“SELECT * FROM users WHERE userID=1 OR 1=1 and pw =’ 1’ OR 1=1;”

很顯然,where 條件變為恒真,也就成功騙過了驗證,登錄進了系統。

案例 2、未處理特殊字符

以常用的注釋符“–” 為例:一般的數據庫均采用其作為注釋符。另外,mysql 還支持“#”注釋。

接下來看注釋符怎么騙過登錄驗證。

程序 sql 依然定義為:strSQL = “select * from users where userID=”+userID+“and password=”+psw

此時 userID 傳入:’’ or 1=1 –

完整 sql 則拼為:select * from users where userID=’’ or 1=1 – and password = …

“–”之后的腳本作為注釋不再執行,實際條件也成了恒真,成功騙過驗證,侵入系統。

對于 mysql 數據庫,把“–”改為“#”同樣可以實現注入。

案例 3、利用不合理的數據庫配置

常見的是權限配置不合理、過高,就會有 update 和 delele 甚至 drop 表的風險。

因此建議,“永遠”不要使用管理員權限連接數據庫,而應該為每個應用使用單獨的、權限有限的數據庫連接。    

報表和 SQL 植入有啥關系?

由于大多數報表工具都會提供參數功能,根據用戶輸入的查詢條件來篩選合適的數據,因此就給 SQL 植入提供了可乘之機。

報表的SQL植入的概念

例如,如果希望查詢指定時間段的數據,可以把時間段作為參數傳遞給報表,報表在從數據庫中取數時將這些參數拼接到取數 SQL 的 WHERE 條件上,就可以根據不同參數取出不同數據來進行呈現了。這種方式要求事先把查詢條件做死,也就是固定了對應的條件字段。 比如下面這種傳統做法:

sql:select * from t where date>=? and date<=?

這個 SQL 定義的數據集專用于按時間段查詢,如果想用地區查詢就不行了,需要再做一個 area=? 的查詢條件或報表。顯然非常麻煩……

如果報表工具只支持這種普通用法,自然不夠靈活,可能就會限制報表工具的功能,于是“通用查詢”這個大招兒就出現了。

報表工具提供了一種特殊的字符串型參數,允許應用其直接替換 SQL 的某一部分,比如 WHERE 子句。界面端則根據用戶的輸入拼出合法的 SQL 條件串,作為參數傳遞給報表替換現有 SQL 的 WHERE 子句,這樣就可以在同一張報表上實現不同形式的查詢條件了。比如數據集的 SQL 可以寫成:

SELECT … FROM T WHERE ${mac}

其中 ${mac} 就是將來會被參數 mac 替換的內容。按時間段查詢時,可以把 mac 拼成 date>… AND data <=…,按地區查詢時則拼成 area=…;當然還可以混合多條件查詢拼成 data>… AND date<=… AND area=…;而無條件時則拼成一個永遠為真的條件 1=1。

是的,這非常靈活了。

But,帶來了靈活性的同時也帶來了 sql 植入的風險……可能的植入風險及基于 sql 的規避方法請研讀此文章:  報表工具的 SQL 植入風險  ]( http://c.raqsoft.com.cn/article/1535513599294 )。(報表與 sql 植入的關系,也引自此文。)

報表工具規避 SQL 植入

上面的內容以及所鏈接的文章介紹了通過 sql 本身的一些限制來防止 sql 注入,那么報表工具能不能也提供一些方法呢?比如著名的潤乾報表。

答案肯定是有的。

目前,報表工具一般都會提供敏感詞檢查,當傳進來的替換子句中包含某些特定詞時將被拒絕,比如很少有人會用 select,from union 這些 SQL 關鍵字作為字段名,那么,我們可以首先判斷一下替換子句中是否包含有 select,from 這些詞,如果有就可以認為受到攻擊并拒絕執行。這樣做肯定會犧牲一點靈活性,例如有時傳進來的子句萬一真的會含有這些關鍵字,不過這種情況相對少見,在獲得了較好的安全性的同時,損失的靈活性可以接受。

下面我們就看一下,潤乾報表里具體怎么用這種方法?

兩種方式:

1、raqsoftConfig.xml 配置需要檢查的敏感詞列表

該方法是由產品提供的方法,配置好敏感詞列表后,報表計算時首先會對每個參數值逐一檢查,一旦發現檢查不通過的情況,報表不再繼續執行,并返回錯誤信息。

配置如

報表的SQL植入的概念

屬性名:disallowedParmWordList,value 為禁用敏感詞列表,多個之間用逗號分隔,英文字母不區分大小寫。

這個方式用起來很簡單,直接改配置,實施或維護人員就能簡單操作。

如訪問 Url: http://localhost:6868/demo/reportJsp/showReport.jsp?rpx=a.rpx&ar  g2= 華北 union select * from users,其中紅色部分為通過參數 arg2 植入的 sql

此時會報錯,報表數據集(sql)不會再執行。

報表的SQL植入的概念

2、自定義參數檢查類

對應方法 1,更為靈活。

(1)對所有參數值檢查,代替方法 1

(2)針對某些指定的參數進行檢查

(3)錯誤信息可自定義

public class … implements IParamChecker {

    // 校驗不通過返回 false,提供 paramName 以便用戶只檢查某種形式的參數

    public boolean check(String s, String s1) {

        //s 為報表–參數內,定義的參數名;s1 為報表接收到的對應 s 的參數值

        return false;

    }

    // 檢驗不通過是可獲取詳細信息

    public String getCause() {

        return “錯誤信息”;

    }

}

接口為 IParamChecker,兩個方法:check()為檢查實現,getCause() 負責返回錯誤信息。

下面是介紹使用方法的簡單代碼示例:

(1)實現自定義類

A、對所有參數值檢查

public class ResistSQLInject implements IParamChecker {

    private String cause = "";

    private List wordList = new ArrayList();

    public boolean check(String paramName, String inputValue) {

        if(inputValue == null || inputValue.length() == 0){// 如果參數值為空,則無需檢查

            return true;

        }

        if(wordList == null){ // 如果檢測關鍵字列表是空,則不作檢查

            return true;

        }

for(int i = 0; i < wordList.size(); i++){

            inputValue = inputValue.toLowerCase();// 這里做,是為了不區分大小寫

            if(inputValue.indexOf(wordList.get(i).toLowerCase())>= 0){       

                return false;

            }

        }

        return true;

    }  

    public String getCause() {

        String tmp = this.cause;

        this.cause = "";

        return tmp;

    }

}

B、針對某些參數檢查

 private String cause = "";

    private List wordList = new ArrayList();

    /*

     * @paramName 驗證的參數名

     * @inputValue 驗證的參數值

     */

    public boolean check(String paramName, String inputValue) {

        //wordList.add(“select”);

        if(wordList == null){ // 如果檢測關鍵字列表是空,則不作檢查

            return true;

        }

        if(paramName==“userID”){

            if(inputValue == null || inputValue.length() == 0){// 如果參數值為空,則無需檢查

                return true;

            }

            for(int i = 0; i < wordList.size(); i++){

                inputValue = inputValue.toLowerCase();// 這里做,是為了不區分大小寫

                if(inputValue.indexOf(wordList.get(i).toLowerCase())>= 0){

                    StringBuffer sb = new StringBuffer();

                    sb.append(“校驗未通過,”).append(paramName).append(“參數中含有以下詞匯:”).append(wordList.get(i))

                            .append(“\n 位置:”).append(inputValue.indexOf(wordList.get(i).toLowerCase()));

                    this.cause = sb.toString();

                    return false;

                }

            }

        }

        return true;

    }

C、自定義錯誤信息

public boolean check(String paramName, String inputValue) {

        //wordList.add(“select”);

        if(wordList == null){ // 如果檢測關鍵字列表是空,則不作檢查

            return true;

        }

        if(inputValue == null || inputValue.length() == 0){// 如果參數值為空,則無需檢查

            return true;

        }

        for(int i = 0; i < wordList.size(); i++){

            inputValue = inputValue.toLowerCase();// 這里做,是為了不區分大小寫

            if(inputValue.indexOf(wordList.get(i).toLowerCase())>= 0){

StringBuffer sb = new StringBuffer();

                sb.append(“參數:”).append(paramName).append(“檢查未通過,”).append(“含有以下敏感詞匯:”).append(wordList.get(i))

                        .append(“。\n 謹記:\n”).append(“道路千萬條 \n 規范第一條 \n 數據不規范 \n 親人兩行淚”);

                this.cause = sb.toString();

                return false;

            }

        }

        return true;

    }

(2)配置自定義類

xml(raqsoftConfig.xml):

paramCheckClass 設置參數值校驗的類路徑

報表的SQL植入的概念

自定義錯誤信息的效果:

訪問 URL: http://localhost:6868/demo/reportJsp/showReport.jsp?rpx=a.rpx&arg2= 華北 union select * from users

報表的SQL植入的概念

到此,關于“報表的SQL植入的概念”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

sql
AI

翼城县| 金秀| 同心县| 孟村| 商城县| 郑州市| 图们市| 绥中县| 浦县| 瑞丽市| 仙游县| 洱源县| 宁城县| 金华市| 禹城市| 溆浦县| 炎陵县| 炉霍县| 荔浦县| 文登市| 昆山市| 鸡西市| 新竹市| 江安县| 江都市| 津南区| 太白县| 丹江口市| 冀州市| 连南| 宜都市| 二手房| 鹰潭市| 佛坪县| 扎兰屯市| 玛纳斯县| 武鸣县| 祥云县| 城步| 临潭县| 怀仁县|