整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          網(wǎng)站防止SQL注入的幾種方法

          網(wǎng)站防止SQL注入的幾種方法

          QL注入是網(wǎng)站常見的黑客攻擊行為之一,相信各大站長對此并不陌生,但是很多站長初遇SQL攻擊時都會感到不知所措。本文將對SQL進(jìn)行一些資料的收集,對針對SQL轉(zhuǎn)入提出一些對應(yīng)的解決方案,希望對各大站長有所幫助。

          什么是SQL注入

          SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令。具體來說,它是利用現(xiàn)有應(yīng)用程序,將(惡意的)SQL命令注入到后臺數(shù)據(jù)庫引擎執(zhí)行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網(wǎng)站上的數(shù)據(jù)庫,而不是按照設(shè)計(jì)者意圖去執(zhí)行SQL語句。比如先前的很多影視網(wǎng)站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊。

          如何判斷SQL注入漏洞

          經(jīng)專業(yè)人士總結(jié),有以下兩種方法可以判斷網(wǎng)站是否被SQL注入

          1、錯誤提示

          如果WEB網(wǎng)站開啟了錯誤顯示,攻擊者就可以通過反復(fù)調(diào)整發(fā)送的參數(shù)、查看頁面打印的錯誤信息,推測出WEB網(wǎng)站使用的數(shù)據(jù)庫和開發(fā)語言等重要信息。

          2、盲注

          除非是運(yùn)維人員疏忽,否則大多數(shù)的WEB運(yùn)營網(wǎng)站應(yīng)該都關(guān)閉錯誤提示信息,此時攻擊者一般會采用盲注的技巧來進(jìn)行反復(fù)的嘗試判斷。如果查看的網(wǎng)頁頁面的url地址為:userinfo.php?username=plhwin,此刻黑客分別訪問userinfo.php?username=plhwin’AND 1=1–hack和userinfo.php?username=plhwin’AND 1=2–hack,如果前者訪問能返回正常的信息而后者不能,就基本可以判斷此網(wǎng)站存在SQL注入漏洞,因?yàn)楹笳叩?=2這個表達(dá)方式永遠(yuǎn)不成立,所以即使username傳入了正確的參數(shù)也無法通過,由此可以推斷這個頁面存在SQL注入漏洞,并且可以通過username參數(shù)進(jìn)行注入。

          網(wǎng)站如何防止SQL注入

          1普通用戶與系統(tǒng)管理員用戶的權(quán)限要有嚴(yán)格的區(qū)分。

          如果一個普通用戶在使用查詢語句中嵌入另一個Drop Table語句,那么是否允許執(zhí)行呢?由于Drop語句關(guān)系到數(shù)據(jù)庫的基本對象,故要操作這個語句用戶必須有相關(guān)的權(quán)限。在權(quán)限設(shè)計(jì)中,對于終端用戶,即應(yīng)用軟件的使用者,沒有必要給他們數(shù)據(jù)庫對象的建立、刪除等權(quán)限。那么即使在他們使用SQL語句中帶有嵌入式的惡意代碼,由于其用戶權(quán)限的限制,這些代碼也將無法被執(zhí)行。故應(yīng)用程序在設(shè)計(jì)的時候,

          2強(qiáng)制使用參數(shù)化語句。

          如果在編寫SQL語句的時候,用戶輸入的變量不是直接嵌入到SQL語句。而是通過參數(shù)來傳遞這個變量的話,那么就可以有效的防治SQL注入式攻擊。也就是說,用戶的輸入絕對不能夠直接被嵌入到SQL語句中。與此相反,用戶的輸入的內(nèi)容必須進(jìn)行過濾,或者使用參數(shù)化的語句來傳遞用戶輸入的變量。參數(shù)化的語句使用參數(shù)而不是將用戶輸入變量嵌入到SQL語句中。采用這種措施,可以杜絕大部分的SQL注入式攻擊。不過可惜的是,現(xiàn)在支持參數(shù)化語句的數(shù)據(jù)庫引擎并不多。不過數(shù)據(jù)庫工程師在開發(fā)產(chǎn)品的時候要盡量采用參數(shù)化語句。

          3多使用SQL Server數(shù)據(jù)庫自帶的安全參數(shù)。

          為了減少注入式攻擊對于SQL Server數(shù)據(jù)庫的不良影響,在SQLServer數(shù)據(jù)庫專門設(shè)計(jì)了相對安全的SQL參數(shù)。在數(shù)據(jù)庫設(shè)計(jì)過程中,工程師要盡量采用這些參數(shù)來杜絕惡意的SQL注入式攻擊。

          如在SQL Server數(shù)據(jù)庫中提供了Parameters集合。這個集合提供了類型檢查和長度驗(yàn)證的功能。如果管理員采用了Parameters這個集合的話,則用戶輸入的內(nèi)容將被視為字符值而不是可執(zhí)行代碼。即使用戶輸入的內(nèi)容中含有可執(zhí)行代碼,則數(shù)據(jù)庫也會過濾掉。因?yàn)榇藭r數(shù)據(jù)庫只把它當(dāng)作普通的字符來處理。使用Parameters集合的另外一個優(yōu)點(diǎn)是可以強(qiáng)制執(zhí)行類型和長度檢查,范圍以外的值將觸發(fā)異常。如果用戶輸入的值不符合指定的類型與長度約束,就會發(fā)生異常,并報(bào)告給管理員。如上面這個案例中,如果員工編號定義的數(shù)據(jù)類型為字符串型,長度為10個字符。而用戶輸入的內(nèi)容雖然也是字符類型的數(shù)據(jù),但是其長度達(dá)到了20個字符。則此時就會引發(fā)異常,因?yàn)橛脩糨斎氲膬?nèi)容長度超過了數(shù)據(jù)庫字段長度的限制。

          4加強(qiáng)對用戶輸入的驗(yàn)證。

          總體來說,防治SQL注入式攻擊可以采用兩種方法,一是加強(qiáng)對用戶輸入內(nèi)容的檢查與驗(yàn)證;二是強(qiáng)迫使用參數(shù)化語句來傳遞用戶輸入的內(nèi)容。在SQLServer數(shù)據(jù)庫中,有比較多的用戶輸入內(nèi)容驗(yàn)證工具,可以幫助管理員來對付SQL注入式攻擊。測試字符串變量的內(nèi)容,只接受所需的值。拒絕包含二進(jìn)制數(shù)據(jù)、轉(zhuǎn)義序列和注釋字符的輸入內(nèi)容。這有助于防止腳本注入,防止某些緩沖區(qū)溢出攻擊。測試用戶輸入內(nèi)容的大小和數(shù)據(jù)類型,強(qiáng)制執(zhí)行適當(dāng)?shù)南拗婆c轉(zhuǎn)換。這即有助于防止有意造成的緩沖區(qū)溢出,對于防治注入式攻擊有比較明顯的效果。

          如可以使用存儲過程來驗(yàn)證用戶的輸入。利用存儲過程可以實(shí)現(xiàn)對用戶輸入變量的過濾,如拒絕一些特殊的符號。如以上那個惡意代碼中,只要存儲過程把那個分號過濾掉,那么這個惡意代碼也就沒有用武之地了。在執(zhí)行SQL語句之前,可以通過數(shù)據(jù)庫的存儲過程,來拒絕接納一些特殊的符號。在不影響數(shù)據(jù)庫應(yīng)用的前提下,應(yīng)該讓數(shù)據(jù)庫拒絕包含以下字符的輸入。如分號分隔符,它是SQL注入式攻擊的主要幫兇。如注釋分隔符。注釋只有在數(shù)據(jù)設(shè)計(jì)的時候用的到。一般用戶的查詢語句中沒有必要注釋的內(nèi)容,故可以直接把他拒絕掉,通常情況下這么做不會發(fā)生意外損失。把以上這些特殊符號拒絕掉,那么即使在SQL語句中嵌入了惡意代碼,他們也將毫無作為。

          故始終通過測試類型、長度、格式和范圍來驗(yàn)證用戶輸入,過濾用戶輸入的內(nèi)容。這是防止SQL注入式攻擊的常見并且行之有效的措施。

          5多層環(huán)境如何防治SQL注入式攻擊?

          在多層應(yīng)用環(huán)境中,用戶輸入的所有數(shù)據(jù)都應(yīng)該在驗(yàn)證之后才能被允許進(jìn)入到可信區(qū)域。未通過驗(yàn)證過程的數(shù)據(jù)應(yīng)被數(shù)據(jù)庫拒絕,并向上一層返回一個錯誤信息。實(shí)現(xiàn)多層驗(yàn)證。對無目的的惡意用戶采取的預(yù)防措施,對堅(jiān)定的攻擊者可能無效。更好的做法是在用戶界面和所有跨信任邊界的后續(xù)點(diǎn)上驗(yàn)證輸入。如在客戶端應(yīng)用程序中驗(yàn)證數(shù)據(jù)可以防止簡單的腳本注入。但是,如果下一層認(rèn)為其輸入已通過驗(yàn)證,則任何可以繞過客戶端的惡意用戶就可以不受限制地訪問系統(tǒng)。故對于多層應(yīng)用環(huán)境,在防止注入式攻擊的時候,需要各層一起努力,在客戶端與數(shù)據(jù)庫端都要采用相應(yīng)的措施來防治SQL語句的注入式攻擊。


          SSL證書采用了技術(shù)含量比較高的加密技術(shù)。日后GDCA(數(shù)安時代)將會持續(xù)為大家推薦更多關(guān)于SSL證書的技術(shù)知識。讓大家正確認(rèn)識SSL證書,快速無誤部署HTTPS安全協(xié)議。更多資訊,請關(guān)注GDCA。

          文章轉(zhuǎn)載:https://www.trustauth.cn/wiki/18364.html

          、SQL注入簡介SQL注入是比較常見的網(wǎng)絡(luò)攻擊方式之一,它不是利用操作系統(tǒng)的BUG來實(shí)現(xiàn)攻擊,而是針對程序員編程時的疏忽,通過SQL語句,實(shí)現(xiàn)無帳號登錄,甚至篡改數(shù)據(jù)庫。

          二、SQL注入攻擊的總體思路

          1.尋找到SQL注入的位置

          2.判斷服務(wù)器類型和后臺數(shù)據(jù)庫類型

          3.針對不通的服務(wù)器和數(shù)據(jù)庫特點(diǎn)進(jìn)行SQL注入攻擊

          三、SQL注入攻擊實(shí)例

          比如在一個登錄界面,要求輸入用戶名和密碼:

          可以這樣輸入實(shí)現(xiàn)免帳號登錄:

          用戶名: ‘or 1=1 –

          密 碼:

          點(diǎn)登陸,如若沒有做特殊處理,那么這個非法用戶就很得意的登陸進(jìn)去了.(當(dāng)然現(xiàn)在的有些語言的數(shù)據(jù)庫API已經(jīng)處理了這些問題)

          這是為什么呢? 下面我們分析一下:

          從理論上說,后臺認(rèn)證程序中會有如下的SQL語句:

          String sql="select * from user_table where username=

          ' "+userName+" ' and password=' "+password+" '";

          當(dāng)輸入了上面的用戶名和密碼,上面的SQL語句變成:

          SELECT * FROM user_table WHERE username=

          '’or 1=1 -- and password='’

          分析SQL語句:

          條件后面username=”or 1=1 用戶名等于 ” 或1=1 那么這個條件一定會成功;

          然后后面加兩個-,這意味著注釋,它將后面的語句注釋,讓他們不起作用,這樣語句永遠(yuǎn)都能正確執(zhí)行,用戶輕易騙過系統(tǒng),獲取合法身份。

          這還是比較溫柔的,如果是執(zhí)行

          SELECT * FROM user_table WHERE

          username='' ;DROP DATABASE (DB Name) --' and password=''

          ….其后果可想而知…

          四、應(yīng)對方法

          下面我針對JSP,說一下應(yīng)對方法:

          1.(簡單又有效的方法)PreparedStatement

          采用預(yù)編譯語句集,它內(nèi)置了處理SQL注入的能力,只要使用它的setXXX方法傳值即可。

          使用好處:

          (1).代碼的可讀性和可維護(hù)性.

          (2).PreparedStatement盡最大可能提高性能.

          (3).最重要的一點(diǎn)是極大地提高了安全性.

          原理:

          sql注入只對sql語句的準(zhǔn)備(編譯)過程有破壞作用

          而PreparedStatement已經(jīng)準(zhǔn)備好了,執(zhí)行階段只是把輸入串作為數(shù)據(jù)處理,

          而不再對sql語句進(jìn)行解析,準(zhǔn)備,因此也就避免了sql注入問題.

          2.使用正則表達(dá)式過濾傳入的參數(shù)

          要引入的包:

          import java.util.regex.*;

          正則表達(dá)式:

          private String CHECKSQL=“^(.+)\sand\s(.+)|(.+)\sor(.+)\s$”;

          判斷是否匹配:

          Pattern.matches(CHECKSQL,targerStr);

          下面是具體的正則表達(dá)式:

          檢測SQL meta-characters的正則表達(dá)式 :

          /(\%27)|(\’)|(\-\-)|(\%23)|(#)/ix

          修正檢測SQL meta-characters的正則表達(dá)式 :/((\%3D)|(=))[^\n]*((\%27)|(\’)|(\-\-)|(\%3B)|(:))/i

          典型的SQL 注入攻擊的正則表達(dá)式 :/\w*((\%27)|(\’))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

          檢測SQL注入,UNION查詢關(guān)鍵字的正則表達(dá)式 :/((\%27)|(\’))union/ix(\%27)|(\’)

          檢測MS SQL Server SQL注入攻擊的正則表達(dá)式:

          /exec(\s|\+)+(s|x)p\w+/ix

          等等…..

          3.字符串過濾

          比較通用的一個方法:

          (||之間的參數(shù)可以根據(jù)自己程序的需要添加)

          public static boolean sql_inj(String str){

          String inj_str="'|and|exec|insert|select|delete|update|

          count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

          String inj_stra[]=split(inj_str,"|");

          for (int i=0 ; i < inj_stra.length ; i++ ){

          if (str.indexOf(inj_stra[i])>=0){

          return true;

          }

          }

          return false;

          }

          4.jsp中調(diào)用該函數(shù)檢查是否包函非法字符

          防止SQL從URL注入:

          sql_inj.java代碼:

          package sql_inj;

          import java.net.*;

          import java.io.*;

          import java.sql.*;

          import java.text.*;

          import java.lang.String;

          public class sql_inj{

          public static boolean sql_inj(String str){

          String inj_str="'|and|exec|insert|select|delete|update|

          count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

          //這里的東西還可以自己添加

          String[] inj_stra=inj_str.split("\|");

          for (int i=0 ; i < inj_stra.length ; i++ ){

          if (str.indexOf(inj_stra[i])>=0){

          return true;

          }

          }

          return false;

          }

          }

          5.JSP頁面判斷代碼:

          使用javascript在客戶端進(jìn)行不安全字符屏蔽

          功能介紹:檢查是否含有”‘”,”\”,”/”

          參數(shù)說明:要檢查的字符串

          返回值:0:是1:不是

          函數(shù)名是

          function check(a){

          return 1;

          fibdn=new Array (”‘” ,”\”,”/”);

          i=fibdn.length;

          j=a.length;

          for (ii=0; ii<i; ii++)

          { for (jj=0; jj<j; jj++)

          { temp1=a.charAt(jj);

          temp2=fibdn[ii];

          if (tem’; p1==temp2)

          { return 0; }

          }

          }

          return 1;

          }

          總的說來,防范一般的SQL注入只要在代碼規(guī)范上下點(diǎn)功夫就可以了。

          凡涉及到執(zhí)行的SQL中有變量時,用JDBC(或者其他數(shù)據(jù)持久層)提供的如:PreparedStatement就可以 ,切記不要用拼接字符串的方法就可以了。

          圖片來源:unsplash.com[1]]

          前言

          Node.js和npm為前端生態(tài)中提供了統(tǒng)一的開發(fā)語言、強(qiáng)大的包管理和模塊生態(tài)系統(tǒng)、靈活的構(gòu)建工具和任務(wù)自動化、以及豐富的前端框架和庫等等。

          可以說,正是因?yàn)閚odejs帶來的這些工具和資源使前端開發(fā)更加高效、便捷,并推動了前端技術(shù)的快速發(fā)展。

          但是近年來,Node.js 生態(tài)系統(tǒng)中的 npm 軟件包中出現(xiàn)了許多 CVE("Common Vulnerabilities and Exposures" 常見漏洞和公開漏洞),譬如lodash庫的CVE漏洞——CVE-2018-16487[2]、express庫的CVE漏洞——CVE-2018-17346[3]以及jsonwebtoken庫的CVE漏洞——CVE-2018-12424[4]等等,在這其中有一個特別危險且屢禁不止的漏洞就是命令注入(Command Injection)

          作為前端工程師而言,在我們?nèi)粘9ぷ髦校粌H需要快速交付、優(yōu)化性能相關(guān),還要時刻對項(xiàng)目中所采用的nodejs技術(shù)棧及其安全相關(guān)的因素考慮在內(nèi)。

          簡而言之,關(guān)于安全這根弦兒得時刻緊繃著!

          命令注入[5]是一種攻擊,其目的是通過有漏洞的應(yīng)用程序在主機(jī)操作系統(tǒng)上執(zhí)行任意命令。當(dāng)應(yīng)用程序?qū)⒂脩籼峁┑牟话踩珨?shù)據(jù)(表單、cookie、HTTP 標(biāo)頭等)傳遞給系統(tǒng)shell時,就有可能發(fā)生命令注入攻擊。在這種攻擊中,攻擊者提供的操作系統(tǒng)命令通常是以受攻擊應(yīng)用程序的權(quán)限執(zhí)行的。命令注入攻擊之所以可能,主要是因?yàn)檩斎胄r?yàn)不足。

          這種攻擊與代碼注入不同,代碼注入允許攻擊者添加自己的代碼,然后由應(yīng)用程序執(zhí)行。在命令注入攻擊中,攻擊者擴(kuò)展應(yīng)用程序的默認(rèn)功能,執(zhí)行系統(tǒng)命令,而無需注入代碼。

          場景分析

          假設(shè)有某程序員a同學(xué)在某個nodejs項(xiàng)目中寫出了類似的代碼:

          const { exec }=require('child_process');
          
          function runCommand(userInput) {
            const command=`ls ${userInput}`; // 將用戶所輸入的內(nèi)容拼接到命令中
            exec(command, (error, stdout, stderr)=> {
              if (error) {
                console.error(`執(zhí)行命令時出錯:${error}`);
                return;
              }
              console.log(`命令執(zhí)行結(jié)果:${stdout}`);
            });
          }
          
          const userInput='; rm -rf /'; // 惡意用戶所輸入的內(nèi)容
          
          runCommand(userInput);
          

          我們簡單分析下以上代碼,這段程序可以將用戶所輸入的內(nèi)容直接拼接到命令行字符串中。如果因?yàn)轫?xiàng)目工期緊張,沒經(jīng)過code review匆忙上線,恰好碰到個別用戶所輸入的惡意的命令,例如'; rm -rf /',那么最終執(zhí)行的命令將變?yōu)?/span>ls ; rm -rf /,導(dǎo)致“刪庫跑路”的危險操作。

          當(dāng)然這只是為了舉例的簡單例子,實(shí)際項(xiàng)目中,發(fā)生命令注入的原因大多是沒有對用戶所輸入的內(nèi)容進(jìn)行嚴(yán)謹(jǐn)?shù)男r?yàn)

          命令注入 - 常見威脅

          命令注入是 Node.js 生態(tài)系統(tǒng)中真實(shí)而普遍的威脅。

          看似顯而易見的安全風(fēng)險,如以下代碼所示:

          var exec=require('child_process').execSync
          var platform=require('os').platform()
          
          module.exports=function(){
            var commands=Array.isArray(arguments[0]) ? arguments[0] : Array.prototype.slice.apply(arguments)
            var command=null
            commands.some(function(c){
              if (isExec(findCommand(c))){
                command=c
                return true
              }
            })
            return command
          }
          
          function isExec(command){
            try{
              exec(command, { stdio: 'ignore' })
              return true
            }
            catch (_e){
              return false
            }
          }
          function findCommand(command){
            if (/^win/.test(platform)){
              return "where " + command
            } else {
              return "command -v " + command
            }
          }
          

          上述命令注入漏洞是在 find-exec[6] npm 軟件包中發(fā)現(xiàn)的,該軟件包每周的下載量多達(dá) 2000 多次。雖然數(shù)量不多,但足以讓一些用戶面臨風(fēng)險。命令注入漏洞的后果可能是毀滅性的,從數(shù)據(jù)泄露到系統(tǒng)完全崩潰不等。

          現(xiàn)在我們再回過頭來看,到底什么是命令注入[7]?簡而言之,命令注入的核心是應(yīng)用程序允許未經(jīng)審核的用戶所輸入的內(nèi)容作為系統(tǒng)命令執(zhí)行。這些命令可操縱底層系統(tǒng),可能導(dǎo)致未經(jīng)授權(quán)的訪問、數(shù)據(jù)泄露,甚至完全破壞系統(tǒng)。

          fs-git

          在另外一個案例中,我們可以看下fs-git npm 軟件包(版本 1.0.1)這個看似無害的模塊是如何成為一個嚴(yán)重的安全隱患的:

          fs-git 是 Node.js 的一個 npm 包,能夠?yàn)?Git 倉庫提供類似于文件系統(tǒng)的 API,進(jìn)而可以讓開發(fā)人員更直觀、更容易地與 Git 倉庫交互。它擁有相當(dāng)數(shù)量的用戶群體,所以該安全隱患所造成的影響可見一斑。

          在1.0.1 版本的 fs-git 模塊中,被發(fā)現(xiàn)了編號為 CVE-2017-1000451[8]漏洞。該模塊依賴 child_process.exec 函數(shù)來執(zhí)行系統(tǒng)命令。然而,用于構(gòu)建執(zhí)行字符串的 buildCommand函數(shù)缺少嚴(yán)謹(jǐn)?shù)男r?yàn)邏輯,使其容易受到命令注入的攻擊。

          以下是fs-git 中存在漏洞的代碼片段:

              showRef(): Promise<RefInfo[]> {
                  let command=this._buildCommand("show-ref");
                  return new Promise((resolve: (value: RefInfo[])=> void, reject: (error: any)=> void)=> {
                      child_process.exec(command, { maxBuffer: maxBuffer }, (error, stdout, stderr)=> {
                          if (error) {
                              reject(error);
                          } else {
                              let list=stdout.toString("utf8").split("\n").filter(line=> !!line);
                              let resultList:RefInfo[]=list.map(str=> {
                                  let columns=str.split(" ", 2);
                                  返回 {
                                      gitDir: this.path、
                                      ref: columns[0]、
                                      name: columns[1]
                                  };
                              });
                              resolve(resultList);
          
          

          最終,代碼還將調(diào)用 _buildCommand 函數(shù),其中包含字符串連接和用戶提供的數(shù)據(jù):

              _buildCommand(...args: string[]): string {
                  return `git --git-dir=${this.path} ${args.join(" ") }`;
          

          當(dāng)攻擊者篡改傳遞給 fs-git 模塊的數(shù)據(jù)以制作利用命令注入漏洞的惡意代碼時,攻擊就展開了。通過提供精心制作的輸入,攻擊者能夠向系統(tǒng)注入任意命令。這樣,攻擊者就可以利用運(yùn)行進(jìn)程的權(quán)限執(zhí)行未經(jīng)授權(quán)的命令,從而可能危及主機(jī)系統(tǒng)。

          該漏洞影響深遠(yuǎn)。攻擊者可以執(zhí)行任意命令,其中可能包括外泄敏感數(shù)據(jù)、修改文件甚至破壞系統(tǒng)正常運(yùn)行等操作。對于依賴fs-git的項(xiàng)目和應(yīng)用程序來說,這個漏洞構(gòu)成了重大的安全風(fēng)險。

          這個案例充分說明了校驗(yàn)用戶所輸入的內(nèi)容和必要的數(shù)據(jù)清除在防止命令注入漏洞方面的重要性。

          所以即使是看似無害的模塊,如果不遵循安全編碼實(shí)踐,也會帶來嚴(yán)重的安全風(fēng)險。開發(fā)者在處理用戶所輸入的內(nèi)容的數(shù)據(jù)時必須十分謹(jǐn)慎。

          安全建議

          對于NodeJs項(xiàng)目,我們可以大致從以下幾點(diǎn)入手,從而減少命令注入的風(fēng)險:

          • 使用ORM(對象關(guān)系映射)庫:使用ORM庫可以幫助處理數(shù)據(jù)庫查詢,避免手動拼接SQL語句,從而減少SQL注入的風(fēng)險。

          譬如,筆者就在曾經(jīng)的Egg.js項(xiàng)目中使用過的Sequelize[9] ORM庫來執(zhí)行安全的數(shù)據(jù)庫操作。

          • 校驗(yàn)嚴(yán)謹(jǐn)

          對用戶所輸入的內(nèi)容進(jìn)行校驗(yàn)和過濾,以防止惡意輸入

          • 遵循安全編碼規(guī)范

          避免直接拼接用戶所輸入的內(nèi)容到命令字符串、使用安全的文件路徑拼接方法等。確保在代碼中進(jìn)行輸入校驗(yàn)和輸出轉(zhuǎn)義,并注意處理用戶所輸入的內(nèi)容時的邊界情況

          • NPM Audit & NSP

          使用經(jīng)過安全審計(jì)和更新頻繁的第三方庫,以減少潛在的安全漏洞。另外還可以使用工具如npm Audit[10]NSP(Node Security Platform)[11]來檢查項(xiàng)目依賴的安全性。

          回過頭看

          假設(shè)項(xiàng)目中需要使用到exec[12]spawn[13]方法時,如果沒有適當(dāng)?shù)臄?shù)據(jù)清理和校驗(yàn),用戶所輸入的內(nèi)容可能被惡意利用,導(dǎo)致命令注入攻擊。

          以下是一個簡單Demo說明這些類似的場景:

          const { exec, spawn }=require('child_process');
          
          // 示例:使用exec執(zhí)行命令
          function executeCommandWithExec(userInput) {
            const command=`ls ${userInput}`; // 拼接用戶所輸入的內(nèi)容的命令
          
            exec(command, (error, stdout, stderr)=> {
              if (error) {
                console.error(`執(zhí)行命令出錯:${error}`);
                return;
              }
              console.log(`命令執(zhí)行結(jié)果:${stdout}`);
            });
          }
          
          // 示例:使用spawn執(zhí)行命令
          function executeCommandWithSpawn(userInput) {
            const command='ls';
            const args=[userInput]; // 將用戶所輸入的內(nèi)容作為命令行參數(shù)
          
            const child=spawn(command, args);
          
            child.stdout.on('data', (data)=> {
              console.log(`命令執(zhí)行結(jié)果:${data}`);
            });
          
            child.stderr.on('data', (data)=> {
              console.error(`執(zhí)行命令出錯:${data}`);
            });
          }
          
          // 測試示例
          const userInput='; rm -rf /'; // 惡意的用戶所輸入的內(nèi)容,嘗試刪除整個系統(tǒng)
          
          executeCommandWithExec(userInput);
          executeCommandWithSpawn(userInput);
          

          在上面的示例中,executeCommandWithExec和executeCommandWithSpawn函數(shù)接受用戶所輸入的內(nèi)容,并將其用于執(zhí)行l(wèi)s命令。

          然而,如果惡意用戶所輸入的內(nèi)容像; rm -rf /這樣的內(nèi)容,它會將rm -rf /命令添加到ls命令后面,進(jìn)而導(dǎo)致"刪庫跑路"的悲劇發(fā)生。

          為了防止這種攻擊,應(yīng)該對用戶所輸入的內(nèi)容進(jìn)行適當(dāng)?shù)臄?shù)據(jù)清理和校驗(yàn)。

          所以對于以上代碼,可以使用安全的執(zhí)行方法execFilespawn,并將用戶所輸入的內(nèi)容作為命令行參數(shù)不是直接拼接到命令中:

          const { execFile, spawn }=require('child_process');
          
          // 示例:使用execFile執(zhí)行命令
          function executeCommandWithExecFile(userInput) {
            const command='ls';
            const args=[userInput]; // 將用戶所輸入的內(nèi)容作為命令行參數(shù)
          
            execFile(command, args, (error, stdout, stderr)=> {
              if (error) {
                console.error(`執(zhí)行命令出錯:${error}`);
                return;
              }
              console.log(`命令執(zhí)行結(jié)果:${stdout}`);
            });
          }
          
          // 示例:使用spawn執(zhí)行命令
          function executeCommandWithSpawn(userInput) {
            const command='ls';
            const args=[userInput]; // 將用戶所輸入的內(nèi)容作為命令行參數(shù)
          
            const child=spawn(command, args);
          
            child.stdout.on('data', (data)=> {
              console.log(`命令執(zhí)行結(jié)果:${data}`);
            });
          
            child.stderr.on('data', (data)=> {
              console.error(`執(zhí)行命令出錯:${data}`);
            });
          }
          
          // 測試示例
          const userInput='; rm -rf /'; // 惡意的用戶所輸入的內(nèi)容,嘗試刪除整個系統(tǒng)
          
          executeCommandWithExecFile(userInput);
          executeCommandWithSpawn(userInput);
          

          在上面的代碼實(shí)現(xiàn)中,executeCommandWithExecFile函數(shù)使用了execFile[14]方法來執(zhí)行命令,而executeCommandWithSpawn函數(shù)保持不變,仍然使用spawn方法執(zhí)行命令。

          使用execFile方法可以避免將用戶所輸入的內(nèi)容直接拼接到命令中,這樣可以在一定程度上減少命令注入攻擊的風(fēng)險。

          總結(jié)

          記住,無論采用哪種方案,主體思想都應(yīng)該是謹(jǐn)慎處理用戶所輸入的內(nèi)容,并進(jìn)行嚴(yán)謹(jǐn)?shù)男r?yàn),以確保代碼的安全性。


          [1]

          unsplash.com: https://unsplash.com/

          [2]

          CVE-2018-16487: https://nvd.nist.gov/vuln/detail/CVE-2018-16487

          [3]

          CVE-2018-17346: https://nvd.nist.gov/vuln/detail/CVE-2018-17346

          [4]

          CVE-2018-12424: https://nvd.nist.gov/vuln/detail/CVE-2018-12424

          [5]

          Command Injection: https://owasp.org/www-community/attacks/Command_Injection

          [6]

          find-exec: https://github.com/shime/find-exec/commit/74fb108097c229b03d6dba4cce81e36aa364b51c

          [7]

          Securing Your Node.js Apps by Analyzing Real-World Command Injection Examples: https://www.nodejs-security.com/blog/securing-your-nodejs-apps-by-analyzing-real-world-command-injection-examples

          [8]

          CVE-2017-1000451: https://github.com/advisories/GHSA-wp3j-gv53-4pg8

          [9]

          sequelize ORM: https://sequelize.org/

          [10]

          npm audit: https://docs.npmjs.com/cli/v8/commands/npm-audit/

          [11]

          NSP: https://github.com/nodesecurity/nsp

          [12]

          exec: https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

          [13]

          spawn: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

          [14]

          execFile: https://nodejs.org/docs/latest/api/child_process.html#child_processexecfilefile-args-options-callback


          作者:Rien.

          來源:微信公眾號:奇舞精選

          出處:https://mp.weixin.qq.com/s/ElsRQhNTI-Y3qGeVzDzvCA


          主站蜘蛛池模板: 国产成人无码一区二区在线观看| 一区二区视频免费观看| 天堂va视频一区二区| 国产视频一区二区在线观看| 精品一区二区三区AV天堂| 久久国产精品亚洲一区二区| 国产aⅴ一区二区三区| 高清精品一区二区三区一区| 中文字幕在线观看一区二区| 国产aⅴ一区二区| 无码视频一区二区三区| 色狠狠AV一区二区三区| 精品国产日产一区二区三区 | 老熟女五十路乱子交尾中出一区| 搜日本一区二区三区免费高清视频 | 日本一道一区二区免费看| 国产成人亚洲综合一区| 亚洲天堂一区在线| 中文字幕一区二区三区在线观看| 视频一区精品自拍| 日韩一区二区久久久久久| 中文字幕无线码一区| 精品亚洲一区二区三区在线观看 | 国产手机精品一区二区| 亚洲sm另类一区二区三区| 国产精品香蕉一区二区三区| 久久精品国产一区二区三区肥胖 | 99久久综合狠狠综合久久一区| 视频一区精品自拍| 日韩人妻无码一区二区三区久久 | 另类ts人妖一区二区三区| 亲子乱av一区区三区40岁| 免费无码A片一区二三区| 老熟妇高潮一区二区三区| 老熟妇高潮一区二区三区| 日本精品少妇一区二区三区| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 美女视频一区三区网站在线观看 | 免费一区二区三区| 精品日韩亚洲AV无码一区二区三区| 久久精品国产第一区二区三区 |