0

Bài 8: Xử lý dữ liệu thô và bảo mật XSS ({!! !!} và @verbatim)

Chào mừng bạn đến với Bài 8! Trong quá trình phát triển web, bảo mật là yếu tố sống còn. Ở các bài trước, chúng ta đã dùng cú pháp {{ }} để in dữ liệu một cách an toàn. Tuy nhiên, sẽ có những tình huống bạn cần hiển thị các thẻ HTML thực sự từ cơ sở dữ liệu, hoặc bạn muốn hiển thị các cặp ngoặc nhọn {{ }} mà không muốn Blade biên dịch nhầm. Bài học này sẽ giải quyết trọn vẹn vấn đề đó.

1. Hiểu rõ hơn về bảo mật XSS và cú pháp {{ }}

Như đã nhắc ở Bài 1, khi bạn viết:

HTML

{{ $userInput }}

Laravel sẽ tự động chạy hàm htmlspecialchars() bên dưới để chuyển đổi các ký tự đặc biệt (như <, >, &, ") thành mã thực thể HTML (HTML entities).

  • Tại sao lại làm vậy? Để ngăn chặn lỗ hổng XSS (Cross-Site Scripting). Nếu kẻ tấn công nhập đoạn mã độc hại như <script>alert('Hacker!')</script> vào ô bình luận, cú pháp {{ }} sẽ biến nó thành dạng văn bản thuần túy hiển thị trên màn hình thay vì thực thi đoạn script đó.

2. In dữ liệu thô (Raw Data) với {!! !!}

Tuy nhiên, đôi khi bạn lưu trữ nội dung từ các trình soạn thảo văn bản phong phú (Rich Text Editors như CKEditor, TinyMCE) trong cơ sở dữ liệu. Dữ liệu này chứa các thẻ HTML hợp lệ như <strong>, <p>, <ul>,... mà bạn muốn trình duyệt hiển thị dạng giao diện.

Lúc này, bạn dùng cú pháp {!! !!}:

HTML

<div class="article-content">
    {!! $article->body !!}
</div>

  • Cảnh báo bảo mật cực kỳ quan trọng: Tuyệt đối không dùng {!! !!} cho dữ liệu trực tiếp do người dùng nhập vào mà chưa qua bước lọc (sanitization). Nếu dùng bừa bãi, website của bạn sẽ dính lỗi XSS nghiêm trọng. Hãy đảm bảo dữ liệu đã được làm sạch (ví dụ dùng thư viện như HTMLPurifier) trước khi đưa vào {!! !!}.

3. Tránh Blade biên dịch nhầm cú pháp với @verbatim

Khi bạn viết các ứng dụng hiện đại kết hợp với các framework JavaScript ở phía client (như Vue.js, Alpine.js, hoặc Angular), chúng cũng thường sử dụng cú pháp ngoặc nhọn kép {{ biến }} để hiển thị dữ liệu trên giao diện.

Khi Blade nhìn thấy cú pháp {{ }} bên trong file view, nó sẽ cố gắng tự động phân tích và tìm biến PHP tương ứng. Nếu không tìm thấy, nó sẽ báo lỗi!

Để giải quyết tình trạng này, Blade cung cấp chỉ thị @verbatim:

HTML

@verbatim
    <div div id="app">
        <!-- Đoạn này sẽ được Vue.js xử lý, Blade sẽ bỏ qua hoàn toàn -->
        <h1>{{ message }}</h1>
        <p>Xin chào, @{{ name }}</p>
    </div>
@endverbatim

  • Toàn bộ nội dung nằm bên trong khối @verbatim và @endverbatim sẽ được giữ nguyên trạng, không bị Blade can thiệp hay biên dịch, giúp bạn dễ dàng kết hợp Blade với các SPA/frontend framework khác.

Tuyệt vời! Bạn đã nắm vững cách cân bằng giữa tính năng hiển thị dữ liệu thô và việc bảo mật ứng dụng.

Chúng ta cùng tiến tới Bài 9: Tối ưu hiệu suất với Blade Directives tùy chỉnh (Custom Directives) nhé! Bạn đã sẵn sàng chưa?


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí