<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                PgSQL 9.4.1在2015年2月5日發布,主打的是安全方面的更新,修補了如下的安全漏洞: * CVE-2015-0241 Buffer overruns in “to_char” functions. * CVE-2015-0242 Buffer overrun in replacement printf family of functions. * CVE-2015-0243 Memory errors in functions in the pgcrypto extension. * CVE-2015-0244 An error in extended protocol message reading. * CVE-2014-8161 Constraint violation errors can cause display of values in columns which the user would not normally have rights to see. 也就是說,在9.4 GA版本中,是存在這些安全漏洞的,9.4.1把它們修復了。好消息是,阿里云的RDS PG將直接采用更安全的9.4.1版本。下面我們不妨分析一下這些漏洞的具體情況,看看如果使用9.4 GA,有哪些安全隱患。 ## CVE-2015-0244 比較起來,CVE-2015-0244這個漏洞較嚴重些,我們做重點分析。從修復這個問題的代碼改動([patch](http://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=2b3a8b20c2da9f39ffecae25ab7c66974fbc0d3b))可以看出,問題主要出在前后端通信過程中。最簡單的觸發方式,是利用Query Cancellation機制。這里有必要先介紹一下前后端的通信過程和Query Cancellation的實現邏輯。 客戶端連接PG時,后端建立一個backend(即后臺進程)為其服務,服務邏輯主要在PostgresMain()中。PostgresMain()有一個無條件for循環,不斷從客戶端讀取新的SQL命令,并進行處理。PG每次從客戶端讀取8K大小的消息;如果一個SQL比較大,大小超過8K,則需要多次讀取。 讀取一次客戶端消息的調用序列如下: ~~~ PostgresMain -> ReadCommand -> SocketBackend -> pq_getmessage | V recv <- secure_read <- pq_recvbuf <- pq_getbytes ~~~ 其中pq_recvbuf調用secure_read每次讀取8K的數據。如果一個SQL很大,比如 ~~~ INSERT INTO tablename VALUES (1), (2),.....,(10000000) ~~~ 則需要反復調用secure_read。此時如果用戶端發起了一個Query Cancellation,比如在psql控制臺按下了Ctl+c,則PG后臺進程最終會收到一個SIGINT信號,觸發它中斷當前的處理,跳轉到信號處理函數StatementCancelHandler。其后的函數調用過程如下: ~~~ StatementCancelHandler -> ProcessInterrupts -> elog( ERROR,......) | V siglongjmp <- PG_RE_THROW <- errfinish ~~~ 可見,最后PG利用siglongjmp,實現了調轉。跳轉到哪里了呢?我們知道,siglongjmp一般和sigsetjmp成對使用;查看PostgresMain函數,可以發現下面這一行: ~~~ if (sigsetjmp(local_sigjmp_buf, 1) != 0) ~~~ 實際上,siglongjmp就是跳轉到這一行,繼續執行。接下來執行的邏輯正好是對事務執行回滾和對session(即當前連接)環境做初始化,接著就又開始調用ReadCommand,繼續從客戶端讀取消息了。 仔細分析上述過程,可以發現一個問題:如果PG在讀取一個客戶端消息的中間,收到了一個Query Cancellation信號,則PG會回滾事務,并將狀態改為等待讀取新消息,然后再次調用ReadCommand讀消息。但是,此時還是從原來的網絡連接中,調用recv讀取,所以讀取到消息,有可能是上一個消息的一部分。就是說,PG可能把上一個消息的一部分,當做一個新的消息的開始來處理!攻擊者可以利用這一點,將一個完整的消息,注入到原SQL中,繞過前端的檢查,執行原來不被允許的SQL。例如,如果一個網站前端有一個這樣的SQL語句: ~~~ INSERT INTO table VALUES ( ? ) ~~~ 問號部分,由用戶輸入并由前端代碼填充。正常情況下,如果用戶的注入一個`'DELETE FROM table'`,企圖刪除整個表,是不符合語法的,PG會返回錯誤。但利用這個漏洞,用戶可以在PG接收這個SQL的時候,撤銷這次SQL操作,如果用戶發起一個Query Cancellation,最終向后臺進程發SIGINT信號,則可能會導致后臺進程跳轉到新消息讀取階段,繼續讀取消息。此時如果恰好讀取到DELETE語句的開頭,那么就可以把注入的SQL作為一個新的完整SQL成功執行。 此漏洞直接的修復方法是,在讀取一個消息過程中,設置一個狀態標識,表明目前正在讀取消息的階段。當發生Query Cancellation中斷或者其他會造成中斷處理的錯誤,后臺進程跳轉到中斷處理代碼,回滾當前事務后,檢測狀態標識。如果狀態標識被設置,說明是從消息讀取階段被中斷的,則直接使用elog( FATAL,…)退出后臺進程,并斷開連接, ## CVE-2015-0241 這個漏洞涉及兩個小問題: 一個是to_char代碼里面在處理localized month(在具體某個locale下的月份名,例如,”January”在中文locale里面是”一月”)和 localized week day(具體某個locale下得星期的名稱,例如,”Monday”在中文里面是”星期一”)時,使用的數組過小,在某些locale下面可能指針越界。 另一個小問題是,to_char在將輸入的float類型轉換為字符串時,如果指定格式的字符串過長,可能造成存放結果的數組不夠大而內存越界。 為修復此漏洞,在下面的文件里面增大了處理數組長度,并加入了對長度的判斷。 ~~~ src/backend/utils/adt/formatting.c ~~~ ## CVE-2015-0242 這個漏洞是PG自帶的snprintf函數,在較大的精度要求時可能導致存放結果的數組過小而造成內存越界。這個問題只影響沒有snprintf支持的平臺。 ## CVE-2015-0243 只影響插件pgcrypto。主要由于此插件所使用的imath的版本有了變化,造成原來代碼里面假設的所調用函數的返回值長度有變化,可能造成數組溢出。 ## CVE-2014-8161 由于疏忽,`BuildIndexValueDescription`,?`ExecBuildSlotValueDescription`以及?`ri_ReportViolation`等函數在打印出錯信息時,會把用戶無權知道的信息打印出來。例如,在插入數據到一個有非空約束的表中時,用戶會看到如下的出錯信息: ~~~ INSERT INTO t1 (c1) VALUES (5); ERROR: null value in column "c2" violates not-null constraint DETAIL: Failing row contains (c1) = (5). ~~~ 用戶實際上沒有查看c2這個字段的權限,所以不應該讓其感知到c2字段的存在。而這個錯誤信息暴露了這一點。 再如,假設用戶沒有查看c1字段值的權限,只有查看c3字段的權限并且c3上有值域約束,則在對c3賦值時,如果使用一個不符合值域約束的值,會提示錯誤,并且錯誤信息會把c1的值打印出來: ~~~ UPDATE t1 SET c3 = 10; ERROR: new row for relation "t1" violates check constraint "t1_c3_check" DETAIL: Failing row contains (c1, c3) = (1, 10). ~~~ 這樣用戶很容易通過執行類似`update set c3 = "any value"`?的語句,把c1的值打出來,造成信息泄露。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看