CSP (Content Security Policy) là 01 lớp bảo mật của trình duyệt giúp ngăn chặn XSS, ngay cả khi hacker đã chèn được mã độc vào trang.
🛡️ Các lớp bảo vệ XSS
| 🔢 | 🛠️ Hàm/Kỹ thuật | 🎯 Mục đích |
|---|---|---|
| 1️⃣ | trim() | Loại bỏ khoảng trắng đầu/cuối |
| 2️⃣ | strip_tags() (nếu không cho phép HTML) | Xóa các thẻ HTML |
| 3️⃣ | filter_var() | Validate email, URL, số... |
| 4️⃣ | htmlspecialchars() | Escape khi xuất ra HTML (quan trọng nhất) |
| 5️⃣ | Prepared Statement | Chống SQL Injection (không phải XSS) |
| 6️⃣ | CSP (Content Security Policy) | Giảm thiểu XSS ngay cả khi lọt dữ liệu độc |
Ví dụ 1: Không có CSP
<?php
echo $_GET['name'];
?>
Người dùng truy cập:
index.php?name=<script>alert('Hack')</script>
Kết quả:
💥 Popup hiện lên.
Ví dụ 2: Có CSP
Trong PHP:
<?php
header("Content-Security-Policy: default-src 'self'");
echo $_GET['name'];
?>
Nếu hacker chèn:
<script>alert(1)</script>
Trình duyệt sẽ báo lỗi:
Refused to execute inline script because it violates the following Content Security Policy...
=> Script không chạy.
Ví dụ 3: Chỉ cho phép JavaScript từ website của mình
header("
Content-Security-Policy:
default-src 'self';
script-src 'self';
");
Được phép
<script src="/js/app.js"></script>
Không được phép
<script src="https://evil.com/hack.js"></script>
Ví dụ 4: Chặn Inline Script
header("
Content-Security-Policy:
script-src 'self';
");
HTML
<script>
alert(1);
</script>
❌ Bị chặn.
Ví dụ 5: Chặn Event Handler
HTML
<button onclick="alert(1)">
Nếu CSP
script-src 'self'
thì
onclick=""
cũng không chạy.
Đây là điểm cực mạnh của CSP.
Ví dụ 6: Chỉ cho phép ảnh từ CDN
header("
Content-Security-Policy:
default-src 'self';
img-src 'self' https://cdn.example.com;
");
Được
<img src="https://cdn.example.com/a.png">
Không được
<img src="https://evil.com/x.png">
Ví dụ CSP thực tế
<?php
header("
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
object-src 'none';
frame-src 'none';
base-uri 'self';
form-action 'self';
");
?>
Ý nghĩa:
| 🔢 | ⚙️ Directive | 🛡️ Chức năng |
|---|---|---|
| 1️⃣ | default-src 'self' | Chỉ tải tài nguyên từ chính website |
| 2️⃣ | script-src 'self' | Chỉ chạy JavaScript nội bộ |
| 3️⃣ | style-src 'self' | Chỉ dùng CSS nội bộ |
| 4️⃣ | img-src 'self' data: | Chỉ cho ảnh từ website hoặc Data URI |
| 5️⃣ | font-src 'self' | Chỉ tải font nội bộ |
| 6️⃣ | object-src 'none' | Cấm Flash, Java Applet... |
| 7️⃣ | frame-src 'none' | Không cho nhúng iframe |
| 8️⃣ | base-uri 'self' | Ngăn thay đổi thẻ <base> |
| 9️⃣ | form-action 'self' | Form chỉ được submit về chính website |
Lưu ý
Nếu website của bạn dùng:
Bootstrap CDN
Google Fonts
Font Awesome CDN
jQuery CDN
thì CSP phải cho phép các domain đó, ví dụ:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.jsdelivr.net;
style-src 'self' https://cdn.jsdelivr.net https://fonts.googleapis.com;
font-src https://fonts.gstatic.com;
Nếu không, CSS hoặc JavaScript từ CDN sẽ bị trình duyệt chặn.
CSP không thay thế
htmlspecialchars()hay việc validate dữ liệu. Hãy xem CSP là lớp phòng thủ cuối cùng: nếu lỡ có lỗ hổng XSS, CSP có thể ngăn nhiều kiểu tấn công thực thi trong trình duyệt.
Không nên đặt ở từng file view.
❌ Cách không nên
Đầu mỗi file:
<?php
header("Content-Security-Policy: ...");
?>
Nếu có 100 trang thì phải sửa 100 nơi.
✅ Cách 1 (Khuyến nghị) - Đặt ở file chung
Ví dụ:
index.php
config.php
bootstrap.php
init.php
Ngay sau <?php
<?php
header("
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
object-src 'none';
frame-src 'none';
base-uri 'self';
form-action 'self';
");
Sau đó
require "config.php";
Tất cả các trang đều được áp dụng CSP.
✅ Cách 2 (MVC)
Ví dụ
public/index.php
<?php
header(...);
require "../app/bootstrap.php";
Laravel, CodeIgniter... đều làm tương tự thông qua middleware hoặc kernel.
✅ Cách 3 (Apache)
Trong .htaccess
Header set Content-Security-Policy "default-src 'self'; script-src 'self';"
Toàn bộ website đều có CSP.
✅ Cách 4 (Nginx)
add_header Content-Security-Policy "default-src 'self';";
Lưu ý rất quan trọng
Nếu website dùng:
Bootstrap CDN
jQuery CDN
Font Awesome CDN
Google Fonts
thì CSP ở trên sẽ làm hỏng giao diện.
Ví dụ
<link href="https://cdn.jsdelivr.net/..." ...>
sẽ bị chặn.
Lúc đó phải khai báo:
style-src 'self' https://cdn.jsdelivr.net https://fonts.googleapis.com;
và
font-src 'self' https://fonts.gstatic.com;
Nếu dùng JavaScript inline
Ví dụ
<script>
alert("Hello");
</script>
CSP
script-src 'self';
➡ Không chạy.
Đây là lý do các dự án hiện đại thường không viết JavaScript trực tiếp trong HTML, mà chuyển hết sang các file như:
/js/app.js
/js/main.js
/js/admin.js
Điều này vừa giúp CSP phát huy hiệu quả, vừa làm mã nguồn dễ bảo trì hơn.
Mẹo: Nếu đang xây dựng framework PHP Core riêng, hãy đặt tất cả các header bảo mật vào một file như security.php hoặc bootstrap.php, ví dụ:
<?php
// Security Headers
header("X-Frame-Options: DENY");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; frame-src 'none'; base-uri 'self'; form-action 'self';");
Sau đó chỉ cần:
require_once 'security.php';
là toàn bộ website sẽ được bảo vệ bởi các HTTP Security Headers, rất gọn và chuyên nghiệp.




Không có nhận xét nào:
Đăng nhận xét