使用 Reporting API 監控網頁應用程式

使用 Reporting API 即可監控安全性違規事項、已淘汰的 API 呼叫等。

Maud Nalpas
Maud Nalpas

部分錯誤只會發生在實際工作環境中。你不會在本機或裝置期間看到這些設定 因為實際的使用者實際網路實際裝置 改變遊戲。Reporting API 有助於找出部分錯誤,例如: 例如安全性違規,或已淘汰且即將遭到淘汰的 API 並傳輸到 。

它可讓您透過 HTTP 標頭宣告要監控的內容,而且 操作是由瀏覽器運作。

設定 Reporting API 可讓您安心無憂。 您就能瞭解並修正這些類型的錯誤

本文章說明這個 API 的功能和使用方式。那就繼續下一步吧!

示範和代碼

Reporting API 應用實例,開始 Chrome 96 以上版本 (Chrome Beta 版或 Canary 版 (截至 2021 年 10 月)

總覽

圖表摘要說明開發人員如何執行報表,從產生報表到存取報表
報表的產生及傳送方式。

假設您的網站 (site.example) 設有內容安全性政策和文件政策。不清楚這些步驟嗎?沒關係,你依然會 都能瞭解這個範例

您決定監控網站,知道何時違反這些政策,也是因為 建議您留意程式碼集可能使用或即將淘汰或即將淘汰的 API。

方法是設定 Reporting-Endpoints 標頭,並對應這些端點 為政策中的 report-to 指令命名。

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the `default` endpoint

您只是發生一些意外狀況,而某些部分廣告違反這些政策 使用者。

違規示例

index.html

<script src="script.js"></script>
<!-- CSP VIOLATION: Try to load a script that's forbidden as per the Content-Security-Policy -->
<script src="https://example.com/script.js"></script>

script.js,由 index.html 載入

// DOCUMENT-POLICY VIOLATION: Attempt to use document.write despite the document policy
try {
  document.write('<h1>hi</h1>');
} catch (e) {
  console.log(e);
}
// DEPRECATION: Call a deprecated API
const webkitStorageInfo = window.webkitStorageInfo;

瀏覽器會產生 CSP 違規報告、文件政策違規報告和淘汰項目 回報這類問題。

然後等候一小段時間 (最多 1 分鐘),瀏覽器就會將報告傳送到 先前針對這個違規類型設定的端點報告 而非您的網站本身。

端點會收到這些報告。

您現在可以存取這些端點上的報表,並監控發生錯誤的原因。 您可以開始排解使用者遇到的問題。

範例報表

{
  "age": 2,
  "body": {
    "blockedURL": "https://site2.example/script.js",
    "disposition": "enforce",
    "documentURL": "https://site.example",
    "effectiveDirective": "script-src-elem",
    "originalPolicy": "script-src 'self'; object-src 'none'; report-to main-endpoint;",
    "referrer": "https://site.example",
    "sample": "",
    "statusCode": 200
  },
  "type": "csp-violation",
  "url": "https://site.example",
  "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
}

用途和報表類型

您可以設定 Reporting API 來監控多種有趣的警告或問題 幾個時段

報告類型 導致產生報表的情況範例
CSP 違規 (僅限第 3 級) 您在其中一個網頁設定了 Content-Security-Policy (CSP),但網頁正在嘗試載入 CSP 不允許的指令碼。
違反 COOP 您在頁面上設定了 Cross-Origin-Opener-Policy,但跨來源視窗嘗試直接與文件互動。
違反 COEP 您已在網頁上設定 Cross-Origin-Embedder-Policy,但文件中的跨來源 iframe 並未選擇以跨來源文件載入。
違反文件政策 網頁含有禁止使用 document.write 的文件政策,但有指令碼會嘗試呼叫 document.write
違反權限政策 網頁設有禁止使用麥克風的權限政策,以及要求音訊輸入的指令碼。
淘汰警告 網頁使用的 API 已淘汰或即將淘汰;直接呼叫或經由頂層第三方指令碼呼叫。
幹預 網頁嘗試基於安全性、效能或使用者體驗考量,瀏覽器決定不遵守的作業內容。Chrome 以 Chrome 為例:網頁透過緩慢網路使用 document.write,或是在使用者尚未互動的跨來源頁框呼叫 navigator.vibrate
當機 網站開啟時,瀏覽器當機。

報表

報表長什麼樣子?

瀏覽器會將報表傳送到您設定的端點。它會傳送如下的要求:

POST
Content-Type: application/reports+json

這些請求的酬載是一份報表清單。

報表清單範例

[
  {
    "age": 420,
    "body": {
      "columnNumber": 12,
      "disposition": "enforce",
      "lineNumber": 11,
      "message": "Document policy violation: document-write is not allowed in this document.",
      "policyId": "document-write",
      "sourceFile": "https://site.example/script.js"
    },
    "type": "document-policy-violation",
    "url": "https://site.example/",
    "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
  },
  {
    "age": 510,
    "body": {
      "blockedURL": "https://site.example/img.jpg",
      "destination": "image",
      "disposition": "enforce",
      "type": "corp"
    },
    "type": "coep",
    "url": "https://dummy.example/",
    "user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
  }
]

每種報表都提供下列資料:

欄位 說明
age 報表時間戳記和目前時間之間的毫秒數。
body 實際的報表資料,序列化為 JSON 字串。報表「body」中包含的欄位取決於報表的type⚠️ 不同類型的報告有不同的身體結構。 如要查看每種報表類型的確切內容,請查看客層報表端點 ,並按照操作說明產生範例報表。
type 報表類型,例如 csp-violationcoep
url 產生報表時使用的文件或工作人員地址。使用者名稱、密碼和片段等機密資料會從這個網址中移除
user_agent 產生報表的來源要求的 User-Agent 標頭。

認證報表

與產生報表的網頁具有相同來源的報表端點會收到憑證 (Cookie)。

憑證可提供與報表相關的實用背景資訊。的 例如特定使用者的帳戶是否持續觸發錯誤,或是特定序列觸發的錯誤 在其他網頁採取的操作觸發了這個頁面上的報表。

瀏覽器傳送報告的時間和方式為何?

網站會以非架構的形式提供報表:瀏覽器會控制 並傳送至設定好的端點而且沒有任何方法 瀏覽器傳送報告模型的擷取作業、佇列,並在 合適的時間。

換言之,使用 Reporting API 時幾乎沒有什麼影響。

報表會延遲傳送一段時間 (最多一分鐘),以提高批次傳送報表的機率。 這樣可以節省頻寬,在使用者的網路連線範圍內特別重要 行動的一大關鍵如果瀏覽器忙於處理優先順序較高的作業,也可能會延遲傳送 或使用者的網路速度緩慢和/或壅塞。

第三方和第一方問題

如果系統在網頁上出現違規或淘汰事件而產生的報表,就會傳送 連上您所設定的端點這包括第三方指令碼提出的違規行為。 在您的網頁上

在網頁內嵌跨來源 iframe 中的違規或淘汰項目 不會回報給端點 (至少非預設)。iframe 可以 也就是第一方的報表服務但沒錯 頁框傳送同一個網站另請注意,大部分只有在違反網頁政策的情況下才會產生報表。 而且網頁的政策和 iframe 的政策不同

淘汰項目範例

如果網頁上設有 Reporting-Endpoint 標頭:由在網頁上執行的第三方指令碼呼叫的已淘汰 API,則會回報至您的端點。嵌入網頁中的 iframe 呼叫的已淘汰 API 將不會回報至您的端點。只有在 iframe 伺服器已設定 Reporting- Endpoints 的情況下,系統才會產生淘汰報表,且系統會將這份報表傳送至 iframe 伺服器設定的任何端點。
如果網頁上設有 Reporting-Endpoint 標頭:由在網頁上執行的第三方指令碼呼叫的已淘汰 API,則會回報至您的端點。嵌入網頁中的 iframe 呼叫的已淘汰 API 將不會回報至您的端點。只有在 iframe 伺服器已設定 Reporting- Endpoints 的情況下,系統才會產生淘汰報表,且系統會將這份報表傳送至 iframe 伺服器設定的任何端點。

瀏覽器支援

下表統整了 Reporting API 第 1 版的瀏覽器支援, Reporting-Endpoints 標頭。Reporting API v0 的瀏覽器支援 (Report-To 標頭) 是 相同,但只有一種報表類型:新的 Reporting API 不支援網路錯誤記錄功能。 詳情請參閱遷移指南

報告類型 Chrome Chrome iOS 版 Safari Firefox Edge
違反 CSP (僅限第 3 級)* ✔ 是 ✔ 是 ✔ 是 ✘ 否 ✔ 是
網路錯誤記錄 ✘ 否 ✘ 否 ✘ 否 ✘ 否 ✘ 否
違反 COOP/COEP ✔ 是 ✘ 否 ✔ 是 ✘ 否 ✔ 是
所有其他類型:違反文件政策、淘汰、幹預、當機 ✔ 是 ✘ 否 ✘ 否 ✘ 否 ✔ 是

此表格摘要列出對 report-to 與新 Reporting-Endpoints 標頭的支援。如要遷移至 Reporting-Endpoints,請參閱 CSP 報告遷移提示

使用 Reporting API

決定報表寄送目的地

方法有以下兩種:

  • 將報表傳送到現有的報表收集器服務。
  • 將報表傳送給您自行建立及營運的報表收集器。

方法 1:使用現有的報表收集器服務

以下是幾個報表收集器服務的範例:

如果您知道其他解決方案,請開啟問題說明,我們會更新這篇文章。

除了定價之外,選擇報表收集工具時,也請考量下列幾點:🧐?

  • 這個收集器是否支援所有報表類型?舉例來說,並非所有報表端點解決方案 支援 COOP/COEP 報告
  • 您是否願意與第三方報表收集器分享應用程式的任何網址? 即使瀏覽器移除了這些網址中的機密資訊,機密資訊仍可能以這種方式外洩。如果這麼做的風險太高 並自行運作報表端點

方法 2:自行建立及經營報表收集器

建立自己的伺服器可以接收報告,並非易事。首先,您可以 輕便的樣板這個平台是以 Express 建立,可接收及顯示報表。

  1. 前往樣板報表收集器

  2. 按一下「Remix to Edit」即可編輯專案。

  3. 您現在有本機副本了!您可以依個人需求自訂這項功能。

如果您沒有使用樣板,且正從頭開始建構自己的伺服器:

  • 檢查 Content-Typeapplication/reports+jsonPOST 要求,以便識別報表 伺服器傳送至您的端點的要求清單
  • 如果您的端點位於與網站不同的來源,請確保該端點支援 CORS 預檢要求
,瞭解如何調查及移除這項存取權。

選項 3:合併選項 1 和 2

建議您讓特定供應商負責處理某些類型的報表, 其他 Google 解決方案

在這種情況下,請按照以下方式設定多個端點:

Reporting-Endpoints: endpoint-1="https://reports-collector.example", endpoint-2="https://my-custom-endpoint.example"

設定 Reporting-Endpoints 標頭

設定 Reporting-Endpoints 回應標頭。值必須是一或一系列以半形逗號分隔 鍵/值組合:

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"

如果您要從舊版 Reporting API 遷移至新版 Reporting API,建議您: 將 Reporting-EndpointsReport-To 設為。詳情請參閱遷移指南。具體來說,假如您要使用報表 僅透過 report-uri 指令執行 Content-Security-Policy 項違規事項,請參閱 CSP 報告遷移步驟

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
Report-To: ...

鍵 (端點名稱)

每個鍵都可以是您選擇的名稱,例如 main-endpointendpoint-1。 您可以決定為不同的報表設定不同命名的端點 類型),例如 my-coop-endpointmy-csp-endpoint。這樣一來, 可根據其類型將報表轉送至不同的端點。

您需要接收幹預淘汰和/或當機通知 則應設定名為 default 的端點。

如果 Reporting-Endpoints 標頭未定義任何 default 端點,系統就「不會」傳送這種類型的報表 (雖然系統會產生這些報表)。

值 (網址)

每個值都是您選擇的網址,報告會傳送至這裡。網址 視您在步驟 1 的決定而定。

端點網址:

範例

Reporting-Endpoints: my-coop-endpoint="https://reports.example/coop", my-csp-endpoint="https://reports.example/csp", default="https://reports.example/default"

這樣就能在適當的政策中使用各個已命名的端點 單一端點

要在哪裡設定標頭?

新的 Reporting API ( 貼文:報告的範圍僅限於文件。也就是說 來源、不同文件,例如 site.example/page1site.example/page2,可以將報表傳送至其他端點。

如要接收報表,瞭解 Google 在 網站,請將所有回應的標題設為中介軟體。

以下是 Express 的範例:

const REPORTING_ENDPOINT_BASE = 'https://report.example';
const REPORTING_ENDPOINT_MAIN = `${REPORTING_ENDPOINT_BASE}/main`;
const REPORTING_ENDPOINT_DEFAULT = `${REPORTING_ENDPOINT_BASE}/default`;

app.use(function (request, response, next) {
  // Set up the Reporting API
  response.set(
    'Reporting-Endpoints',
    `main-endpoint="${REPORTING_ENDPOINT_MAIN}", default="${REPORTING_ENDPOINT_DEFAULT}"`,
  );
  next();
});
敬上

編輯政策

設定好 Reporting-Endpoints 標頭後,請新增 report-to 指定要收到違規內容的每個政策標頭 報表。report-to 的值應為您在過去的其中一個已命名端點 專案。

您可以將多個端點用於多項政策,或使用不同的端點 跨政策端點

針對每項政策, report-to 的值應為你設定的其中一個已命名端點。

即使淘汰幹預當機report-to 也不需要。 報表。這些報告不受任何政策約束。產生長度的 default 端點已設定完成,並會傳送至這個 default 端點。

範例

# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0;report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the default endpoint
敬上

範例程式碼

為了瞭解上述所有情況,以下為使用 Express 的節點伺服器範例 並整合本文提到的所有要點這項工具會說明如何 設定多種不同類型的報表,並顯示結果。

對報表設定進行偵錯

刻意產生報表

設定 Reporting API 時,您可能需要刻意違反 政策,確認報表是否正常產生及傳送。 查看違反政策的程式碼範例,以及會達到 如果需要所有類型的報表,請查看示範

節省時間

系統可能會延遲寄出報表,大約一分鐘,最後是時間 。∫ 幸好,在 Chrome 中偵錯時,你可以使用旗標 --short-reporting-delay,即可在報表產生時立即收到報表。

在終端機中執行下列指令即可開啟這個標記:

YOUR_PATH/TO/EXECUTABLE/Chrome --short-reporting-delay
敬上

使用開發人員工具

在 Chrome 中,使用開發人員工具查看已傳送或即將傳送的報告。

自 2021 年 10 月起,這項功能仍處於實驗階段。如要使用,請按照下列步驟操作:

  1. 使用 Chrome 96 以上版本 (確認是否在瀏覽器中輸入 chrome://version)
  2. 在 Chrome 的網址列中輸入或貼上 chrome://flags/#enable-experimental-web-platform-features
  3. 按一下「已啟用」
  4. 重新啟動瀏覽器。
  5. 開啟 Chrome 開發人員工具。
  6. 在 Chrome 開發人員工具中開啟「設定」。在「實驗」下方,按一下「啟用 Reporting API 面板」: 「Applications」面板
  7. 重新載入開發人員工具。
  8. 重新載入網頁。如果「開發人員工具」頁面產生的報表, Chrome 開發人員工具「Application」(應用程式) 面板的「Reporting API」(報表 API) 下方。
,瞭解如何調查及移除這項存取權。
開發人員工具清單的螢幕截圖
Chrome 開發人員工具會顯示頁面產生的報表及其狀態。

報表狀態

「狀態」欄會指出報表是否已成功傳送。

狀態 說明
Success 瀏覽器已送出報告,且端點以成功代碼 (200 或其他成功回應代碼 2xx) 回覆。
Pending 瀏覽器正在嘗試傳送報告。
Queued 報表已產生,瀏覽器目前無法傳送報表。在下列任一情況下,報表會顯示為 Queued
  • 此報表才剛推出,瀏覽器在嘗試傳送前,需先確認是否有更多報表送達。
  • 本報告並非新報告。瀏覽器已嘗試傳送這份報表,但作業失敗,正在等候系統重試。
MarkedForRemoval 重試一段時間後 (Queued),瀏覽器已停止嘗試傳送報表,很快就會從報表清單中移除該報表。

報表在一陣子後就會移除,不論是否成功送出。

疑難排解

報表是否無法依預期的方式產生,或未如預期傳送至您的端點? 以下提供一些疑難排解提示。

無法產生報表

開發人員工具中顯示的報表已正確產生。 如果您預期的報表「不會」出現在這份清單中:

  • 請查看政策中的「report-to」。如果設定錯誤, 不會產生報表前往「編輯政策」: 修正此問題。另一個排解問題的方法,是查看 Chrome 的開發人員工具控制台,如果發生這個問題, 控制台就會顯示您預期的違規事項,表示政策可能 並正確設定
  • 請注意,只有使用開發人員工具產生的報表才會開啟 並顯示在這份清單中舉例來說,如果你的網站 site1.example 嵌入了 iframe site2.example 違反政策並產生報告。除非您開啟 iframe 以獨立視窗開啟,然後為該視窗開啟開發人員工具。

產生報表,但不傳送或接收

如果開發人員工具中顯示報表,但端點未收到報告,該怎麼辦?

  • 請務必短暫延遲。看不到報表的原因可能就是 尚未傳送!
  • 檢查 Reporting-Endpoints 標頭設定。如果發生問題, 正確產生的數字不會傳送在開發人員工具中,報表的狀態將維持不變 Queued (可能會跳轉至 Pending,如果嘗試傳送Queued 。可能導致這個問題的常見錯誤:

  • 已使用這個端點,但尚未設定。範例:

含有錯誤的程式碼
 Document-Policy: document-write=?0;report-to=endpoint-1;
 Reporting-Endpoints: default="https://reports.example/default"

「文件政策違規」報告應傳送至「endpoint-1」,但您未在 Reporting-Endpoints

  • 缺少 default 端點。部分報表類型 (例如淘汰和介入措施) 報表,只會傳送到名為 default 的端點。詳情請參閱設定報表端點標頭

  • 找出政策標頭語法是否有問題,例如缺少引號。瞭解詳情

  • 檢查您的端點是否能處理傳入要求。

    • 請確認您的端點支援 CORS 預檢要求。如果沒有,就無法接收報表。

    • 測試端點的行為。方法是 報表則能模擬瀏覽器,方法是將類似 瀏覽器傳送的檔案執行以下指令:

    curl --header "Content-Type: application/reports+json" \
      --request POST \
      --data '[{"age":420,"body":{"columnNumber":12,"disposition":"enforce","lineNumber":11,"message":"Document policy violation: document-write is not allowed in this document.","policyId":"document-write","sourceFile":"https://dummy.example/script.js"},"type":"document-policy-violation","url":"https://dummy.example/","user_agent":"xxx"},{"age":510,"body":{"blockedURL":"https://dummy.example/img.jpg","destination":"image","disposition":"enforce","type":"corp"},"type":"coep","url":"https://dummy.example/","user_agent":"xxx"}]' \
      YOUR_ENDPOINT
    

    您的端點應以成功代碼 (200 或其他成功回應代碼 2xx) 回應。如果沒有 設定有問題。

報表專用

-Report-Only 政策標頭和 Reporting-Endpoints 會搭配運作。

端點已在 Reporting-Endpoints 設定,且在以下欄位的 report-to 欄位中指定: Content-Security-PolicyCross-Origin-Embedder-PolicyCross-Origin-Opener-Policy,違反這些政策時將收到報告。

您也可以在 Reporting-Endpoints 中設定端點, report-to 個欄位,共 Content-Security-Policy-Report-OnlyCross-Origin-Embedder-Policy-Report-OnlyCross-Origin-Opener-Policy-Report-Only。 違反這些政策時,使用者也會收到檢舉。

雖然這兩種方式都會傳送報表,但 -Report-Only 標頭不會強制規定 您不會因此喪失或實際封鎖 回報「可能」毀損或遭到封鎖的情況。

ReportingObserver

ReportingObserver JavaScript API 可協助您 觀察用戶端警告

ReportingObserverReporting-Endpoints 標頭會產生報表 看起來一樣,但用途也稍有不同。

如果符合下列情況,請使用 ReportingObserver

  • 您只想監控淘汰情況和/或瀏覽器介入措施。 ReportingObserver 會顯示用戶端警告,例如淘汰 與 Reporting-Endpoints 不同之處在於 擷取任何其他類型的報告,例如 CSP 或 COOP/COEP 違規事件。
  • 請務必即時回應這些違規行為。ReportingObserver 型號 可附加回呼至違規事件。
  • 您想在報表中附加額外資訊,以便偵錯, 呼叫回呼來源。

另一個差異在於 ReportingObserver 僅設定用戶端: 即使您無法控制伺服器端標頭,也無法 設定「Reporting-Endpoints」。

延伸閱讀

主頁橫幅由 Nine Koepfer / @enka80 提供 Unsplash 已編輯。由 Ian Clelland、Eiji Kitamura 和 Milica Mihajlija 的作者為這篇文章提供評論和建議。