Chính sách bảo mật nội dung

Joe Medley
Joe Medley

Mô hình bảo mật của trang web này bắt nguồn từ chính sách cùng nguồn gốc. Mã từ https://mybank.com chỉ có quyền truy cập vàohttps://mybank.comhttps://evil.example.com chắc chắn không bao giờ được phép truy cập. Mỗi nguồn gốc đều được tách biệt với phần còn lại của web, nhằm cung cấp cho nhà phát triển trong hộp cát để xây dựng và chơi. Trên lý thuyết, đây là một con đường hoàn hảo. Trong kẻ tấn công đã tìm ra những cách thức khéo léo để phá vỡ hệ thống.

Tập lệnh trên nhiều trang web (XSS) các cuộc tấn công khác. Ví dụ: bỏ qua cùng một chính sách nguồn gốc bằng cách lừa một trang web phân phối mã độc hại cùng với nội dung mong muốn. Đây là một vì các trình duyệt tin tưởng tất cả mã hiển thị trên một trang là một phần chính đáng của nguồn gốc bảo mật của trang đó. Chiến lược phát hành đĩa đơn Bản tóm tắt về XSS là một mặt cắt cũ nhưng mang tính đại diện cho những phương pháp mà kẻ tấn công có thể sử dụng xâm phạm sự tin tưởng này bằng cách chèn mã độc hại. Nếu kẻ tấn công thành công chèn bất kỳ mã nào, nhưng mọi việc gần như không kết thúc: dữ liệu phiên của người dùng được bị xâm phạm và thông tin cần được giữ bí mật được trích xuất cho The Bad Các bạn ơi. Hiển nhiên là chúng tôi sẽ ngăn chặn điều đó nếu có thể.

Nội dung tổng quan này nêu bật một biện pháp phòng ngừa có thể làm giảm đáng kể rủi ro và tác động của các cuộc tấn công XSS trong các trình duyệt hiện đại: Chính sách bảo mật nội dung (CSP).

TL;DR

  • Sử dụng danh sách cho phép để cho khách hàng biết những nội dung được phép và không được phép.
  • Tìm hiểu xem có những lệnh nào.
  • Tìm hiểu các từ khoá họ sử dụng.
  • Mã cùng dòng và eval() được coi là gây hại.
  • Hãy báo cáo lỗi vi phạm chính sách cho máy chủ của bạn trước khi thực thi.

Danh sách nguồn đã cho phép

Vấn đề bị các cuộc tấn công XSS khai thác là trình duyệt không thể phân biệt giữa tập lệnh là một phần của ứng dụng và tập lệnh đã được do một bên thứ ba chèn vào một cách ác ý. Ví dụ: nút Google +1 ở cuối trang này tải và thực thi mã từ https://apis.google.com/js/plusone.js theo ngữ cảnh nguồn gốc của trang này. T4 tin tưởng mã đó, nhưng chúng ta không thể kỳ vọng trình duyệt tự tìm ra mã đó từ apis.google.com thì tuyệt vời, trong khi mã từ apis.evil.example.com có thể không. Trình duyệt thoải mái tải xuống và thực thi bất kỳ mã nào trên một trang các yêu cầu, bất kể nguồn.

Thay vì tin tưởng một cách mù quáng mọi thứ mà máy chủ phân phối, CSP sẽ xác định Tiêu đề HTTP Content-Security-Policy, cho phép bạn tạo danh sách cho phép cho nguồn nội dung đáng tin cậy và hướng dẫn trình duyệt chỉ thực thi hoặc hiển thị từ các nguồn đó. Ngay cả khi kẻ tấn công có thể tìm thấy lỗ hổng chèn tập lệnh, tập lệnh sẽ không khớp với danh sách cho phép và do đó sẽ không được thực thi.

Vì chúng tôi tin tưởng apis.google.com cung cấp mã hợp lệ và chúng tôi tin tưởng chính mình để làm tương tự, hãy xác định một chính sách chỉ cho phép tập lệnh thực thi khi tập lệnh đó bắt nguồn từ một trong hai nguồn đó:

Content-Security-Policy: script-src 'self' https://apis.google.com

Thật đơn giản, đúng không? Như bạn có thể đoán, script-src là một lệnh kiểm soát một nhóm đặc quyền liên quan đến tập lệnh cho một trang cụ thể. Chúng tôi đã chỉ định 'self' là một nguồn tập lệnh hợp lệ và https://apis.google.com là khác. Trình duyệt tải xuống và thực thi JavaScript hợp lệ từ apis.google.com qua HTTPS, cũng như từ nguồn gốc của trang hiện tại.

Lỗi bảng điều khiển: Từ chối tải tập lệnh "http://evil.example.com/evil.js" vì đoạn mã này vi phạm lệnh sau đây trong Chính sách bảo mật nội dung: script-src "self" https://apis.google.com

Khi chính sách này được xác định, trình duyệt chỉ gửi lỗi thay vì đang tải tập lệnh từ bất kỳ nguồn nào khác. Khi một kẻ tấn công thông minh tìm được chèn mã vào trang web của bạn, chúng sẽ chạy đầy đủ trong một thông báo lỗi thay vì so với thành công họ mong đợi.

Chính sách áp dụng cho nhiều loại tài nguyên

Mặc dù tài nguyên tập lệnh là những rủi ro bảo mật rõ ràng nhất, nhưng CSP cung cấp một tập hợp chỉ thị chính sách cho phép kiểm soát khá chi tiết các tài nguyên mà một trang được phép tải. Bạn đã xem script-src, vì vậy, khái niệm này phải rõ ràng.

Hãy cùng tìm hiểu nhanh phần còn lại của các lệnh tài nguyên. Danh sách bên dưới biểu thị trạng thái của lệnh kể từ cấp 2. Thông số kỹ thuật cấp 3 đã được xuất bản, nhưng phần lớn chưa được triển khai trong trình duyệt.

  • base-uri hạn chế các URL có thể xuất hiện trong phần tử <base> của trang.
  • child-src liệt kê URL của worker và nội dung khung được nhúng. Cho ví dụ: child-src https://youtube.com sẽ bật nhúng video từ YouTube chứ không phải từ các nguồn khác.
  • connect-src giới hạn các nguồn gốc mà bạn có thể kết nối (thông qua XHR, WebSockets và EventSource).
  • font-src chỉ định những nguồn gốc có thể phân phát phông chữ trên web. Web của Google phông chữ có thể được bật qua font-src https://themes.googleusercontent.com.
  • form-action liệt kê các điểm cuối hợp lệ để gửi bằng các thẻ <form>.
  • frame-ancestors chỉ định các nguồn có thể nhúng trang hiện tại. Lệnh này áp dụng cho các thẻ <frame>, <iframe>, <embed><applet>. Lệnh này không được dùng trong các thẻ <meta> và chỉ áp dụng cho các mục không phải HTML của chúng tôi.
  • frame-src đã ngừng hoạt động trong cấp độ 2, nhưng sẽ được khôi phục trong cấp độ 3. Nếu không trình bày thì lớp này vẫn quay về child-src như trước đây.
  • img-src xác định các nguồn gốc có thể tải hình ảnh.
  • media-src hạn chế các nguồn gốc được phép phân phối video và âm thanh.
  • object-src cho phép kiểm soát Flash và các trình bổ trợ khác.
  • plugin-types giới hạn các loại trình bổ trợ mà một trang có thể gọi.
  • report-uri chỉ định một URL mà trình duyệt sẽ gửi báo cáo khi một chính sách bảo mật nội dung là vi phạm. Không được dùng lệnh này trong <meta> các thẻ.
  • style-src là phiên bản tương đương của script-src cho biểu định kiểu.
  • upgrade-insecure-requests hướng dẫn các tác nhân người dùng ghi lại giao thức URL, thay đổi HTTP thành HTTPS. Lệnh này dành cho các trang web có số lượng lớn URL cũ cần được viết lại.
  • worker-src là một lệnh CSP cấp 3 có tác dụng hạn chế các URL mà có thể được tải dưới dạng trình thực thi, trình thực thi dùng chung hoặc trình chạy dịch vụ. Tính đến tháng 7 năm 2017, có có giới hạn số lượng triển khai.

Theo mặc định, các lệnh sẽ mở rộng. Nếu bạn không đặt chính sách cụ thể cho giả sử là font-src, thì lệnh đó sẽ hoạt động theo mặc định như sau: mặc dù bạn đã chỉ định * làm nguồn hợp lệ (ví dụ: bạn có thể tải phông chữ từ mọi nơi, mà không bị hạn chế).

Bạn có thể ghi đè hành vi mặc định này bằng cách chỉ định default-src . Lệnh này xác định các chế độ mặc định cho hầu hết mà bạn không chỉ định. Nói chung, chính sách này áp dụng cho mọi chỉ thị kết thúc bằng -src. Nếu default-src được đặt thành https://example.com và bạn không thành công để chỉ định một lệnh font-src, sau đó bạn có thể tải phông chữ từ https://example.com và không nơi nào khác. Chúng ta chỉ xác định script-src trong các ví dụ trước đó, có nghĩa là hình ảnh, phông chữ, v.v. có thể được tải từ nguồn gốc bất kỳ.

Các lệnh sau đây không dùng default-src làm phương án dự phòng. Hãy nhớ rằng không đặt chúng cũng giống như cho phép bất kỳ thứ gì.

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

Bạn có thể sử dụng số lượng lệnh trong số này tuỳ ý ứng dụng cụ thể, chỉ cần liệt kê từng thông báo trong tiêu đề HTTP, bằng dấu chấm phẩy. Đảm bảo rằng bạn liệt kê tất cả tài nguyên cần thiết thuộc một loại cụ thể trong một lệnh duy nhất. Nếu bạn đã viết điều gì đó tương tự như script-src https://host1.com; script-src https://host2.com lệnh thứ hai sẽ bị bỏ qua. Ví dụ: chỉ định chính xác cả hai nguồn gốc là hợp lệ:

script-src https://host1.com https://host2.com

Ví dụ: nếu bạn có một ứng dụng tải tất cả tài nguyên của nó từ một mạng phân phối nội dung (giả sử https://cdn.example.net) và biết rằng bạn không cần bất kỳ trình bổ trợ hoặc nội dung có khung nào, thì chính sách của bạn có thể trông giống như sau:

Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'

Chi tiết triển khai

Bạn sẽ thấy tiêu đề X-WebKit-CSPX-Content-Security-Policy trong nhiều hình thức trên web. Từ giờ trở đi, bạn nên bỏ qua những tiền tố này . Các trình duyệt hiện đại (ngoại trừ IE) hỗ trợ mã không có tiền tố Tiêu đề Content-Security-Policy. Đó là tiêu đề mà bạn nên sử dụng.

Bất kể tiêu đề bạn sử dụng là gì, chính sách đều được xác định trên cơ sở từng trang: bạn sẽ cần gửi tiêu đề HTTP cùng với mọi phản hồi mà mình muốn đảm bảo được bảo vệ. Điều này mang lại tính linh hoạt cao, vì bạn có thể tinh chỉnh chính sách cho các trang cụ thể dựa trên nhu cầu cụ thể của các trang đó. Có thể một nhóm các trang trong trang web của bạn có nút +1, trong khi các trang khác thì không: bạn có thể cho phép mã nút chỉ được tải khi cần.

Danh sách nguồn trong mỗi lệnh rất linh hoạt. Bạn có thể chỉ định nguồn theo lược đồ (data:, https:) hoặc có đặc điểm khác nhau từ chỉ tên máy chủ (example.com, khớp với mọi nguồn gốc trên máy chủ đó: mọi lược đồ, cổng bất kỳ) để URI đủ điều kiện (https://example.com:443, chỉ khớp với HTTPS example.com và chỉ cổng 443). Chấp nhận ký tự đại diện, nhưng chỉ dưới dạng lược đồ, một cổng hoặc ở vị trí ngoài cùng bên trái của tên máy chủ: *://*.example.com:* sẽ khớp với tất cả các miền con của example.com (nhưng không phải example.com), sử dụng mọi lược đồ, trên bất kỳ cổng nào.

Danh sách nguồn cũng chấp nhận 4 từ khoá:

  • 'none', như bạn dự kiến, không khớp với giá trị nào.
  • 'self' khớp với nguồn gốc hiện tại, nhưng không khớp với miền con của nguồn này.
  • 'unsafe-inline' cho phép CSS và JavaScript cùng dòng. (Chúng tôi sẽ trình bày về vấn đề này trong chi tiết hơn.)
  • 'unsafe-eval' cho phép các cơ chế chuyển văn bản sang JavaScript như eval. (Chúng tôi sẽ lấy tính năng này.)

Những từ khoá này cần có dấu ngoặc đơn. Ví dụ: script-src 'self' (có dấu ngoặc kép) cho phép thực thi JavaScript từ máy chủ hiện tại; script-src self (không có dấu ngoặc kép) cho phép JavaScript từ máy chủ có tên "self" (và không từ máy chủ hiện tại) và có thể không phải là ý của bạn.

Cơ chế hộp cát

Còn một lệnh nữa đáng nói: sandbox. Hơi quan tâm khác với các hành động khác mà chúng tôi xem xét vì hệ thống này đặt ra các quy định hạn chế đối với những hành động trang có thể sử dụng thay vì tài nguyên mà trang có thể tải. Nếu Đã có lệnh sandbox, trang được xử lý như thể trang này đã được tải bên trong <iframe> có thuộc tính sandbox. Chiến dịch này có thể có nhiều tác động lên trang: buộc trang thành một nguồn gốc duy nhất và ngăn biểu mẫu nội dung gửi, v.v. Mặc dù nội dung nằm ngoài phạm vi của bài viết này một chút, nhưng bạn Bạn có thể xem toàn bộ thông tin chi tiết về các thuộc tính hộp cát hợp lệ trong "Cơ chế hộp cát" của thông số HTML5.

Thẻ meta

Cơ chế phân phối ưu tiên của CSP là tiêu đề HTTP. Tuy nhiên, cách này có thể hữu ích để đặt chính sách trên một trang ngay trong mã đánh dấu. Bạn có thể làm việc đó bằng cách sử dụng thẻ <meta> với thuộc tính http-equiv:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'"
/>

Bạn không thể sử dụng tính năng này cho frame-ancestors, report-uri hoặc sandbox.

Mã cùng dòng được coi là gây hại

Cần phải làm rõ rằng CSP dựa trên nguồn gốc trong danh sách cho phép, vì đó là phương pháp rõ ràng hướng dẫn trình duyệt xử lý các nhóm tài nguyên cụ thể chấp nhận được và từ chối các thông tin còn lại. Danh sách cho phép dựa trên nguồn gốc sẽ không hoạt động tuy nhiên, giải quyết mối đe doạ lớn nhất do tấn công XSS gây ra: chèn tập lệnh nội tuyến. Nếu kẻ tấn công có thể chèn thẻ tập lệnh trực tiếp chứa một số phần mềm độc hại tải trọng (<script>sendMyDataToEvilDotCom();</script>), trình duyệt không có cơ chế nào để phân biệt với trình duyệt thẻ tập lệnh nội tuyến. CSP giải quyết vấn đề này bằng cách cấm hoàn toàn tập lệnh cùng dòng: đó là cách duy nhất để chắc chắn.

Lệnh cấm này không chỉ bao gồm các tập lệnh được nhúng trực tiếp trong thẻ script mà còn bao gồm cả các tập lệnh Trình xử lý sự kiện cùng dòng và javascript: URL. Bạn cần chuyển nội dung của Các thẻ script vào một tệp bên ngoài rồi thay thế URL javascript:<a ... onclick="[JAVASCRIPT]"> bằng các lệnh gọi addEventListener() thích hợp. Ví dụ: bạn có thể viết lại những nội dung sau từ:

<script>
  function doAmazingThings() {
    alert('YOU AM AMAZING!');
  }
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>

thành một số thứ khác như:

<!-- amazing.html -->
<script src="amazing.js"></script>
<button id="amazing">Am I amazing?</button>

<div style="clear:both;"></div>
// amazing.js
function doAmazingThings() {
  alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('amazing').addEventListener('click', doAmazingThings);
});

Mã viết lại có một số ưu điểm vượt trội hơn khi hoạt động hiệu quả với CSP; đây đã là phương pháp hay nhất, cho dù bạn có sử dụng CSP hay không. Cùng dòng JavaScript kết hợp cấu trúc và hành vi chính xác theo cách không cần thiết. Các tài nguyên bên ngoài dễ dàng được lưu vào bộ nhớ đệm hơn cho trình duyệt, cũng dễ hiểu hơn đối với phát triển, hỗ trợ việc biên dịch và giảm kích thước. Bạn sẽ viết tốt hơn nếu bạn muốn di chuyển mã vào các tài nguyên bên ngoài.

Kiểu cùng dòng được xử lý theo cùng một cách: cả thuộc tính stylestyle thẻ phải được hợp nhất vào biểu định kiểu bên ngoài để bảo vệ chống lại nhiều loại thông minh đáng ngạc nhiên phương thức đánh cắp dữ liệu mà CSS cho phép.

Nếu phải có kiểu và tập lệnh cùng dòng, bạn có thể bật chế độ đó bằng cách thêm 'unsafe-inline' làm nguồn được phép trong script-src hoặc style-src . Bạn cũng có thể sử dụng số chỉ dùng một lần hoặc hàm băm (xem bên dưới), nhưng thực sự không nên làm vậy. Cấm tập lệnh cùng dòng là biện pháp bảo mật lớn nhất mà CSP mang lại, và việc cấm kiểu cùng dòng cũng sẽ làm cứng ứng dụng của bạn. Hơi quan tâm nỗ lực trước để đảm bảo rằng mọi thứ hoạt động chính xác sau khi di chuyển tất cả mã ngoài luồng, nhưng đó cũng là một sự đánh đổi đáng để thực hiện.

Nếu bạn chắc chắn phải sử dụng

CSP cấp 2 cung cấp khả năng tương thích ngược cho các tập lệnh cùng dòng bằng cách cho phép bạn thêm các tập lệnh cùng dòng cụ thể vào danh sách cho phép bằng cách sử dụng một số chỉ dùng một lần bằng mật mã (số sử dụng một lần) hoặc một hàm băm. Mặc dù có thể rườm rà nhưng sẽ hữu ích trong tích tắc.

Để sử dụng số chỉ dùng một lần, hãy cung cấp cho thẻ tập lệnh của bạn thuộc tính số chỉ dùng một lần. Giá trị của trường này phải khớp với một trong danh sách các nguồn đáng tin cậy. Ví dụ:

<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
  // Some inline code I can't remove yet, but need to asap.
</script>

Bây giờ, hãy thêm số chỉ dùng một lần vào lệnh script-src được thêm vào từ khoá nonce-.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Hãy nhớ rằng số chỉ dùng một lần phải được tạo lại cho mọi yêu cầu trang và chúng phải được không thể đoán được.

Hàm băm cũng hoạt động tương tự như vậy. Thay vì thêm mã vào thẻ tập lệnh, tạo hàm băm SHA của chính tập lệnh rồi thêm hàm này vào lệnh script-src. Ví dụ: giả sử trang của bạn có chứa:

<script>
  alert('Hello, world.');
</script>

Chính sách của bạn sẽ chứa nội dung sau:

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

Có một vài điều cần lưu ý ở đây. Tiền tố sha*- chỉ định thuật toán để tạo hàm băm. Trong ví dụ trên, sha256- được sử dụng. CSP cũng hỗ trợ sha384-sha512-. Khi tạo hàm băm, đừng thêm Thẻ <script>. Ngoài ra, cách viết hoa và khoảng trắng cũng quan trọng, bao gồm cả dấu đầu dòng hoặc khoảng trắng ở cuối.

Khi tìm kiếm trên Google về cách tạo hàm băm SHA sẽ đưa bạn đến các giải pháp cho mọi số lượng ngôn ngữ. Khi sử dụng Chrome 40 trở lên, bạn có thể mở Công cụ cho nhà phát triển, sau đó tải lại trang của bạn. Thẻ Bảng điều khiển sẽ chứa các thông báo lỗi với thông tin chính xác hàm băm sha256 cho từng tập lệnh cùng dòng của bạn.

Cả Eval

Ngay cả khi kẻ tấn công không thể chèn tập lệnh trực tiếp, chúng vẫn có thể đánh lừa ứng dụng của bạn thành chuyển đổi văn bản trơ thành JavaScript có thể thực thi và thực hiện thay mặt cho họ. eval(), mới Function() , setTimeout([string], ...)setInterval([string], ...) là tất cả các vectơ mà thông qua đó được chèn có thể thực thi nội dung nào đó độc hại không mong muốn. Giá trị mặc định của CSP ứng phó với rủi ro này là chặn hoàn toàn tất cả các vectơ này.

Điều này có một vài tác động đến cách bạn xây dựng ứng dụng:

  • Bạn phải phân tích cú pháp JSON qua JSON.parse tích hợp sẵn thay vì dựa vào eval Hoạt động JSON gốc có trong mọi trình duyệt kể từ IE8 và chúng được hoàn toàn an toàn.
  • Viết lại mọi cuộc gọi setTimeout hoặc setInterval mà bạn đang thực hiện bằng các hàm cùng dòng thay vì chuỗi. Ví dụ:
setTimeout("document.querySelector('a').style.display = 'none';", 10);

tốt hơn là:

setTimeout(function () {
  document.querySelector('a').style.display = 'none';
}, 10);
  • Tránh tạo mẫu cùng dòng trong thời gian chạy: Nhiều thư viện tạo mẫu sử dụng new Function() một cách thoải mái để tăng tốc việc tạo mẫu trong thời gian chạy. Đó là ứng dụng hữu ích của lập trình động, nhưng có nguy cơ đánh giá văn bản độc hại. Một số khung hỗ trợ ngay từ đầu, quay lại trình phân tích cú pháp mạnh mẽ khi không có eval. Lệnh ng-csp của AngularJS là một ví dụ điển hình cho trường hợp này.

Tuy nhiên, lựa chọn tốt hơn là ngôn ngữ tạo mẫu, cung cấp biên dịch trước (Thanh công cụ có, chẳng hạn). Việc biên dịch trước các mẫu của bạn có thể giúp cải thiện trải nghiệm người dùng nhanh hơn cách triển khai trong thời gian chạy nhanh nhất, đồng thời cũng an toàn hơn. Nếu eval và các đoạn văn bản sang JavaScript rất cần thiết cho ứng dụng của bạn, bạn có thể bật chúng bằng cách thêm 'unsafe-eval' làm nguồn được phép trong script-src nhưng chúng tôi tuyệt đối không khuyến khích điều này. Cấm khả năng thực thi Chuỗi khiến kẻ tấn công khó thực thi quyền truy cập trái phép hơn nhiều trên trang web của bạn.

Báo cáo

Việc CSP có thể chặn các tài nguyên không đáng tin cậy ở phía máy khách mang lại một lợi ích lớn nhưng sẽ rất hữu ích nếu có một loại thông báo gửi lại máy chủ để bạn có thể xác định và loại bỏ mọi lỗi cho phép độc hại ngay từ đầu. Để đạt được mục tiêu này, bạn có thể hướng dẫn trình duyệt đến POST báo cáo lỗi vi phạm theo định dạng JSON cho một vị trí được chỉ định trong lệnh report-uri.

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Các báo cáo đó sẽ trông giống như sau:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

Đối tượng này chứa một phần thông tin hữu ích giúp bạn theo dõi nguyên nhân cụ thể của vi phạm, bao gồm trang mà vi phạm đã xảy ra (document-uri), liên kết giới thiệu của trang đó (lưu ý rằng không giống như liên kết HTTP trường tiêu đề, khoá không bị viết sai chính tả), tài nguyên đã vi phạm chính sách của trang (blocked-uri), chỉ thị cụ thể mà trang này đã vi phạm (violated-directive) và chính sách hoàn chỉnh của trang (original-policy).

Chỉ báo cáo

Nếu mới bắt đầu sử dụng CSP, bạn nên đánh giá của ứng dụng trước khi triển khai một chính sách hà khắc cho người dùng. Là bước đệm để hoàn tất việc triển khai, bạn có thể yêu cầu trình duyệt giám sát chính sách, báo cáo hành vi vi phạm nhưng không thực thi các quy định hạn chế. Thay vì gửi tiêu đề Content-Security-Policy, gửi Tiêu đề Content-Security-Policy-Report-Only.

Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Chính sách được chỉ định ở chế độ chỉ báo cáo sẽ không chặn tài nguyên bị hạn chế, mà ứng dụng sẽ gửi báo cáo vi phạm đến vị trí mà bạn chỉ định. Bạn thậm chí có thể gửi cả hai tiêu đề, thực thi một chính sách trong khi giám sát một chính sách khác. Đây là một trải nghiệm tuyệt vời cách đánh giá tác động của những thay đổi đối với CSP của ứng dụng: bật báo cáo chính sách mới, theo dõi báo cáo vi phạm và sửa mọi lỗi tăng âm lượng; khi bạn đã hài lòng với hiệu quả của chính sách, hãy bắt đầu thực thi chính sách mới.

Sử dụng thực tế

CSP 1 khá hữu dụng trong Chrome, Safari và Firefox, nhưng đã hạn chế hỗ trợ trong IE 10. Bạn có thể xem thông tin cụ thể tại caniuse.com. CSP cấp độ 2 đã có trong Chrome kể từ phiên bản 40. Các trang web lớn như Twitter và Facebook đã triển khai tiêu đề (Nghiên cứu điển hình của Twitter rất đáng để đọc) và tiêu chuẩn này rất sẵn sàng để bạn bắt đầu triển khai trên các trang web của mình.

Bước đầu tiên trong việc xây dựng chính sách cho ứng dụng của bạn là đánh giá mà bạn đang thực sự tải. Khi bạn nghĩ rằng mình đã hiểu được cách mọi thứ được tập hợp trong ứng dụng của bạn, hãy thiết lập chính sách dựa trên các yêu cầu liên quan. Hãy xem qua một vài trường hợp sử dụng phổ biến và xác định cách hỗ trợ họ hiệu quả nhất trong phạm vi bảo vệ của CSP.

Trường hợp sử dụng 1: tiện ích mạng xã hội

  • Nút +1 của Google bao gồm một tập lệnh từ https://apis.google.com và nhúng một <iframe> từ https://plusone.google.com. Bạn cần một chính sách bao gồm cả hai nguồn gốc để nhúng nút. Chính sách tối thiểu sẽ là script-src https://apis.google.com; child-src https://plusone.google.com. Bạn cũng cần để đảm bảo rằng đoạn mã JavaScript mà Google cung cấp được kéo vào tệp JavaScript bên ngoài. Nếu bạn đã có chính sách dựa trên Cấp 1 bằng cách sử dụng frame-src Cấp 2 yêu cầu bạn thay đổi thành child-src. Việc này không cần thiết nữa trong CSP cấp 3.

  • Nút thích của Facebook có một số cách triển khai. Chúng tôi khuyên bạn nên duy trì <iframe> vì phiên bản này được tạo hộp cát an toàn với phần còn lại của trang web. Nó cần có lệnh child-src https://facebook.com để hoạt động đúng cách. Ghi chú theo mặc định, mã <iframe> mà Facebook cung cấp sẽ tải URL, //facebook.com. Thay đổi điều đó để chỉ định rõ HTTPS: https://facebook.com. Chẳng có lý do gì để sử dụng HTTP nếu bạn không cần.

  • Nút tweet của Twitter dựa vào quyền truy cập vào tập lệnh và khung, cả hai đều được lưu trữ tại https://platform.twitter.com. (Twitter cũng cung cấp URL tương đối theo default; chỉnh sửa mã để chỉ định HTTPS khi sao chép/dán mã cục bộ.) Bạn sẽ thiết lập xong với script-src https://platform.twitter.com; child-src https://platform.twitter.com, miễn là bạn di chuyển đoạn mã JavaScript mà Twitter cung cấp trong tệp JavaScript bên ngoài.

  • Các nền tảng khác có yêu cầu tương tự và có thể được giải quyết tương tự. Bạn chỉ nên đặt default-src'none' và xem bảng điều khiển của mình để xác định những tài nguyên bạn cần bật để tiện ích hoạt động.

Nhiều tiện ích rất đơn giản: bạn chỉ cần kết hợp chính sách nên chúng tôi muốn hợp nhất tất cả các tài nguyên thuộc cùng một loại thành một . Nếu bạn muốn sử dụng cả 3 tiện ích mạng xã hội, chính sách sẽ như sau:

script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com

Trường hợp sử dụng 2: khoá

Giả sử trong một khoảnh khắc mà bạn chạy trang web ngân hàng và muốn đảm bảo rằng chỉ có thể tải những tài nguyên mà bạn tự viết. Trong trường hợp này, bắt đầu bằng một chính sách mặc định chặn hoàn toàn mọi thứ (default-src 'none') và xây dựng từ đó.

Giả sử ngân hàng tải tất cả hình ảnh, kiểu và tập lệnh từ CDN tại https://cdn.mybank.net và kết nối qua XHR với https://api.mybank.com/ tới kéo các bit dữ liệu khác nhau xuống. Khung được sử dụng, nhưng chỉ cho các trang cục bộ trên (không có nguồn gốc của bên thứ ba). Không có Flash trên trang web, không có phông chữ, không ứng dụng khác. Tiêu đề CSP có tính hạn chế nhất mà chúng tôi có thể gửi là:

Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; child-src 'self'

Trường hợp sử dụng 3: Chỉ SSL

Một quản trị viên diễn đàn thảo luận về lễ cưới muốn đảm bảo rằng tất cả các tài nguyên đều được chỉ được tải qua các kênh bảo mật, nhưng không thực sự viết nhiều mã; viết lại nhiều phần lớn phần mềm diễn đàn của bên thứ ba được bổ sung đầy đủ kịch bản và phong cách cùng dòng vượt quá khả năng của anh. Chính sách sau đây sẽ là có hiệu lực:

Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'

Mặc dù https: được chỉ định trong default-src, nhưng tập lệnh và kiểu không tự động kế thừa nguồn đó. Mỗi lệnh hoàn toàn sẽ ghi đè giá trị mặc định cho loại tài nguyên cụ thể đó.

Tương lai

Chính sách bảo mật nội dung Cấp 2 là Đề xuất ứng cử viên. Nhóm làm việc về bảo mật ứng dụng web của W3C đã bắt đầu làm việc trong vòng lặp tiếp theo của quy cách, Chính sách bảo mật nội dung cấp 3

Nếu bạn quan tâm đến thảo luận về các tính năng sắp ra mắt này, duyệt qua kho lưu trữ danh sách gửi thư Public-webappsec@, hoặc tự tham gia.

Phản hồi