Defaults.Exposed › Cách khắc phục › Content-Security-Policy (CSP)
Cách khắc phục Content-Security-Policy (CSP)
Content Security Policy là bộ quy tắc an toàn website của bạn trao cho trình duyệt mỗi khách truy cập, nói chính xác mã nào được phép chạy. Không có nó, nếu có thứ gì độc hại vào trang — qua hộp bình luận, plugin bị tấn công, hoặc script bên thứ ba — trình duyệt sẽ chạy nó tự do, kể cả mã lặng lẽ skim số thẻ và mật khẩu của khách hàng khi họ gõ, trong khi ổ khóa vẫn hiển thị.
Điểm mấu chốt với doanh nghiệp bạn: Nếu website bị can thiệp, mã độc có thể đọc thông tin thẻ thanh toán và đăng nhập của khách hàng ngay trên trang thanh toán của bạn trong khi mọi thứ trông hoàn toàn bình thường — để lại cho bạn chargeback, khiếu nại gian lận, vi phạm dữ liệu phải báo cáo, và lỗi kiểm tra mà nhóm bảo mật của khách hàng lớn hơn dùng để đình trệ hoặc hủy thỏa thuận.
Điều này có thể gây thiệt hại gì
- Mã ẩn trượt vào một trong các trang của bạn và lặng lẽ sao chép mọi số thẻ và mật khẩu khách hàng nhập ở thanh toán, gửi cho kẻ tấn công trong khi website trông hoàn toàn bình thường — bạn chỉ phát hiện khi khiếu nại gian lận đến.
- Kẻ lừa đảo đặt form 'thanh toán tại đây' giả trên website thật của bạn, chụp thanh toán vào tài khoản của chúng; khách hàng nghĩ họ đã trả cho bạn, đổ lỗi cho bạn khi hàng không đến, và đòi lại tiền.
- Nhóm bảo mật của khách hàng lớn hơn quét website của bạn, thấy bảo vệ cơ bản này bị tắt, và gắn cờ — đình trệ hoặc làm bạn mất hợp đồng cho đến khi có thể chứng minh đã sửa.
- Vi phạm có thể truy nguyên đến thiếu biện pháp bảo vệ tiêu chuẩn trở thành sự cố phải báo cáo: câu hỏi từ cơ quan quản lý, thông báo đến khách hàng, và thiệt hại danh tiếng tốn kém hơn nhiều so với bản sửa miễn phí.
Tại sao điều này quan trọng. Ổ khóa chứng minh kết nối đến website của bạn là riêng tư, nhưng nó không làm gì để kiểm soát mã nào chạy khi khách truy cập đang trên trang. Content Security Policy là biện pháp bảo vệ làm điều đó — nó nói với trình duyệt bỏ qua bất kỳ script nào không đến từ nguồn bạn tin tưởng, vì vậy một trường bị can thiệp, quảng cáo, hoặc plugin không thể trở thành công cụ ăn cắp tiền và dữ liệu khách hàng. Đây là kiểm tra có điểm trên scorecard của bạn, đáng điểm thật, và là một trong những thứ đầu tiên đánh giá bảo mật chuyên nghiệp tìm kiếm.
Thực ra là gì, giải thích đơn giản
Khi ai đó truy cập website của bạn, trình duyệt tải trang và chạy bất kỳ mã nào trên đó — các script làm menu thả xuống, nút hoạt động, form thanh toán gửi, v.v. Theo mặc định, trình duyệt tin tưởng tất cả. Nó không có cách nào biết mã nào thực sự là của bạn và mã nào bị ai đó khác lén vào.
Content Security Policy (thường viết tắt là CSP) là danh sách ngắn quy tắc website của bạn gắn vào mỗi trang, nói với trình duyệt: “chỉ chạy mã từ các nguồn tôi đã phê duyệt, và từ chối mọi thứ khác.” Đó là sự khác biệt giữa hộp đêm cho phép bất kỳ ai vào và hộp đêm có danh sách khách mời ở cửa.
Lý do điều này quan trọng đến vậy là website bị can thiệp liên tục — không phải lúc nào cũng bằng cách tấn công máy chủ của bạn, mà qua cửa sau hầu hết website để mở: hộp bình luận, ô tìm kiếm, plugin lỗi thời, script bên thứ ba cho quảng cáo hoặc analytics, hoặc widget chat. Nếu kẻ tấn công đưa được dù chỉ một dòng mã của chúng vào một trong các trang của bạn, trình duyệt chạy nó như thể là của bạn. Từ đó nó có thể đọc mọi thứ khách hàng gõ — số thẻ, mật khẩu, địa chỉ — và lặng lẽ gửi đi nơi khác. Content Security Policy đóng cửa đó bằng cách từ chối chạy bất cứ thứ gì từ nguồn bạn không phê duyệt.
Điều này có thể khiến bạn mất gì
Đây không phải trừu tượng. Cuộc tấn công mà Content Security Policy ngăn chặn — mã được chèn vào trang đánh cắp dữ liệu từ chính khách hàng của bạn — là nguyên nhân đằng sau một số vi phạm skimming thẻ lớn nhất trong lịch sử. Đây là cách nó thường diễn ra với doanh nghiệp bình thường:
-
Công cụ đọc thẻ vô hình ở trang thanh toán. Kẻ tấn công lén vài dòng mã vào trang thanh toán của bạn qua plugin dễ bị tổn thương hoặc script bên thứ ba bị xâm phạm. Mọi số thẻ, tên, và CVV khách hàng gõ được sao chép và gửi cho kẻ tấn công theo thời gian thực. Website trông và hoạt động hoàn hảo; ổ khóa ở đó. Bạn phát hiện ra nhiều tuần sau khi nhà cung cấp thanh toán gọi về một loạt báo cáo gian lận tất cả có nguồn gốc từ cửa hàng của bạn. Giờ bạn đối mặt với chargeback, kiểm toán bảo mật bắt buộc, có thể mất quyền xử lý thẻ, và vi phạm mà bạn có thể phải báo cáo theo quy định.
-
Form thanh toán giả. Kẻ lừa đảo chèn hộp “thanh toán tại đây” thuyết phục vào website thật của bạn. Khách hàng nhập thông tin tin tưởng thương hiệu của bạn; tiền và dữ liệu đến tay kẻ tấn công. Khách hàng đổ lỗi cho bạn — và họ không sai, vì nó xảy ra trên website của bạn.
-
Hợp đồng bị mất. Khách hàng tiềm năng lớn hơn chạy quét tự động website của bạn như một phần thẩm định nhà cung cấp. Thiếu Content Security Policy xuất hiện ngay lập tức như khoảng cách nghiêm trọng cao. Với người xem xét thu mua hoặc bảo mật, thiếu một biện pháp bảo vệ đó đọc là “nhà cung cấp này không làm những điều cơ bản” — và thỏa thuận đình trệ trong khi họ yêu cầu khắc phục, hoặc âm thầm chuyển sang đối thủ đã vượt qua.
-
Vi phạm phải báo cáo. Khi vi phạm dữ liệu có thể truy nguyên đến thiếu biện pháp bảo vệ tiêu chuẩn, miễn phí, nó không còn là xui xẻo và bắt đầu trông như sơ suất. Điều đó thay đổi câu hỏi của cơ quan quản lý, nghĩa vụ thông báo khách hàng, và chi phí — cả phạt tiền và thiệt hại danh tiếng, tồn tại lâu sau khi sự cố được đóng.
-
Quảng cáo hoặc widget bị xâm phạm. Nhiều website tải mã từ bên ngoài — mạng quảng cáo, font, chat hỗ trợ, analytics. Nếu bất kỳ cái nào trong số đó bị tấn công, mã độc đi thẳng vào trang của bạn. Content Security Policy giới hạn bán kính nổ bằng cách chỉ cho phép nguồn bên ngoài cụ thể bạn tin tưởng, vì vậy vi phạm của một nhà cung cấp không tự động trở thành của bạn.
Thực ra nó là gì (chi tiết)
Content Security Policy được gửi như một HTTP response header duy nhất — một dòng máy chủ web của bạn gửi với mỗi trang. Giá trị của nó là một tập chỉ thị, mỗi cái đặt tên một loại nội dung và các nguồn được phép cho nó. Ví dụ:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'
Nói đơn giản, điều đó có nghĩa: theo mặc định chỉ tải thứ từ tên miền của chính tôi; chỉ chạy script từ tên miền của chính tôi; không cho phép plugin kiểu cũ; và không để trang khác nhúng trang của tôi vào frame.
“Tốt” trông như thế nào. Kiểm tra của chúng tôi không chỉ tìm sự có mặt của header — nó đọc từng chỉ thị chính sách và tính điểm mạnh thực sự của nó như người đánh giá bảo mật sẽ làm. Chính sách mạnh:
- Đặt mức cơ bản hạn chế (
default-src 'self') và chỉ mở rộng cho các bên thứ ba đáng tin cụ thể bạn thực sự dùng. - Tránh các lỗ hổng. Nó không dùng
'unsafe-inline'hoặc'unsafe-eval'cho script, và không dùng nguồn wildcard (*) hoặc nguồn chỉ scheme (nhưhttps:) cho script — chúng hiệu quả mở lại cửa mà chính sách muốn đóng. Khi script inline thực sự cần thiết, nó dùng nonce hoặc hash để chỉ mã được phê duyệt cụ thể của bạn chạy. - Khóa framing với
frame-ancestors 'self'(điều này cũng chặn tấn công “nhúng trang của bạn để lừa khách hàng”) và vô hiệu hóa plugin cũ vớiobject-src 'none'. - Đang thực thi, không phải chỉ-báo-cáo. Header
Content-Security-Policy-Report-Onlychỉ theo dõi; nó không cung cấp bảo vệ runtime nào. Kiểm tra của chúng tôi trao cho nó một phần nhỏ tín dụng và không bao giờ ghi nhận là đạt. Bạn chỉ được bảo vệ khi chính sách đang thực thi.
Chính sách tồn tại nhưng dựa vào 'unsafe-inline', 'unsafe-eval', hoặc wildcard vẫn sẽ điểm kém — vì trong thực tế nó cung cấp ít bảo vệ thật. Mục tiêu là chính sách chặt chẽ, không chỉ bất kỳ chính sách nào.
Cách sửa (miễn phí, ~1–2 giờ)
Chuyển cho người IT của bạn hoặc người chạy website — bản sửa hoàn toàn miễn phí. Chúng tôi chỉ tính phí để theo dõi rằng nó luôn được bật và đúng theo thời gian; bật nó không tốn gì. Lý do điều này mất một hoặc hai giờ thay vì vài phút là bước thử nghiệm cẩn thận ngăn nó vô tình chặn các phần của chính website bạn.
-
Bắt đầu ở chế độ chỉ-báo-cáo — chưa thực thi. Thêm response header
Content-Security-Policy-Report-Only. Điều này theo dõi và ghi nhật ký những gì sẽ bị chặn mà không thực sự chặn gì, vì vậy trang live vẫn hoạt động trong khi bạn tìm hiểu mỗi trang phụ thuộc vào gì. (Quan trọng: chỉ-báo-cáo không cung cấp bảo vệ nào cho khách truy cập — đó chỉ là bước đầu tiên an toàn.) -
Xây dựng chính sách từ những gì website thực sự dùng. Xem xét báo cáo để tìm mọi nguồn script, style, font, và hình ảnh hợp lệ — tên miền của bạn, analytics, nhà cung cấp thanh toán, host font, widget chat — và liệt kê chúng là nguồn được phép. Điểm bắt đầu vững chắc là
default-src 'self'cộng với các mục rõ ràng cho các bên thứ ba đáng tin bạn thực sự dùng. -
Tránh các lỗ hổng đánh bại toàn bộ mục đích. Tránh
'unsafe-inline'và'unsafe-eval'cho script, và tránh nguồn wildcard như*và scheme bare nhưhttps:cho script — chúng mở lại chính xác khoảng cách mà chính sách muốn đóng. Khi script inline không thể tránh khỏi, dùng nonce hoặc hash để chỉ mã được phê duyệt cụ thể của bạn chạy. -
Khóa framing và plugin. Thêm
frame-ancestors 'self'(điều này cũng ngăn các trang khác nhúng trang của bạn để lừa khách hàng, và nó thỏa mãn kiểm tra clickjacking liên quan) vàobject-src 'none'để chặn tấn công dựa trên plugin cũ. -
Chuyển từ chỉ-báo-cáo sang thực thi. Sau khi báo cáo sạch và website hoạt động, thay tên header từ
Content-Security-Policy-Report-OnlythànhContent-Security-Policy. Đây là bước thực sự mang lại bảo vệ — chính sách chỉ-báo-cáo đơn lẻ không làm vậy, và sẽ không vượt qua kiểm tra.Nơi bạn đặt header phụ thuộc vào nền tảng:
- Cloudflare: Rules → Transform Rules → Modify Response Header → đặt
Content-Security-Policy. - Nginx:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" always; - Apache:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" - IIS (web.config): thêm HTTP response header tùy chỉnh tên
Content-Security-Policyvới chính sách là giá trị của nó. - Google Workspace / Microsoft 365: những thứ này chạy email của bạn, không phải website công khai, vì vậy chính sách được đặt bất cứ nơi nào website của bạn thực sự được lưu trữ (Cloudflare hoặc web host ở trên), không phải trong console admin email.
- Cloudflare: Rules → Transform Rules → Modify Response Header → đặt
-
Kiểm tra lại tên miền để xác nhận chính sách giờ hiển thị là đang bật và thực thi, không có lỗ hổng làm yếu.
Các lỗi phổ biến
- Dừng ở chỉ-báo-cáo. Lỗi đơn lẻ phổ biến nhất: chính sách được thêm ở chế độ chỉ-báo-cáo, mọi người tiếp tục, và website thực sự không bao giờ được bảo vệ. Chỉ-báo-cáo không chặn gì. Bạn phải chuyển sang thực thi.
- Dùng
'unsafe-inline'để làm nó “chỉ hoạt động.” Khi chính sách chặn script inline hợp lệ, giải pháp nhanh là cho phép tất cả script inline — nhưng điều đó mở lại chính xác lỗ mà chính sách muốn đóng. Dùng nonce hoặc hash thay thế. - Dùng wildcard.
*bare (hoặchttps:) trongscript-srccho phép script từ bất cứ đâu, nghĩa là chính sách hầu như không cung cấp bảo vệ thật và vẫn điểm thấp. - Quên nguồn bên thứ ba. Thực thi chính sách nghiêm ngặt mà không liệt kê trước các dịch vụ bên ngoài hợp lệ bạn dùng (analytics, font, widget thanh toán) có thể làm hỏng các phần của chính website bạn — đó chính xác là lý do tại sao bước thử nghiệm chỉ-báo-cáo tồn tại.
- Chỉ đặt trên trang chủ. Chính sách cần bao phủ mỗi trang, đặc biệt trang thanh toán, đăng nhập và tài khoản — đó là những trang đáng tấn công.
- Coi nó như thay thế cho ổ khóa. Content Security Policy và HTTPS/HSTS bảo vệ những thứ khác nhau. Bạn muốn tất cả chúng; cái này không bù cho cái kia.
FAQ
Tôi không rành kỹ thuật — tôi có thể tự xử lý điều này không?
Bạn không cần hiểu các chi tiết. Đây là cài đặt được thêm bởi người chạy website hoặc hosting của bạn, và trên dịch vụ như Cloudflare nó được hướng dẫn phần lớn. Chuyển phần 'Cách sửa' bên dưới cho họ. Miễn phí; thận trọng duy nhất là nên triển khai cẩn thận trong thử nghiệm chỉ-theo-dõi trước để không vô tình chặn các phần của chính website bạn — đó chính xác là những gì các bước bao gồm.
Tôi đã có ổ khóa và chứng chỉ SSL — website tôi không an toàn sao?
Ổ khóa bảo vệ việc gửi trang của bạn; nó không kiểm soát những gì chạy bên trong nó. Nếu mã độc vào trang — qua plugin bị tấn công, quảng cáo bị xâm phạm, hoặc trường bị chèn vào — ổ khóa không ngăn nó đánh cắp dữ liệu. Content Security Policy là lớp giới hạn những gì được phép chạy ngay từ đầu. Chúng bảo vệ những thứ khác nhau, và bạn muốn cả hai.
Bật cái này có thể phá website của tôi không?
Có thể nếu bật tích cực ngay lập tức, vì nó có thể chặn các script hợp lệ bạn thực sự dùng. Đó là lý do tại sao cách tiếp cận tiêu chuẩn là bắt đầu ở chế độ thử nghiệm 'chỉ-báo-cáo' theo dõi mà không chặn, sửa bất cứ thứ gì nó gắn cờ, và chỉ sau đó thực thi. Làm theo cách này thì an toàn — và bước thử nghiệm được tích hợp vào phần sửa bên dưới.
Chúng tôi đã đặt nó ở chế độ 'chỉ-báo-cáo' rồi — chúng tôi đã được bảo vệ chưa?
Chưa, và đây là cảm giác an toàn giả phổ biến nhất. Chế độ chỉ-báo-cáo theo dõi và ghi nhật ký những gì sẽ bị chặn, nhưng nó không chặn gì — khách truy cập không có bảo vệ thật. Đó chỉ là bước đầu tiên an toàn. Kiểm tra của chúng tôi trao cho chỉ-báo-cáo một phần nhỏ tín dụng của chính sách thật và sẽ không ghi nhận là đạt. Bạn chỉ được bảo vệ khi chuyển sang chế độ thực thi.
Điều này có ảnh hưởng điểm của chúng tôi không, hay chỉ là tư vấn?
Ảnh hưởng điểm của bạn. Kiểm tra Content Security Policy được tính điểm và đáng đến 25 điểm trong danh mục Bảo mật Web. Chính sách thiếu hoặc yếu được đánh dấu nghiêm trọng cao và kéo điểm xuống — và đây chính xác là loại khoảng cách bảng câu hỏi bảo mật của khách hàng hỏi.
Nhà phát triển của chúng tôi đã thêm chính sách nhưng điểm vẫn thấp — tại sao?
Chính sách có thể tồn tại và vẫn yếu. Thủ phạm phổ biến nhất là lỗ hổng như 'unsafe-inline' và 'unsafe-eval' cho script, hoặc nguồn wildcard (bare *), chúng mở lại chính xác khoảng cách mà chính sách muốn đóng. Kiểm tra của chúng tôi đọc từng chỉ thị chính sách và tính điểm thấp hơn cho những điểm yếu đó — chính sách cho phép bất cứ thứ gì điểm không tốt hơn không có gì nhiều. Bản sửa là siết chặt quy tắc script bằng nonces hoặc hash thay vì những lỗ hổng đó.