Server Side Includes(SSI)是一種伺服器端的指令集,讓 Web 伺服器在將 HTML 回應傳送給瀏覽器之前,先解析並執行嵌入在 HTML 中的特殊指令。這通常用於靜態網站中動態插入共用元件,例如頁首、頁尾、導覽列等,避免在每個頁面重複相同的 HTML 程式碼。
SSI 的基本概念
SSI 指令以 HTML 註解語法包裝,格式為:
伺服器在傳送回應前會掃描這些指令並替換成對應的內容,瀏覽器看到的是已處理完的 HTML,完全不知道 SSI 的存在。
常用 SSI 指令
include - 引入其他檔案
1
2
3
4
5
6
|
<!-- 引入相對路徑的檔案 -->
<!--#include virtual="/header.html" -->
<!--#include virtual="../footer.html" -->
<!-- 引入實體路徑(相對於目前文件)-->
<!--#include file="sidebar.html" -->
|
echo - 輸出環境變數
1
2
3
4
5
6
7
8
|
<!-- 顯示目前文件的最後修改時間 -->
<!--#echo var="LAST_MODIFIED" -->
<!-- 顯示訪客 IP -->
<!--#echo var="REMOTE_ADDR" -->
<!-- 顯示目前頁面 URL -->
<!--#echo var="REQUEST_URI" -->
|
set - 設定自訂變數
1
2
|
<!--#set var="pageTitle" value="關於我們" -->
<title><!--#echo var="pageTitle" --></title>
|
if / elif / else - 條件判斷
1
2
3
4
5
|
<!--#if expr="${QUERY_STRING} = 'admin'" -->
<p>管理員模式</p>
<!--#else -->
<p>一般使用者</p>
<!--#endif -->
|
exec - 執行系統指令或 CGI
1
2
|
<!-- 執行 shell 指令(需啟用 exec 功能) -->
<!--#exec cmd="date" -->
|
在 Apache 中啟用 SSI
- 啟用
mod_include 模組:
- 在
httpd.conf 或 .htaccess 中設定:
1
2
3
4
5
6
|
# 允許特定目錄啟用 SSI
<Directory "/var/www/html">
Options +Includes
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</Directory>
|
- 將需要使用 SSI 的檔案副檔名改為
.shtml,或設定 .html 也支援 SSI:
1
2
|
AddType text/html .html
AddOutputFilter INCLUDES .html
|
安全性注意事項
SSI Injection 攻擊
若網站將使用者輸入直接嵌入到 SSI 解析的頁面中,攻擊者可能注入惡意 SSI 指令,例如:
1
2
|
<!-- 攻擊者在表單欄位中輸入 -->
<!--#exec cmd="cat /etc/passwd" -->
|
如果這段內容被直接寫入到 .shtml 檔案中,伺服器會執行 cat /etc/passwd 並將結果輸出給使用者。
防護措施
- 永遠對使用者輸入進行 HTML 跳脫,避免注入 SSI 指令
- 停用
exec 功能,除非絕對必要:
1
|
Options +Includes -ExecCGI
|
- 限制 SSI 解析範圍,只對特定目錄啟用
現代替代方案
SSI 雖然簡單,但已是較舊的技術。現代 Web 開發中有更好的替代方案:
| 方案 |
說明 |
| 靜態網站產生器 |
Hugo、Jekyll、Next.js 等,build time 合併元件 |
| 模板引擎 |
Jinja2、Handlebars、Blade,在後端渲染 |
| 前端框架 |
React、Vue、Angular 的元件化設計 |
| Nginx SSI |
Nginx 也支援 SSI,語法相同但效能更好 |
SSI 仍適合用於純靜態網站的小型共用元件場景,但若網站已使用後端語言(PHP、Node.js 等),建議直接使用各語言的 include 或模板機制。
參考資料