隨著網路應用程式日漸普及,網頁安全也成為開發者不可忽視的重要議題。本文將探討常見的網頁安全威脅,包括跨來源資源共用(CORS)、跨站請求偽造(CSRF)和點選劫持(Clickjacking),並提供相應的防禦策略與實務做法。理解這些安全議題並實施有效的防禦措施,有助於開發者建構更安全的網頁應用程式,保障使用者資料與系統安全。從 CORS 的設定與原理,到 CSRF 和 Clickjacking 的攻擊手法與防禦技巧,本文將提供全面的安全知識,協助開發者提升網站安全性。
CORS的應用
CORS可以用於許多場景,例如:
- 跨域資源分享:允許網頁從不同的源請求資源。
- API設計:允許API被不同源的網頁呼叫。
- 微前端架構:允許不同源的網頁之間分享資源。
範例
以下是兩個CORS的範例:
範例1:使用Google字型
<html>
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Caveat&display=swap">
<style>
body {
font-family: 'Caveat', serif;
}
</style>
</head>
<body>
Text displayed in Caveat font
</body>
</html>
在這個範例中,網頁請求Google字型,並且Google伺服器傳回一個包含Access-Control-Allow-Origin: *
頭的回應,允許所有源存取字型。
範例2:跨域資源分享
<script>
fetch('https://example.com/trending')
.then(response => response.json())
.then(data => {
const widget = document.getElementById('widget');
//...
});
</script>
在這個範例中,網頁請求一個不同源的資源,並且伺服器傳回一個包含Access-Control-Allow-Origin: https://example.com
頭的回應,允許只有https://example.com
源存取資源。
CORS 的實作與設定
CORS(Cross-Origin Resource Sharing)是一種機制,允許網頁從不同的網域名稱或埠取得資源。這是因為瀏覽器的同源政策(SOP)限制了網頁只能從相同的網域名稱和埠取得資源。
CORS 的設定
要實作 CORS,需要在伺服器端設定相關的 HTTP 標頭。其中,Access-Control-Allow-Origin
是最基本的設定,指定哪些網域名稱可以存取伺服器的資源。
例如,設定 Access-Control-Allow-Origin
為 *
,表示所有網域名稱都可以存取伺服器的資源。
Access-Control-Allow-Origin: *
Django 中的 CORS 設定
在 Django 中,可以使用 django-cors-headers
套件來實作 CORS。首先,需要安裝這個套件:
pipenv install django-cors-headers
然後,在 settings.py
中新增 corsheaders
到 INSTALLED_APPS
中:
INSTALLED_APPS = [
#...
'corsheaders',
]
並且在 MIDDLEWARE
中新增 CorsMiddleware
:
MIDDLEWARE = [
#...
'corsheaders.middleware.CorsMiddleware',
#...
]
Access-Control-Allow-Origin 的設定
要設定 Access-Control-Allow-Origin
,需要在 settings.py
中定義 CORS_ALLOWED_ORIGINS
或 CORS_ALLOW_ALL_ORIGINS
。
例如,設定 CORS_ALLOWED_ORIGINS
為特定的網域名稱:
CORS_ALLOWED_ORIGINS = [
'http://example.com',
'http://example.net',
]
或設定 CORS_ALLOW_ALL_ORIGINS
為 True
,允許所有網域名稱存取:
CORS_ALLOW_ALL_ORIGINS = True
URL 模式的設定
可以使用 CORS_URLS_REGEX
來設定特定的 URL 模式允許 CORS 存取。
例如,設定 CORS_URLS_REGEX
為特定的 URL 模式:
CORS_URLS_REGEX = r'^/shared_resources/.*$'
這樣就可以允許特定的 URL 模式存取伺服器的資源。
CORS 的原理和實踐
CORS(Cross-Origin Resource Sharing)是一種機制,允許 Web 開發者在不同網域名稱之間分享資源。它可以讓瀏覽器在不同網域名稱之間傳送請求,從而實作跨域資源分享。
CORS 的工作原理
CORS 的工作原理是根據瀏覽器和伺服器之間的通訊。當瀏覽器傳送請求到不同網域名稱的伺服器時,瀏覽器會自動新增一個 Origin
標頭,標頭中包含了請求的來源網域名稱。伺服器收到請求後,會根據 Origin
標頭中的網域名稱決定是否允許請求。
如果伺服器允許請求,則會在回應中新增一個 Access-Control-Allow-Origin
標頭,標頭中包含了允許的網域名稱。如果瀏覽器收到回應中包含了 Access-Control-Allow-Origin
標頭,則會允許請求。
CORS 的設定
CORS 的設定可以透過以下幾種方式實作:
- 設定
Access-Control-Allow-Origin
標頭:伺服器可以在回應中新增Access-Control-Allow-Origin
標頭,指定允許的網域名稱。 - 設定
CORS_ORIGIN_ALLOW_ALL
引數:如果設定CORS_ORIGIN_ALLOW_ALL
引數為True
,則允許所有網域名稱傳送請求。 - 設定
CORS_ORIGIN_WHITELIST
引數:可以設定CORS_ORIGIN_WHITELIST
引數,指定允許的網域名稱列表。 - 設定
CORS_ORIGIN_REGEX_WHITELIST
引數:可以設定CORS_ORIGIN_REGEX_WHITELIST
引數,指定允許的網域名稱正規表示式列表。
CORS 的預檢請求
CORS 的預檢請求是一種機制,允許瀏覽器在傳送請求之前先傳送一個預檢請求,以確定伺服器是否允許請求。預檢請求使用 OPTIONS
方法傳送,並包含了以下幾個標頭:
Access-Control-Request-Method
:指定了請求方法。Access-Control-Request-Headers
:指定了請求標頭。
伺服器收到預檢請求後,會根據請求方法和標頭決定是否允許請求。如果允許請求,則會在回應中新增以下幾個標頭:
Access-Control-Allow-Methods
:指定了允許的請求方法。Access-Control-Allow-Headers
:指定了允許的請求標頭。
CORS 預檢請求的處理
CORS(Cross-Origin Resource Sharing)是一種機制,允許網頁從不同於自己所在的網域名稱、協定或埠號的伺服器上請求資源。當瀏覽器偵測到跨域請求時,會自動傳送預檢請求(Preflight Request)給伺服器,以確定伺服器是否允許跨域請求。
預檢請求的觸發條件
預檢請求會在以下情況下被觸發:
- 請求方法不是 GET、HEAD 或 POST。
- 請求包含非標準的 HTTP 標頭。
- 請求包含非標準的 Content-Type 標頭,例如 application/json。
預檢請求的流程
當瀏覽器傳送預檢請求時,會包含以下標頭:
Access-Control-Request-Method
:指定了實際請求的方法,例如 PUT。Access-Control-Request-Headers
:指定了實際請求的標頭,例如 Content-Type。
伺服器收到預檢請求後,需要傳回包含以下標頭的回應:
Access-Control-Allow-Methods
:指定了允許的請求方法,例如 GET、OPTIONS、PUT。Access-Control-Allow-Headers
:指定了允許的請求標頭,例如 accept、accept-encoding、content-type 等。
如果伺服器傳回的回應包含了允許的方法和標頭,瀏覽器就會傳送實際的請求。如果伺服器傳回的回應不包含允許的方法和標頭,瀏覽器就會丟擲錯誤。
使用 Django-CORS-Headers 處理預檢請求
Django-CORS-Headers 是一個 Django 的套件,提供了一個簡單的方式來處理 CORS 預檢請求。以下是如何使用它來設定預檢請求的回應:
from django.conf import settings
from corsheaders.defaults import default_headers
CORS_ALLOWED_ORIGINS = [
'http://localhost:8000',
]
CORS_ALLOW_METHODS = [
'GET',
'OPTIONS',
'PUT',
]
CORS_ALLOW_HEADERS = default_headers + [
'content-type',
]
在上面的例子中,我們設定了允許的來源、方法和標頭。這樣,當瀏覽器傳送預檢請求時,Django-CORS-Headers 會自動傳回包含了允許的方法和標頭的回應。
內容解密:
在上面的程式碼中,我們使用了 Django-CORS-Headers 來設定預檢請求的回應。這樣可以簡化 CORS 的設定,並且讓我們可以專注於開發應用程式。同時,我們也需要注意預檢請求的觸發條件和流程,以確保我們的應用程式可以正常工作。
圖表翻譯:
sequenceDiagram participant Browser as 瀏覽器 participant Server as 伺服器 Note over Browser,Server: 預檢請求流程 Browser->>Server: 傳送預檢請求 (OPTIONS) Server->>Browser: 傳回預檢請求的回應 (Access-Control-Allow-Methods, Access-Control-Allow-Headers) Browser->>Server: 傳送實際請求 (PUT) Server->>Browser: 傳回實際請求的回應
在上面的圖表中,我們展示了預檢請求的流程。瀏覽器首先傳送預檢請求給伺服器,伺服器傳回包含了允許的方法和標頭的回應。然後,瀏覽器傳送實際的請求給伺服器,伺服器傳回實際請求的回應。
CORS 設定最佳實踐
在開發 Web 應用程式時,CORS(Cross-Origin Resource Sharing)是一個重要的安全機制,允許不同來源的資源分享。以下是 CORS 設定的最佳實踐:
1. Access-Control-Allow-Methods
此標題設定允許的 HTTP 方法。根據最小許可權原則,只允許必要的方法。
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
2. Access-Control-Allow-Headers
此標題設定允許的請求標頭。預設情況下,已經包含了一些常見的標頭。如果需要新增自定義標頭,可以這樣做:
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = list(default_headers) + [
'Custom-Request-Header'
]
3. Access-Control-Max-Age
此標題設定預檢請求的快取時間。預設情況下為 86400 秒(1 天)。但是,在生產環境中,建議設定為 60 秒,以避免版本更新問題。
CORS_PREFLIGHT_MAX_AGE = 60
在開發環境中,為了方便除錯,建議設定為 1 秒:
CORS_PREFLIGHT_MAX_AGE = 1 if DEBUG else 60
17.5 傳送 Cookie 於不同來源間
當 Bob 發現使用者經常使用匿名評論來傳送垃圾郵件時,他意識到了一個大問題。他決定用驗證的評論來取代匿名評論。從現在開始,對 /comment/
的請求必須包含一個有效的會話 ID。
然而,瀏覽器的同源政策(SOP)限制了 Cookie 的傳送。瀏覽器會忽略從不同來源的非同步請求中接收到的 Cookie,並且不會在不同來源的非同步請求中包含 Cookie。
為瞭解決這個問題,Bob 在 /comment/
的預檢請求中增加了 Access-Control-Allow-Credentials
標頭。這個標頭允許瀏覽器在跨來源請求中包含認證資料,例如 Cookie、授權標頭和 TLS 使用者端證書。
以下是 Access-Control-Allow-Credentials
標頭的範例:
Access-Control-Allow-Credentials: true
在 Django 中,可以使用 CORS_ALLOW_CREDENTIALS
引數要求 django-cors-headers
新增這個標頭到所有的 CORS 回應中:
CORS_ALLOW_CREDENTIALS = True
雖然 Access-Control-Allow-Credentials
標頭允許瀏覽器傳送 Cookie,但它並不強制瀏覽器這樣做。相反,伺服器和瀏覽器必須合作才能傳送 Cookie。在客戶端,可以使用 fetch
函式的 credentials
選項或 XmlHttpRequest
的 withCredentials
屬性來包含認證資料。
以下是使用 fetch
函式包含認證資料的範例:
fetch('/comment/', {
method: 'PUT',
headers: headers,
credentials: 'include',
body: JSON.stringify(body)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('error', error));
17.6 CORS 和 CSRF 的區別
CORS(Cross-Origin Resource Sharing)和 CSRF(Cross-Site Request Forgery)都是與網路安全相關的議題,但它們是不同的。
- CORS 是一個 W3C 推薦的標準,允許網頁從不同的來源載入資源。
- CSRF 是一種攻擊手法,涉及到網站之間的請求偽造。
儘管 CORS 和 CSRF 都與網路安全相關,但它們是不同的,並且不應該混淆。以下是幾個原因:
- CORS 標頭不能防禦 CSRF 攻擊。
- 防禦 CSRF 攻擊不能削弱同源政策(SOP)。
- CORS 是一個標準化的協定,而 CSRF 防禦並不是標準化的。
在本章中,我們將分別介紹 CORS 和 CSRF,以避免混淆。
網頁安全:跨來源資源共用(CORS)和點選劫持(Clickjacking)
CORS簡介
跨來源資源共用(CORS)是一種機制,允許網頁從不同於其自身來源的伺服器請求資源。它是為瞭解決瀏覽器同源政策(Same-Origin Policy)限制而生的。同源政策規定,網頁只能請求與其自身來源相同的資源,而CORS則允許網頁請求不同來源的資源。
CORS工作原理
當網頁請求不同來源的資源時,瀏覽器會先傳送一個預檢請求(Preflight Request)到伺服器,詢問伺服器是否允許跨來源請求。伺服器如果允許,會傳回一個包含Access-Control-Allow-Origin
頭的回應,指定允許的來源。瀏覽器收到此回應後,才會傳送實際的請求。
點選劫持(Clickjacking)
點選劫持是一種攻擊方式,攻擊者透過建立一個看似無害的網頁,實際上是將受害者的點選事件轉移到另一個網頁的元素上。這樣,攻擊者就可以控制受害者的點選事件,進行惡意操作。
防禦點選劫持
為了防禦點選劫持,網站可以設定X-Frame-Options
頭,指定是否允許其網頁被框架化(Framed)。另外,還可以設定內容安全政策(Content Security Policy, CSP)的frame-ancestors
指令,指定哪些網站可以框架化其網頁。
內容解密:
- CORS是什麼?它的工作原理是怎樣的?
- 點選劫持是什麼?它的攻擊方式是怎樣的?
- 如何防禦點選劫持?設定哪些頭和政策可以幫助防禦?
圖表翻譯:
下面是CORS工作原理的流程圖:
sequenceDiagram participant 網頁 participant 伺服器 Note over 網頁,伺服器: 網頁請求不同來源的資源 網頁->>伺服器: 預檢請求(Preflight Request) 伺服器->>網頁: 回應(包含Access-Control-Allow-Origin頭) Note over 網頁,伺服器: 網頁收到回應後,傳送實際的請求 網頁->>伺服器: 實際請求 伺服器->>網頁: 回應
這個流程圖展示了CORS工作原理的步驟。首先,網頁請求不同來源的資源,瀏覽器會先傳送一個預檢請求到伺服器。伺服器收到預檢請求後,傳回一個包含Access-Control-Allow-Origin
頭的回應。網頁收到此回應後,才會傳送實際的請求。
什麼是Clickjacking攻擊?
Clickjacking是一種網頁攻擊,攻擊者透過建立一個看似合法的網頁,實際上卻是用來捕捉使用者的點選動作。這種攻擊通常是透過將一個透明的iframe疊加在一個合法的網頁上,當使用者點選網頁時,實際上卻是在點選iframe中的內容。
Clickjacking攻擊的原理
Clickjacking攻擊的原理是透過建立一個iframe,並將其設定為透明,然後將其疊加在一個合法的網頁上。當使用者點選網頁時,實際上卻是在點選iframe中的內容。這樣,攻擊者就可以捕捉使用者的點選動作,並將其用於惡意目的。
如何防禦Clickjacking攻擊
防禦Clickjacking攻擊的一種方法是使用X-Frame-Options заголовок。這個zаголовок可以設定為DENY或SAMEORIGIN,分別表示禁止將網頁嵌入iframe中,或只允許同源的網頁嵌入iframe中。
在Django中,可以使用X_FRAME_OPTIONS
引數來設定X-Frame-Options заголовок的值。例如:
X_FRAME_OPTIONS = 'SAMEORIGIN'
這樣就可以防禦Clickjacking攻擊。
另外,還可以使用xframe_options_sameorigin
decorator來設定X-Frame-Options заголовок的值。例如:
from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import xframe_options_sameorigin
@method_decorator(xframe_options_sameorigin, name='dispatch')
class XFrameOptionsSameOriginView(View):
def get(self, request):
#...
這樣就可以設定X-Frame-Options заголовок的值為SAMEORIGIN,防禦Clickjacking攻擊。
網站安全:防禦Clickjacking攻擊
Clickjacking是一種網站安全漏洞,攻擊者可以透過 iframe 或其他 HTML 元素將惡意網站嵌入到受害者網站中,從而欺騙使用者進行非預期的操作。為了防禦Clickjacking攻擊,開發人員可以使用以下幾種方法:
1. X-Frame-Options
X-Frame-Options是一個HTTP標頭,用於指定哪些網站可以將本網站嵌入到iframe中。開發人員可以設定X-Frame-Options為DENY、SAMEORIGIN或ALLOW-FROM,以控制哪些網站可以嵌入本網站。
- DENY:禁止任何網站嵌入本網站。
- SAMEORIGIN:只允許相同-origin的網站嵌入本網站。
- ALLOW-FROM:允許指定的網站嵌入本網站。
2. Content-Security-Policy (CSP)
Content-Security-Policy (CSP)是一個HTTP標頭,用於指定哪些資源可以被載入到網頁中。開發人員可以設定CSP的frame-ancestors指令,以控制哪些網站可以嵌入本網站。
- frame-ancestors:指定哪些網站可以嵌入本網站。
3. 框架隔離
開發人員可以使用框架隔離技術,例如使用sandbox屬性,來限制iframe中的內容。
4. 監控和更新
開發人員應該定期監控網站的安全性,並及時更新軟體和框架,以確保網站的安全性。
網站安全資訊來源
為了保持網站安全,開發人員應該關注最新的安全資訊和漏洞。以下是一些推薦的資訊來源:
- Bruce Schneier:一位知名的安全專家和作家。
- Brian Krebs:一位知名的安全記者和部落格作者。
- SANS Institute:一個提供安全培訓和資訊的組織。
- OWASP:一個開源的安全組織,提供安全資訊和工具。
透過關注這些資訊來源,開發人員可以保持對最新的安全資訊和漏洞的瞭解,從而更好地保護自己的網站。
網路安全資訊來源
若要掌握網路安全的最新動態,以下幾點建議可以幫助您保持更新:
- 關注網路安全專家:您可以關注像格雷厄姆·克魯利(Graham Cluley)這樣的網路安全專家,他們在推特上分享有關網路安全的資訊和見解。
- 訂閱網路安全新聞來源:訂閱可靠的網路安全新聞來源,可以幫助您掌握最新的網路安全事件、漏洞發現、新的工具和法律變化等資訊。這些來源通常提供RSS訂閱服務。
- 參與網路安全社群:參與像Reddit的/r/netsec社群,可以讓您與其他網路安全愛好者和專家交流,分享資訊和經驗。
網路安全風險通知
除了關注最新的網路安全新聞和趨勢外,還可以訂閱風險通知服務。這些服務會在您的帳戶被洩露或出現新的漏洞時通知您。
網路安全研究和資源
網路安全研究和資源包括:
- 漏洞和漏洞利用:瞭解最新的漏洞和漏洞利用,可以幫助您更好地保護您的系統和資料。
- CVE(Common Vulnerabilities and Exposures):CVE是一個公開的漏洞和漏洞利用函式庫,可以幫助您快速查詢和了解特定的漏洞。
網站安全與防護
在網站開發中,安全性是非常重要的。一個安全的網站可以保護使用者的資料和隱私,同時也可以避免網站被攻擊和破壞。在本文中,我們將討論一些網站安全與防護的相關知識。
CORS(Cross-Origin Resource Sharing)
CORS是一種機制,允許網頁從不同的網域名稱或埠中取得資源。它可以解決瀏覽器的同源政策限制,讓網頁可以跨網域名稱或埠存取資源。
在Django中,可以使用corsheaders
函式庫來實作CORS。首先,需要安裝corsheaders
函式庫:
pip install django-cors-headers
然後,在settings.py
中新增以下程式碼:
INSTALLED_APPS = [
#...
'corsheaders',
#...
]
MIDDLEWARE = [
#...
'corsheaders.middleware.CorsMiddleware',
#...
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = ('Content-Type', 'Authorization')
CORS_ALLOW_METHODS = ('GET', 'POST', 'PUT', 'DELETE')
這樣就可以啟用CORS了。
CSRF(Cross-Site Request Forgery)
CSRF是一種攻擊方式,攻擊者可以偽造使用者的請求,讓使用者執行不想要的動作。例如,攻擊者可以建立一個表單,讓使用者提交一個請求,然後攻擊者就可以獲得使用者的身份驗證資訊。
在Django中,可以使用csrf
函式庫來防禦CSRF攻擊。首先,需要安裝csrf
函式庫:
pip install django-csrf
然後,在settings.py
中新增以下程式碼:
INSTALLED_APPS = [
#...
'csrf',
#...
]
MIDDLEWARE = [
#...
'csrf.middleware.CsrfViewMiddleware',
#...
]
這樣就可以啟用CSRF防禦了。
SSL/TLS
SSL/TLS是一種加密協定,用於保護網站和使用者之間的通訊。它可以確保使用者的資料和隱私不會被擷取或竊聽。
在Django中,可以使用ssl
函式庫來實作SSL/TLS。首先,需要安裝ssl
函式庫:
pip install pyopenssl
然後,在settings.py
中新增以下程式碼:
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
這樣就可以啟用SSL/TLS了。
網頁安全:CORS、CSP 和加密技術
從系統安全架構的視角來看,保障網頁應用程式安全需要多層級的防護機制。本文深入探討了 CORS、CSP 和加密技術如何協同構建網頁安全防線。分析發現,CORS 雖然能有效管控跨域資源存取,但仍需搭配其他機制才能抵禦 CSRF 等攻擊;CSP 則透過限制資源載入來源,進一步降低 XSS 等注入攻擊的風險。然而,僅依靠前端防護並不足夠,HTTPS 等加密技術在保護資料傳輸安全方面扮演著至關重要的角色。目前,瀏覽器對安全策略的支援程度不一,開發者需要仔細考量相容性問題。玄貓認為,未來網頁安全將更注重整合性方案,結合瀏覽器內建功能、伺服器端設定和安全意識培訓,才能有效應對日益複雜的網路攻擊。對於開發者而言,持續關注安全標準演進並將其融入開發流程,才能構建真正安全的網頁應用程式。