CORS là gì? Tìm hiểu về Cross-Origin Resource Sharing trong lập trình web

Trong thế giới lập trình web, bảo mật luôn là một ưu tiên hàng đầu. Khi các ứng dụng web ngày càng phức tạp, việc trao đổi tài nguyên giữa các tên miền khác nhau đã trở thành một nhu-cầu tất yếu. Tuy nhiên, chính sự tương tác này lại mở ra những lỗ hổng bảo mật tiềm ẩn nếu không được kiểm soát chặt chẽ. Chắc hẳn nhiều lập trình viên đã từng gặp phải thông báo lỗi “Cross-Origin Resource Sharing” hay còn gọi là CORS, một vấn đề phổ biến gây không ít khó khăn. Tham khảo thêm về Lỗ hổng bảo mật để hiểu rõ hơn các rủi ro tiềm tàng khi các cơ chế bảo mật không được áp dụng đúng đắn.

Vậy CORS không phải là một lỗi, mà là một cơ chế bảo mật được thiết kế để bảo vệ người dùng. Nó hoạt động như một người gác cổng, cho phép hoặc từ chối các yêu cầu truy cập tài nguyên từ một nguồn (domain) khác. Hiểu rõ về CORS không chỉ giúp bạn giải quyết các vấn đề phát sinh mà còn là chìa khóa để xây dựng những ứng dụng web an toàn và hiệu quả hơn. Bài viết này sẽ cùng bạn tìm hiểu sâu hơn về định nghĩa CORS, cơ chế hoạt động, tầm quan trọng, các vấn đề thường gặp và cách xử lý triệt để.

Hình minh họa

Định nghĩa CORS và thuật ngữ Cross-Origin Resource Sharing

Để làm việc hiệu quả với các công nghệ web, việc nắm vững các khái niệm cốt lõi là vô cùng quan trọng. CORS là một trong những cơ chế mà bất kỳ lập trình viên web nào cũng cần phải hiểu rõ.

CORS là gì?

CORS, viết tắt của Cross-Origin Resource Sharing, là một cơ chế cho phép các tài nguyên trên một trang web (như fonts, JavaScript, API) được yêu cầu từ một tên miền khác với tên miền mà trang web đó đang chạy. Nói một cách đơn giản, đây là một tiêu chuẩn web cho phép các máy chủ nới lỏng chính sách Same-Origin Policy (SOP) một cách có kiểm soát. Bạn có thể đọc chi tiết hơn về Tấn công mạng là gì để thấy vai trò bảo vệ của các cơ chế như CORS trong hệ sinh thái bảo mật mạng.

Mục đích chính của CORS là cho phép các tương tác cross-origin hợp lệ, chẳng hạn như khi một ứng dụng frontend được host trên https://your-app.com cần gọi đến một API đặt tại https://api.your-service.com. Nếu không có CORS, trình duyệt sẽ chặn yêu cầu này ngay lập tức để bảo vệ người dùng khỏi các nguy cơ bảo mật. CORS cung cấp một phương thức an toàn để máy chủ có thể “nói” với trình duyệt rằng: “Tôi cho phép yêu cầu từ tên miền này, hãy tiếp tục xử lý nó.”

Tại sao cần có Cross-Origin Resource Sharing?

Nguồn gốc của CORS xuất phát từ một chính sách bảo mật nền tảng của web: Same-Origin Policy (SOP). Chính sách này quy định rằng một tập lệnh (script) từ một “origin” (nguồn) chỉ có thể yêu cầu tài nguyên từ chính origin đó. Một origin được định nghĩa bởi sự kết hợp của ba yếu tố: giao thức (protocol), tên miền (domain), và cổng (port). Ví dụ, http://buimanhduc.com:80https://buimanhduc.com là hai origin khác nhau.

Chính sách SOP cực kỳ quan trọng trong việc ngăn chặn các trang web độc hại đọc dữ liệu nhạy cảm từ các trang web khác mà bạn đang mở. Ví dụ, nếu không có SOP, một trang web lừa đảo có thể dùng JavaScript để gửi yêu cầu đến website ngân hàng của bạn và đánh cắp thông tin phiên đăng nhập. Tìm hiểu thêm về các phương pháp Xác thực để bảo vệ tài khoản và phiên làm việc một cách hiệu quả.

Tuy nhiên, trong bối cảnh phát triển web hiện đại với kiến trúc microservices hay các ứng dụng trang đơn (SPA), việc gọi API từ các domain khác nhau là điều không thể tránh khỏi. Giới hạn nghiêm ngặt của SOP sẽ cản trở sự phát triển này. Đây chính là lúc Cross-Origin Resource Sharing trở nên cần thiết, nó tạo ra một “lối đi an toàn” để vượt qua rào cản của SOP một cách linh hoạt và bảo mật.

Hình minh họa

Cách hoạt động của CORS trong lập trình web

Hiểu được cách CORS hoạt động dưới “mui xe” sẽ giúp bạn gỡ lỗi và cấu hình hệ thống một cách chính xác. Về cơ bản, CORS hoạt động dựa trên việc trao đổi các HTTP header giữa trình duyệt và máy chủ.

Cơ chế kiểm soát truy cập cross-origin

CORS phân loại các yêu cầu cross-origin thành hai loại chính: yêu cầu đơn giản (simple request) và yêu cầu cần kiểm tra trước (preflight request).

Simple Requests (Yêu cầu đơn giản):
Một yêu cầu được coi là “đơn giản” nếu nó đáp ứng tất cả các điều kiện sau:

  • Phương thức là GET, HEAD, hoặc POST.
  • Các header, ngoài những header được trình duyệt tự động thêm vào, chỉ được phép là Accept, Accept-Language, Content-Language, Content-Type.
  • Giá trị của header Content-Type chỉ có thể là application/x-www-form-urlencoded, multipart/form-data, hoặc text/plain.

Với các yêu cầu đơn giản, trình duyệt sẽ gửi thẳng yêu cầu đến máy chủ, kèm theo một header Origin để chỉ định nguồn của yêu cầu. Máy chủ sau đó sẽ kiểm tra header này và nếu chấp nhận, nó sẽ trả về phản hồi kèm theo header Access-Control-Allow-Origin với giá trị là nguồn được phép hoặc * (cho phép tất cả). Bạn có thể tham khảo thêm về Https và các yếu tố bảo mật để hiểu cơ chế bảo mật liên quan tới giao thức truyền tải.

Preflight Requests (Yêu cầu kiểm tra trước):
Đối với bất kỳ yêu cầu nào không phải là “yêu cầu đơn giản” (ví dụ: sử dụng phương thức PUT, DELETE hoặc có các header tùy chỉnh như Authorization), trình duyệt sẽ tự động gửi một yêu cầu “kiểm tra trước”.

Đây là một yêu cầu OPTIONS được gửi đến URL của tài nguyên trước khi gửi yêu cầu thực tế. Yêu cầu OPTIONS này chứa các header như Origin, Access-Control-Request-Method (phương thức của yêu cầu thực tế) và Access-Control-Request-Headers (các header sẽ được gửi). Máy chủ nhận yêu cầu preflight này và quyết định xem có nên cho phép yêu cầu thực tế hay không. Nếu có, nó sẽ phản hồi với các header Access-Control-Allow-Origin, Access-Control-Allow-Methods, và Access-Control-Allow-Headers.

Quy trình trao đổi dữ liệu qua CORS

Hãy cùng xem một ví dụ minh họa về quy trình của một preflight request để hiểu rõ hơn. Giả sử ứng dụng frontend tại https://my-awesome-app.com muốn gửi một yêu cầu PUT để cập nhật dữ liệu người dùng tới API tại https://api.service.com/users/123.

  1. Gửi Preflight Request:PUT không phải là một phương thức đơn giản, trình duyệt sẽ không gửi yêu cầu PUT ngay. Thay vào đó, nó gửi một yêu cầu OPTIONS tới https://api.service.com/users/123. Yêu cầu này sẽ chứa các header:
    • Origin: https://my-awesome-app.com
    • Access-Control-Request-Method: PUT
    • Access-Control-Request-Headers: Content-Type, Authorization
  2. Máy chủ xử lý Preflight: Máy chủ API nhận yêu cầu OPTIONS. Nó kiểm tra xem nguồn https://my-awesome-app.com có được phép thực hiện yêu cầu PUT với các header Content-TypeAuthorization hay không.
  3. Phản hồi Preflight: Nếu máy chủ cho phép, nó sẽ trả về một phản hồi với mã trạng thái 200 OK và các header CORS:
    • Access-Control-Allow-Origin: https://my-awesome-app.com
    • Access-Control-Allow-Methods: GET, POST, PUT, DELETE
    • Access-Control-Allow-Headers: Content-Type, Authorization
  4. Trình duyệt xác thực và gửi yêu cầu thực tế: Trình duyệt nhận được phản hồi preflight. Nó thấy rằng nguồn, phương thức và các header đều được cho phép. Lúc này, trình duyệt mới tiến hành gửi yêu cầu PUT thực tế đến máy chủ, kèm theo dữ liệu cần cập nhật.
  5. Máy chủ xử lý yêu cầu thực tế: Máy chủ nhận yêu cầu PUT, xử lý nó như bình thường và gửi lại phản hồi cuối cùng cho ứng dụng frontend. Nếu preflight không thành công, trình duyệt sẽ báo lỗi CORS trên console và yêu cầu thực tế sẽ không bao giờ được gửi đi.

Hình minh họa

Tầm quan trọng của CORS trong bảo mật web

CORS không chỉ là một công cụ giúp các ứng dụng web hiện đại hoạt động trơn tru; nó còn là một thành phần quan trọng trong kiến trúc bảo mật của trình duyệt. Việc hiểu và áp dụng đúng CORS giúp bảo vệ cả người dùng và hệ thống của bạn.

Ngăn chặn tấn công giả mạo (CSRF)

Một trong những lợi ích bảo mật của CORS là góp phần ngăn chặn các cuộc tấn công Cross-Site Request Forgery (CSRF). CSRF là kiểu tấn công mà kẻ xấu lừa người dùng đã đăng nhập vào một trang web hợp lệ (ví dụ: my-bank.com) thực hiện một hành động không mong muốn bằng cách truy cập vào một trang web độc hại (evil-site.com). Trang web độc hại này có thể chứa một đoạn mã tự động gửi yêu cầu đến my-bank.com (ví dụ: yêu cầu chuyển tiền). Để hiểu rộng hơn về các loại tấn công qua web, bạn có thể tham khảo bài viết về XSS là gì và cách phòng chống.

Mặc dù chính sách Same-Origin Policy (SOP) là tuyến phòng thủ chính chống lại việc đọc dữ liệu từ các nguồn khác, nó không ngăn chặn việc gửi yêu cầu (fire-and-forget). Tuy nhiên, nếu API của bạn yêu cầu các phương thức phức tạp (như PUT, DELETE) hoặc các header tùy chỉnh (ví dụ: Content-Type: application/json), trình duyệt sẽ kích hoạt cơ chế preflight của CORS.

Khi đó, yêu cầu từ evil-site.com sẽ thất bại ở bước preflight vì máy chủ my-bank.com sẽ không trả về header Access-Control-Allow-Origin: https://evil-site.com. Điều này ngăn chặn yêu cầu độc hại được thực hiện, tăng cường một lớp bảo vệ chống lại CSRF. Bạn cũng có thể tìm hiểu thêm về các phương pháp bảo vệ nâng cao ở bài viết về Firewall là gì.

Hình minh họa

Bảo vệ dữ liệu và quyền truy cập tài nguyên

Tầm quan trọng cốt lõi của CORS nằm ở việc nó trao quyền kiểm soát cho chủ sở hữu tài nguyên (máy chủ). Thay vì trình duyệt mặc định chặn tất cả, CORS cho phép máy chủ định nghĩa một danh sách trắng (whitelist) các nguồn được phép truy cập vào dữ liệu của mình.

Hãy tưởng tượng bạn có một API cung cấp thông tin người dùng nhạy cảm. Nếu không có CORS, bất kỳ trang web nào cũng có thể cố gắng dùng JavaScript để yêu cầu dữ liệu từ API của bạn khi người dùng truy cập chúng. Trình duyệt, nhờ vào Same-Origin Policy, sẽ chặn phản hồi, ngăn không cho mã độc đọc được dữ liệu.

CORS củng cố cơ chế này bằng cách cho phép bạn chỉ định rõ ràng: “Chỉ ứng dụng frontend tại https://my-app.com mới được phép đọc dữ liệu từ API này.” Bất kỳ yêu cầu nào từ một nguồn không xác định hoặc không đáng tin cậy sẽ bị trình duyệt từ chối ngay cả khi yêu cầu đó hợp lệ về mặt kỹ thuật. Điều này đảm bảo rằng dữ liệu của bạn chỉ được chia sẻ với các đối tác và ứng dụng mà bạn tin tưởng, giảm thiểu nguy cơ rò rỉ thông tin và lạm dụng tài nguyên. Để hiểu sâu hơn về các kỹ thuật bảo mật dữ liệu, bạn có thể xem thêm bài viết về Mã hóa là gì.

Các vấn đề thường gặp liên quan đến CORS

Mặc dù là một cơ chế hữu ích, CORS cũng là nguồn gốc của nhiều vấn đề đau đầu cho các lập trình viên, chủ yếu xuất phát từ việc cấu hình sai hoặc hiểu chưa đúng về cách nó hoạt động.

Lỗi phổ biến khi không cấu hình đúng CORS

Thông báo lỗi CORS kinh điển mà hầu hết các nhà phát triển web đều đã từng thấy trong console của trình duyệt là:
Access to XMLHttpRequest at 'https://api.example.com/data' from origin 'https://my-app.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Đây là thông báo rõ ràng nhất cho thấy yêu cầu cross-origin đã bị chặn. Các nguyên nhân phổ biến dẫn đến lỗi này bao gồm:

  • Thiếu header Access-Control-Allow-Origin: Đây là nguyên nhân cơ bản nhất. Máy chủ đích đã không trả về header này trong phản hồi, khiến trình duyệt phải chặn nó theo mặc định.
  • Giá trị Access-Control-Allow-Origin không khớp: Máy chủ có trả về header, nhưng giá trị của nó không khớp với Origin của trang web gửi yêu cầu. Ví dụ, trang của bạn là https://app.domain.com nhưng máy chủ chỉ cho phép https://api.domain.com.
  • Lỗi trong Preflight Request: Đối với các yêu cầu phức tạp, yêu cầu OPTIONS (preflight) có thể đã thất bại. Điều này xảy ra khi phương thức (ví dụ: PATCH) hoặc header tùy chỉnh (ví dụ: X-Custom-Auth) không được cho phép trong các header Access-Control-Allow-Methods hoặc Access-Control-Allow-Headers từ máy chủ.
  • Sử dụng Wildcard * với Credentials: Nếu yêu cầu được gửi kèm theo thông tin xác thực (credentials) như cookies hoặc token xác thực (credentials: 'include'), máy chủ không được phép sử dụng giá trị * cho Access-Control-Allow-Origin. Nó phải chỉ định chính xác nguồn được phép.

Hình minh họa

Hạn chế của CORS trong môi trường lập trình thực tế

Bên cạnh các lỗi cấu hình, CORS cũng có một số hạn chế và thách thức cố hữu mà lập trình viên cần lưu ý:

  • Gỡ lỗi phức tạp: Việc gỡ lỗi CORS đôi khi rất khó khăn, đặc biệt khi liên quan đến chuỗi chuyển hướng (redirects) hoặc các yêu cầu preflight phức tạp. Thông báo lỗi trên trình duyệt không phải lúc nào cũng chỉ rõ nguyên nhân gốc rễ trên máy chủ.
  • Tăng độ trễ: Đối với các yêu cầu không đơn giản, cơ chế preflight thêm một lượt đi-về (round-trip) giữa client và server chỉ để kiểm tra quyền. Mặc dù trình duyệt thường cache kết quả preflight, nó vẫn có thể gây ra độ trễ ban đầu cho các yêu cầu quan trọng.
  • Cấu hình phía máy chủ là bắt buộc: CORS là một cơ chế “opt-in”. Điều này có nghĩa là bạn không thể “ép” một máy chủ của bên thứ ba chấp nhận yêu cầu của mình nếu họ không cấu hình CORS để cho phép nguồn của bạn. Nếu bạn không có quyền kiểm soát máy chủ đích, bạn sẽ phải tìm giải pháp thay thế.
  • Hỗ trợ trình duyệt cũ: Mặc dù hầu hết các trình duyệt hiện đại đều hỗ trợ CORS đầy đủ, một số trình duyệt rất cũ có thể có các triển khai không nhất quán hoặc bị lỗi, gây ra các vấn đề khó lường.

Cách cấu hình và xử lý lỗi CORS trong phát triển web

Khi đã hiểu nguyên nhân gây ra lỗi CORS, việc khắc phục chúng trở nên đơn giản hơn. Giải pháp chính là cấu hình đúng cách trên máy chủ hoặc sử dụng các kỹ thuật thay thế khi cần thiết.

Cấu hình CORS trên server

Cách xử lý triệt để nhất là thiết lập các header CORS cần thiết trên máy chủ nơi chứa tài nguyên bạn muốn truy cập. Dưới đây là ví dụ cấu hình cho một số môi trường server phổ biến.

Node.js (sử dụng Express):
Cách dễ nhất là dùng middleware cors. Đầu tiên, cài đặt nó: npm install cors. Sau đó, sử dụng trong ứng dụng Express của bạn:

const express = require('express'); const cors = require('cors'); const app = express(); // Cho phép tất cả các nguồn (không khuyến khích cho production) // app.use(cors()); // Chỉ cho phép một nguồn cụ thể const corsOptions = { origin: 'https://your-trusted-site.com' }; app.use(cors(corsOptions)); app.get('/api/data', (req, res) => { res.json({ message: 'Đây là dữ liệu được bảo vệ bởi CORS!' }); }); app.listen(3001, () => { console.log('Server đang chạy trên cổng 3001'); });

Hình minh họa

Apache:
Bạn có thể thêm các chỉ thị vào file .htaccess hoặc file cấu hình của virtual host:

<IfModule mod_headers.c> Header set Access-Control-Allow-Origin "https://your-trusted-site.com" Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type, Authorization" </IfModule>

Hình minh họa

Nginx:
Thêm các lệnh add_header vào block server hoặc location trong file cấu hình của Nginx:

location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' 'https://your-trusted-site.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } add_header 'Access-Control-Allow-Origin' 'https://your-trusted-site.com' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;  # ... các cấu hình khác của bạn }

Các giải pháp xử lý lỗi CORS

Trong trường hợp bạn không thể thay đổi cấu hình trên máy chủ đích (ví dụ: khi dùng API của bên thứ ba), có một vài giải pháp thay thế.

Sử dụng Proxy Server:
Đây là giải pháp phổ biến và mạnh mẽ nhất. Thay vì ứng dụng frontend của bạn gọi trực tiếp đến API bên ngoài, nó sẽ gửi yêu cầu đến chính backend của bạn (cùng một origin). Sau đó, backend của bạn sẽ đóng vai trò trung gian (proxy), gọi đến API bên ngoài và chuyển tiếp phản hồi về lại cho frontend.

Vì yêu cầu từ backend đến API bên ngoài là một giao tiếp server-to-server, nó không bị chi phối bởi chính sách Same-Origin Policy của trình duyệt.
Ví dụ luồng hoạt động:

  1. Frontend (my-app.com) gửi yêu cầu đến my-app.com/api-proxy/data.
  2. Backend của bạn nhận yêu cầu này.
  3. Backend gửi một yêu cầu mới đến API thực tế external-api.com/data.
  4. external-api.com trả về dữ liệu cho backend của bạn.
  5. Backend của bạn chuyển tiếp dữ liệu này về cho frontend.

Đối với trình duyệt, đây chỉ là một yêu cầu same-origin thông thường và không có lỗi CORS nào xảy ra.

Hình minh họa

JSONP (JSON with Padding):
Đây là một kỹ thuật cũ hơn, hoạt động bằng cách lợi dụng việc thẻ <script> không bị giới hạn bởi SOP. JSONP chỉ hoạt động với các yêu cầu GET và ngày nay ít được sử dụng do các rủi ro bảo mật và sự phổ biến của CORS. Nó được đề cập ở đây chủ yếu vì lý do lịch sử, và CORS luôn là lựa chọn ưu tiên hàng đầu.

Best Practices

Để làm việc với CORS một cách hiệu quả và an toàn, hãy luôn tuân thủ các nguyên tắc tốt nhất sau đây. Việc áp dụng chúng sẽ giúp bạn tránh được các lỗi phổ biến và bảo vệ ứng dụng của mình khỏi các lỗ hổng bảo mật.

  • Khai báo rõ ràng các nguồn được phép: Luôn ưu tiên chỉ định một danh sách trắng các tên miền cụ thể trong header Access-Control-Allow-Origin. Ví dụ: Access-Control-Allow-Origin: https://buiducmanh.com. Điều này đảm bảo chỉ những trang web bạn tin tưởng mới có thể truy cập tài nguyên.
  • Tránh dùng wildcard * trong môi trường production: Việc đặt Access-Control-Allow-Origin: * sẽ cho phép bất kỳ trang web nào trên Internet truy cập vào tài nguyên của bạn. Mặc dù tiện lợi cho việc phát triển, đây là một rủi ro bảo mật lớn trong môi trường thực tế. Đặc biệt, nó không tương thích với các yêu cầu cần gửi thông tin xác thực (credentials).
  • Chỉ mở rộng CORS với các domain tin cậy: Trước khi thêm một domain vào danh sách cho phép, hãy chắc chắn rằng bạn hiểu rõ domain đó là gì và tại sao nó cần truy cập vào tài nguyên của bạn. Mỗi domain được thêm vào là một cánh cửa tiềm năng vào hệ thống của bạn.
  • Hạn chế các phương thức và header không cần thiết: Khi cấu hình Access-Control-Allow-MethodsAccess-Control-Allow-Headers, chỉ liệt kê những phương thức và header thực sự cần thiết cho ứng dụng của bạn hoạt động. Đừng mở tất cả chỉ vì sự tiện lợi.
  • Xử lý yêu cầu Preflight một cách cẩn thận: Đảm bảo máy chủ của bạn phản hồi chính xác cho các yêu cầu OPTIONS. Việc cấu hình sai ở bước này là một trong những nguyên nhân phổ biến nhất gây ra lỗi CORS đối với các yêu cầu phức tạp.
  • Kiểm tra và giám sát lỗi CORS: Tích hợp việc kiểm tra cấu hình CORS vào quy trình CI/CD của bạn. Sử dụng các công cụ giám sát lỗi ở phía client để phát hiện sớm các vấn đề liên quan đến CORS khi ứng dụng đang hoạt động, giúp bạn khắc phục kịp thời trước khi ảnh hưởng đến người dùng.

Hình minh họa

Conclusion

Qua bài viết này, hy vọng bạn đã có một cái nhìn toàn diện và sâu sắc hơn về CORS. Nó không phải là một “lỗi” phiền phức, mà là một cơ chế bảo mật thiết yếu được thiết kế để bảo vệ cả người dùng và tài nguyên trên web. CORS chính là cây cầu nối an toàn, cho phép các ứng dụng web hiện đại, phân tán có thể giao tiếp với nhau một cách linh hoạt mà không hy sinh tính bảo mật.

Việc nắm vững cách CORS hoạt động, từ các loại yêu cầu, quy trình preflight cho đến các HTTP header liên quan, là một kỹ năng quan trọng đối với bất kỳ lập trình viên web nào. Nó giúp bạn không chỉ giải quyết các vấn đề phát sinh một cách nhanh chóng mà còn xây dựng các hệ thống mạnh mẽ, an toàn và có khả năng mở rộng. Thay vì tìm cách “tắt” CORS một cách mù quáng, hãy coi nó như một người đồng minh trong hành trình phát triển web.

Thế giới bảo mật web luôn rộng lớn và không ngừng phát triển. Bùi Mạnh Đức khuyến khích bạn tiếp tục tìm hiểu sâu hơn về các chủ đề liên quan như Content Security Policy (CSP), Cross-Site Scripting (XSS) và các kỹ thuật khác để nâng cao kỹ năng, tạo ra những sản phẩm số ngày càng chất lượng và an toàn hơn.

Hình minh họa

Đánh giá
Tác giả

Mạnh Đức

Có cao nhân từng nói rằng: "Kiến thức trên thế giới này đầy rẫy trên internet. Tôi chỉ là người lao công cần mẫn đem nó tới cho người cần mà thôi !"

Chia sẻ
Bài viết liên quan