Mod-Security

ModSecurity:SecAction 中的 setenv 無效

  • September 13, 2018

我正在嘗試調試 ModSecurity 的問題。在 Apache 2.4.33 上使用 ModSecurity 2.9.2。我已經盡可能簡化了情況,但遇到了障礙。我在虛擬主機配置中工作。這是我正在嘗試做的事情:

SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE

在沒有其他規則的情況下,這應該始終設置 X-Debug 標頭,但事實並非如此。為了找出原因,首先我刪除了 SecAction 並這樣做了:

RewriteRule .* - [E=TESTPAGE]
Header always set X-Debug "IsTest" env=TESTPAGE

果然,在這種情況下設置了標頭,所以我知道標頭正在工作並且可以設置/檢查環境變數。然後我嘗試了這個:

SecAction "deny,status:503,setenv:TESTPAGE=1,nolog,id:10001001"

事實上,我被 503 http 程式碼阻止了,所以我知道正在處理 SecAction。鑑於這兩件事,唯一的可能性是 ModSec 未能按應有的方式設置環境變數,但我不知道為什麼會出現這種情況。

編輯#1

由於某種原因,“拒絕”設置現在不再阻止頁面處理。所以我仍然得到狀態程式碼集,或者如果我保留“拒絕”但刪除“狀態”指令,我會得到一個 403 程式碼,我認為這是“拒絕”的預設值,但頁面本身仍然載入。不確定這是否與未設置環境變數的原因相同。

事實證明這是由於 mod_rewrite 的內部重寫,由於在 Symfony2 應用程序的上下文中執行它,該應用程序將所有請求重寫到其 app.php 控制器。同樣的事情也會發生在像 wordpress 這樣將所有內容重寫為 index.php 的 CMS 中,或者在其他內部重寫 url 的 url 美化方案中。(注意,這不是瀏覽器重定向的問題,因為這些會導致一個全新的請求,只是內部重寫。)基本上在你最後一次重寫完成後,apache htaccess 和配置邏輯再次執行,並且它在那次執行設置您的最終環境變數等。因此,如果在重寫之前設置了一個變數,那麼它之後將不可用(就像我試圖在此處設置問題中的標題時一樣)。

即使問題中的這兩行是相鄰的……

SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE

第一行在請求正文階段(modsec 階段 2)根據預設值執行,因為我沒有指定階段。對 app.php 的重寫(由於未顯示 .htaccess 規則)隨後發生。因此,當設置 Header 時,變數不再存在。

但是,所有預重寫變數仍然可以使用“redirect_”前綴。所以要解決這個問題,我需要這樣寫:

SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=REDIRECT_TESTPAGE

或者,如果我不確定請求是否會被重定向,我可以使用兩個版本:

SecAction "pass,setenv:TESTPAGE=1,nolog,id:10001001"
Header always set X-Debug "IsTest" env=TESTPAGE
Header always set X-Debug "IsTest" env=REDIRECT_TESTPAGE

(可能有一種方法可以將它們結合起來;不確定您是否可以在 apache ’env’ 語句中使用 OR 邏輯;如果可以,請發表評論!)

**編輯:**關於“拒絕”不再起作用,這也是由於某種方式的重定向。Mod Security 預設拋出 500 錯誤,但預設的 500 錯誤頁面 500.shtml 不存在。因此,框架攔截了該請求並將其發送回 app.php,app.php 然後查看請求 URL 並繼續載入最初請求的頁面,儘管出現錯誤。如果配置的 ErrorDocument 存在,則拒絕正常工作並顯示該文件。

引用自:https://serverfault.com/questions/914377