隨著網路應用程式日漸普及,網頁安全也成為開發者不可忽視的重要議題。本文將探討常見的網頁安全威脅,包括跨來源資源共用(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 中新增 corsheadersINSTALLED_APPS 中:

INSTALLED_APPS = [
    #...
    'corsheaders',
]

並且在 MIDDLEWARE 中新增 CorsMiddleware

MIDDLEWARE = [
    #...
    'corsheaders.middleware.CorsMiddleware',
    #...
]

Access-Control-Allow-Origin 的設定

要設定 Access-Control-Allow-Origin,需要在 settings.py 中定義 CORS_ALLOWED_ORIGINSCORS_ALLOW_ALL_ORIGINS

例如,設定 CORS_ALLOWED_ORIGINS 為特定的網域名稱:

CORS_ALLOWED_ORIGINS = [
    'http://example.com',
    'http://example.net',
]

或設定 CORS_ALLOW_ALL_ORIGINSTrue,允許所有網域名稱存取:

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 的設定可以透過以下幾種方式實作:

  1. 設定 Access-Control-Allow-Origin 標頭:伺服器可以在回應中新增 Access-Control-Allow-Origin 標頭,指定允許的網域名稱。
  2. 設定 CORS_ORIGIN_ALLOW_ALL 引數:如果設定 CORS_ORIGIN_ALLOW_ALL 引數為 True,則允許所有網域名稱傳送請求。
  3. 設定 CORS_ORIGIN_WHITELIST 引數:可以設定 CORS_ORIGIN_WHITELIST 引數,指定允許的網域名稱列表。
  4. 設定 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

當 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 選項或 XmlHttpRequestwithCredentials 屬性來包含認證資料。

以下是使用 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:一個開源的安全組織,提供安全資訊和工具。

透過關注這些資訊來源,開發人員可以保持對最新的安全資訊和漏洞的瞭解,從而更好地保護自己的網站。

網路安全資訊來源

若要掌握網路安全的最新動態,以下幾點建議可以幫助您保持更新:

  1. 關注網路安全專家:您可以關注像格雷厄姆·克魯利(Graham Cluley)這樣的網路安全專家,他們在推特上分享有關網路安全的資訊和見解。
  2. 訂閱網路安全新聞來源:訂閱可靠的網路安全新聞來源,可以幫助您掌握最新的網路安全事件、漏洞發現、新的工具和法律變化等資訊。這些來源通常提供RSS訂閱服務。
  3. 參與網路安全社群:參與像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 等加密技術在保護資料傳輸安全方面扮演著至關重要的角色。目前,瀏覽器對安全策略的支援程度不一,開發者需要仔細考量相容性問題。玄貓認為,未來網頁安全將更注重整合性方案,結合瀏覽器內建功能、伺服器端設定和安全意識培訓,才能有效應對日益複雜的網路攻擊。對於開發者而言,持續關注安全標準演進並將其融入開發流程,才能構建真正安全的網頁應用程式。