標籤:cgi php js html web安全
1、有關html/css, js, php, cgi 的一些認識
當我們瀏覽器訪問一個網站的靜態檔案,會把檔案內容都下載下來(一般壓縮),當然如果遇到外聯的css/js,會再發起請求得
到。如果我們右鍵查看網頁原始碼,一片混亂沒法看,可以使用firefox + firebug,可以清晰看到html dom tree,右鍵inspect
element 可以很快定位到tree node,由於是下載到本地,所以可以自己嘗試修改element 查看效果,這並不影響伺服器上的原始
檔案。最後瀏覽器會開始渲染,包括執行js比如document.write() 之類,就呈現出現在我們所看到的網頁模樣。
CGI 的意思是啥?不是一種語言,也不是一種技術,而是一種模式。搜尋一下CGI的定義Common Gateway Interface,簡稱
CGI。在物理上是一段程式,存放在伺服器上。只要是提供HTML的伺服器端程式都可以叫CGI,ASP/PHP/JSP這些都是,你用
C/C++寫一個可以提供HTML的伺服器端bin檔案,也叫CGI,至於python/perl/shell 等指令碼當然也能寫cgi。
對一個 CGI 程式,做的工作其實只有:從環境變數(environment variables)和標準輸入(standard input)中讀取資料、處理資料、
向標準輸出(standard output)輸出資料。環境變數中儲存的叫 Request Meta-Variables,也就是諸如 QUERY_STRING、
PATH_INFO 之類的東西,這些是由 Web Server 通過環境變數傳遞給 CGI 程式的,CGI 程式也是從環境變數中讀取的。
標準輸入中存放的往往是使用者通過GET 或者 POST 提交的資料,這些資料也是由 Web Server 傳過來的(用戶端提交)。傳統的
get 即是以 url?key1=value1&key2=value2的 形式傳輸過去。而post 形式(http請求包體)就比較多了,可以是傳統的
key=value,也可以是json/xml 等形式,只是這些從標準輸入得到後還需要經過一個解析的過程才能得到想要的key=value 形式的
呈現。
當然cgi 的body輸出也是多種形式了,可以是簡單的json/xml 形式,也可以是php echo 出一個text/platin or text/html,但要明
確的是php 等指令碼是在服務器端執行的,也就是說當用戶端訪問test.php 時,server 先執行php指令碼(php 會 讀取標準輸入,處
理過程,向標準輸出輸出數據),形象地來說,就是“戳一次就動一次”,根據使用者輸入的不同而產生不同的輸出結果,即動態網
頁的概念。注意,php, js css, 都可以和html 標籤寫在同個html 檔案中。
有時候訪問出現403 forbidden ,有種原因是 apache 設定的user,即運行httpd的user 是nobody(假設),對你想要訪問的目
錄/檔案 沒有讀或者執行的許可權,所以server 沒辦法讀取執行檔案,故 禁止訪問。
2. 從瀏覽器 url發出的請求,如果進行了 urlencode,比如將 " 轉成%22 發出去,在伺服器端的php 接收到的是原始
的" 還是編碼後的%22 得看用$GET["key"] 還是$_SERVER[‘QUERY_STRING‘],還要看在php 指令碼內有沒有做
addslashes 或者 htmlspecialchars 等函數調用,這樣就能判斷解析指令碼 echo 出來的html 是怎樣的組織形式,當然客
戶端請求得到的html 也就是這樣的形式了。
那為什麼在chrome中對於< 等沒有alert 彈窗呢,只是因為某些瀏覽器有anti_xss 模組或者filter,在瀏覽器解析html 的
時候 過濾掉這些危險的script 而沒有執行。
htmlspecialchars 會把 < 編碼成 < 還有 >,",‘ 等
addslashes() 函數在指定的預定義字元前添加反斜線。這些預定義字元是:
單引號 (‘)
雙引號 (")
反斜線 (\)
NULL
這樣就無法從url 傳遞帶引號的參數來閉合引號來達到xss的目的,但是在charset=gbk 的情況下,如果參數含大於
127的值如%ae,後面再跟引號,雖然引號變成\‘, 但%ae\ 在gbk 看來也許是一個字元,當然我們看起來好像是一個
亂碼,這樣也會造成引號可以閉合,sql 注入也存在這樣的字元集解析問題。設定了某種字元集,瀏覽器會按這種編
碼去解析html 來展示給使用者。
3. 反斜線 \ 在script域內會起轉義作用,而在html 標籤內就是表示的字元含義,從下面alert()出來的字元可以得知。
<script> var test="a\""; alert(test); </script>
<script> var test=‘a\‘‘; alert(test); </script>
<script> var test=‘a‘; alert(test); </script>
<input type="text" value="a\" onmousemove=alert(/xss/) " />
工作中有關web安全的片段記錄(不定時更新)