關於SQL INJECTION(SQL 植入) 安全問題 一問

edited 十月 2013 in 伺服器環境
我有一個自製登入頁面
有2個欄位,用戶名及密碼
沒做任何addslashes() FUNCTION等的檢查

我在自己電腦伺服器(wamp server)使用SQL INJECTION的漏洞 都成功登入到

可是我把登入頁面整個檔案上傳到一些網上免費空間
再用 SQL INJECTION 的漏洞,結果登入不到
這是什麼原因??

是否他們的伺服器本身有著安全機制避免到這些安全漏洞?

原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=7119

評論

  • edited 十二月 2012
    是否開啟了magic quote?
  • edited 十二月 2012
    jaychu.
    是開了

    那個伺服器是網上的免空間

    我是否不能隨意關閉?

    另外我想問現在大部份空間都開啓了magic quote???

    我家中所用的是WAMP SERVER
    經測試,magic quote關閉了
  • edited 十二月 2012
    基本上你應該是無法關掉,山不轉路轉
    把魔術引號再轉回原形就好啦...請參考
    http://stackoverflow.com/questions/517008/how-to-turn-off-magic-quotes-on-shared-hosting
  • edited 十二月 2012
    SoltyRain,謝
    如果是自己的SERVER,例如WAMP SERVER
    應該在那裡把magic quote開啓?
  • edited 十二月 2012
    php.ini or php.conf
  • edited 十二月 2012
    $account = $_POST;
    $sourcePassword = $_POST;
    $keyword = 'keyword'; <==關鍵字自己隨便想。
    $password = sha1($account . $keyword . $sourcePassword);
    最後你只要把上面的password存進資料庫當密碼就好了。
    取出方式同上。
    就是使用者輸入帳密後,你只要再加密去比對和資料庫的密碼欄是否相同就行了。
    因為不管他輸入什麼都會被編碼,輸入引號,輸入空白,輸入sql injection文字都會被強迫編碼。
    這麼一來他如果不輸入正確的帳密就根本不能登入。
    而且重點是因為是加密過的就不會是明碼。
    就算資料庫被入侵駭客也很難去反解這種「原則不可逆」的加密。
    多多少少可以避免帳密被盜的情形。
    缺點:就客戶忘記密碼你也幫不了他,只能請他使用忘記密碼功能寄信到email用臨時密碼登入後修改。
    另外就是驗證的資料庫語法就不用帳號和密碼都要比對。
    只要比對加密過後的密碼就知道是不是驗證成功了:(畢竟加密時就已經連帳號一起加密了)
    $sql = "SELECT * FROM `user` WHERE password = '{$password}'";
  • edited 十二月 2012
    tkdmaf , 你寫的有問題吧 ....
    你的 WHERE 只判斷 password ?
    如果要同時判斷 user , 那駭客針對 user 那邊去做 INJECTION 就成了

    這老問題了
    我 blog 有寫怎麼防
    http://www.pigo.idv.tw/archives/820
  • edited 十二月 2012
    @pigo:
    是的!where就只是判斷password。
    你要不要仔細看看上面的code我對password做了什麼事?
  • edited 十二月 2012
    @pigo:
    我知道你很想提pdo和mysql_real_escage_string();
    但那不是我想去講的「原本就應該知道的重點」。
    我要講的是:如何對於放在資料庫的東西也做加密的行為。
    畢竟你的想法是處理SQL INJECTION
    但我的想法是:怎麼樣在避免SQL INJECTION之上,還能保全在第一時間不會立刻暴露密碼。
    但然大家都知道這都是防君子不防小人。
    駭客總是有千百種方法能看光光你的資料。
    基本上我的做法來說,就是把帳密和一個關鍵字都加密成密碼。
    所以要存取那一筆資料,就是要把輸入的帳密做相同的加密再去比對。
    但因為加密的資料就是有包含了「帳號」和「密碼」
    所以根本就『不需要』寫成:
    $sql = "SELECT * FROM `user` WHERE account = '{$account}' AND password = '{$password}'";
    來取得該使用者的存在與否。
    以及取得他的資料。
    $sql = "SELECT * FROM `user` WHERE password = '{$password}'";
    這裡的$password都必須先被$password = sha1($account . $keyword . $sourcePassword);處理過。
    就算你在$_POST或$_POST放入sql injection字元也沒有用。
    因為通通都會被sha1編譯成加密格式(用md5也是可以的)
    當然編輯後你還想用pdo處理或是用mysql_real_escape_string()處理也是ok的。
    只不過sha1()加密後的東西根本不會有脫逸字元或魔術引號的問題。


  • edited 十二月 2012
    任何雜湊演算法都會有重複性的
    你的做法可能是在少量資料才不會發生問題
    萬一 password 被雜湊之後出現重複性會發生什問題 ?
  • edited 十二月 2012
    我對你每次就原本的想法問題挑不到毛病。
    就改挑其他毛病這一點真的很感冒。
    程師設計師之前要挑毛病的話實在挑不完。
    任何技術都可能有他的缺點和風險。
    怎麼用是人自己的問題。
  • edited 十二月 2012
    我的ci code我節錄那段下來了。
    $account = $this->input->post('account');
    $password = $this->input->post('password');
    $where = sha1($account.'XXXXXXXX'.$password);
    $query = $this->db->get_where('XXXXXX',$where);
    foreach($query->result() as $row){
    if($account == $row->account){
    $this->session->set_userdata('XXXXXXXX',$row->id);
    }
    }
    簡單來說!就算有mysql_real_escape_string()我還是不放心。
    所以我做了sha1之後,才去判斷帳號是否對應。
    $account的來源源自於ci的$this->input->post('account');
    CI本身就有針對sql_injection和其他的攻擊做了預處理。
    雜揍的可能重覆性這種事當初在設計時就想到了。
    但因為帳號本身就不可能把他做雜湊的加密。
    我根本上就不想打算即使處理過他還放進資料過做查詢。
    由於帳號是唯一鍵,就算雜湊值相同回饋的帳號也不可能會一樣。
    對於每次我都還得寫出我寫過的東西才能證明我有做其他的防制這一點真的很累。
    可是不講又好像常常被當成我沒做一樣。
  • edited 十二月 2012
    看你的程式還是有問題啊 . 就事論事吧
    你的 code 仍然只是判斷 db 中 password 一個欄位而已 , 仍是有重複性問題 ,
    既然是用了 sha , 就一定會有兩筆以上被抓出的可能
    這種情況發生的時候 , 該怎麼辦 ?
  • edited 十二月 2012
    就事論事的話~~~~~~~~~~~~~~~~~~
    我真的不知道你是怎麼看程式碼的。
    真的讓我非常驚訝!
    就算他取出100筆好了。(這機率低到我不想講了。光是要2筆一樣的機率就低到比中樂透還低了。)
    在比對帳號的時候也只有一筆會對到。
    難不成你會以為存入資料庫的時候就只有存密碼?帳號不存進去?
  • edited 十二月 2012
    問題是比對到的是誰的帳號呢 ?
    即便是 0.0000001% 的可能性 . 出錯了就是出錯了 . 剛好 好死不死就 login admin 的帳號
    難道程式設計師在預期會有錯誤的情形下 , 還是堅持一定要寫出可能有錯的 code 嗎 ?
    對你提出疑問 , 就是不想誤導其他人也跟著這麼做
    要加 hash 我百分百認同
    但也應該要把 user name 一併做判斷才是百分百抓到的是正確的吧
  • edited 十二月 2012
    另外你究竟是什麼時候產生了我沒有把帳號一起加進去判斷的錯覺?
    你要不要看清楚一點我sha()的內容是放那些東西?
    出來之後是用什麼去判斷資料對應是誰?
    還是說其實我會鏡花水月?所以你迷惑了?
  • edited 十二月 2012
    後面那段我沒去看 . 經你解說之後我終於如夢初醒知道你在寫甚麼鬼了 . 明明兩三行就能解決的事情 . 何必搞那麼複雜呢 ?
  • edited 十二月 2012
    我覺得廢話一堆沒用。
    你自己去裝ci寫寫看。
    程式設計師用嘴巴講不懂那就請實際寫一下好了。
    不然我和你就只是光說不練。
  • edited 十二月 2012
    是啊!我當然知道二三行就能解決。
    老子我就是不爽進來的資料直接放進去判斷不行嗎?
    老子我心裡就是覺得怪怪的那樣不能信任,所以想多一點東西來防制一下不ok嗎?
  • edited 十二月 2012
    「後面那段我沒去看 . 」
    那不管你想講什麼可以以後都「看清楚」人家文章在「寫些什麼」再「發言」ok?
    不要文章「沒看完」就一股惱的想「指正人家」這樣「非常不好」。
    請改進一下。
    你有你的堅持,我自然也有我的做法。
    目標是一樣的,只是做法不一定相同。
  • edited 十二月 2012
    別氣惱.這論壇沒甚麼人氣的.需要激烈的討論
    你說的對 . 目標是一樣的 . 就如同下面的笑話一樣

    Q: how to get tomorrow date

    A:

    Sub tomorrow {
    sleep( 86400 );
    return localtime();

    }
  • edited 十二月 2012
    pigo 寫道:
    別氣惱.這論壇沒甚麼人氣的.需要激烈的討論
    你說的對 . 目標是一樣的 . 就如同下面的笑話一樣

    Q: how to get tomorrow date

    A:

    Sub tomorrow {
    sleep( 86400 );
    return localtime();

    }

    哈哈~程式能動就好~能動就好..
Sign In or Register to comment.