Tags:

CORS là gì? Tại sao nó quan trọng trong ứng dụng web

Các trang web hiện đại mà bạn đang truy cập hằng ngày cần phải request rất nhiều nội dung như image, font, html, css và nhiều thứ khác từ các nguồn khác nhau trên internet. Nếu những request này được gửi đi cách tự do thì nó có thể gây ra các lỗ hỏng bảo mật nghiêm trọng cho trình duyệt của bạn.

Ví dụ bạn đang mở 2 tab, một tab vào internet banking của ngân hàng, và một tab mở một trang web xyz.com, nếu trang web xyz.com này chứa mã độc thì nó có thể sử dụng tài nguyên của tab internet banking để thực hiện các hành vi chiếm đoạt tài khoản.

Để giúp chặn lỗ hỏng bảo mật như thế này, trình duyệt có một cơ chế bảo mật gọi là same-origin policy mà chúng ta sẽ tìm hiểu ngay sau đây.

Same Origin Policy

Same-origin policy là một security concept quan trọng được hiện thực trên các loại trình duyệt nhằm ngăn chặn HTTP Request không an toàn đến những nguồn khác. Ví dụ từ một domainA mà lại request đến domainB sẽ bị chặn vì domainA đang cố gắng truy cập tài nguyên từ một nguồn khác. Same-origin policy chỉ ra rằng từ một domain chúng ta chỉ được truy cập đến các tài nguyên trong cùng domain đó. Các tài nguyên thuộc cùng một domain thì chúng phải giống nhau từ protocol, host và port.

Giả sử chúng ta đang sử dụng trình duyệt để truy cập và một trang web có đường dẫn

http://www.example.com/foo-bar.html

Gọi nó là URL1.

Nếu trang web tại URL1 request đến server http://www.example.com/imageA.jpg để tải một hình ảnh xuống thì request này được xem là hợp lệ vì chúng có cùng protocol, Host và Port. 

Note: Các bạn lưu ý rằng mỗi trang web thật chất bên dưới được cấu hình bởi protocol, host, port, tuy nhiên để thân thiện với người dùng nên các trang web thường dùng domain(tên miền) để thay thế. Trong trường hợp trên, domain giống nhau là cấu trúc của nó về Protocol, Host, port là hoàn toàn giống nhau.

Tuy nhiên, nếu tại URL1 mà chúng ta request đến https://www.en.example.com/imageB.jpg thì sẽ bị trình duyệt ngăn chặn vì chúng khác Protocol(HTTPS) và Host(en.example.com).

Same-Origin có lẽ là một cơ chế bảo mật tốt, tuy nhiên có những trường hợp một domain có thể request đến các domain khác được cho là an toàn, có thể là domain đó public cho tất cả các các domain khác trên internet, hoặc đơn giản nó là một REST API được dùng cho nhiều client khác nhau trong cùng một hệ thống. May mắn thay chúng ta có một cơ chế gọi là CORS cho phép chia sẽ tài nguyên giữ các domain với nhau sẽ được trình bày ở phần sau.

CORS là gì?

Một request được thực hiện từ một domain đến một domain khác được gọi là cross-origin request. CORS(cross-origin resource sharing) là một cơ chế cho phép quản lý các cross-origin request.

Quay trở lại với URL1 ở phần trước.

http://www.example.com/foo-bar.html

Nếu từ URL1, request đến server https://www.ejemplo.com/imageB.jpg sẽ được cho phép với CORS. Để làm được điều này, server phải là nơi triển khai mã xử lý cho các request đến từ các domain khác nhau. CORS cho phép server chỉ định rõ những domain nào có thể truy cập các tài nguyên của server.

Tại sao cần CORS?

Sau khi đã tìm hiểu về CORS, có thể chúng ta vẫn băng khăng không biết nên sử dụng nó trong trường hợp này. Trong phần này chúng ta sẽ xem một số trường hợp sử dụng phổ biến của CORS.

Những request từ một domain đến một domain khác được gọi là cross-origin request. Trong thực tế cross-origin request là các HTTP request method như GET, POST, PUT, DELETE, PATH, OPTIONS. Thông thường chúng ta phát triển một API có thể dùng cho các trang web trong hệ thống giả sử là trang web A, và B. Thì lúc này chúng ta có thể cấu hình CORS cho API chỉ chấp nhận các request từ A và B, những request đến từ các nguồn khác sẽ bị từ chối. Hoặc là chúng ta phát triển một nền tảng cho phép upload và download miễn khí, công khai thì có thể cấu hình CORS cho phép tất cả các domain khác có thể truy cập.

CORS quản lý các request như thế nào?

HTTP Header là một phần thông tin được đính kèm trong một request hoặc một response. CORS quản lý các cross-origin request bằng cách thêm một số HTTP Header vào danh sách các HTTP Header sẵn có trong response trả về. 

Dưới đây là danh sách các HTTP Header có thể được thêm bởi CORS:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Method
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Origin

Tất cả các thuộc tính trên đều quan trọng và có một ý nghĩa riêng, tuy nhiên chúng ta cần chú ý đến 

  • Access-Control-Allow-Origin

Access-Control-Allow-Origin Header cho phép server chỉ định các domain khác có thể truy cập vào tài nguyên của nó.

Use case: Khi có một GET request từ trình duyệt đến Server. Server sẽ trả lời với một giá trị đính kèm với Access-Control-Allow-Origin Header trong response mà nó trả về cho trình duyệt.

Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: <domain>
Access-Control-Allow-Origin: null

Thông thường nếu Access-Control-Allow-Origin có giá trị là * nghĩa là tất cả các domain có thể truy cập vào server. Hoặc chúng ta có thể đặt giá trị cho header này là một domain hoặc một danh sách các domain cụ thể được server cho phép.

Lưu ý tằng chỉ duy nhất một domain được chỉ định trong Access-Control-Allow-Origin, vì thế nếu ứng dụng của bạn hỗ trợ cho nhiều client khác nhau thì nó phải xử lý các request với các domain tương ứng.

Access-Control-Allow-Origin: null thường không được khuyến khích sử dụng vì lý do bảo mật. Khi server trả về Access-Control-Allow-Origin: “null”, kể xấu có thể mạo danh domain URL tương tự “null” có có thể truy cập vào. Cách tốt nhất là không đính kèm Access-Control-Allow-Origin khi chúng ta không muốn chia sẽ tài nguyên cho bất kỳ một domain nào.

Một số CORS header quan trọng khác dùng để hỗ trợ thêm các thông tin như:

  • Access-Control-Allow-Methods: mô tả những method nào client có thể gửi đi.
  • Access-Control-Max-Age: mô tả thời gian hợp lệ của preflight request , nếu quá hạn, browser sẽ tự tạo một preflight request mới.

Preflight Requests

Trước khi một origin HTTP request được gửi lên server để tải các tài nguyên thì một HTTP request khác được gọi là preflight request sẽ được request trước khi HTTP request ban đầu gửi đến server

Preflight request sử dụng OPTIONS method để gửi lên server với mục đích kiểm tra xem liệu origin HTTP request có được phép truy cập server hay không. Nếu server trả lời preflight là original request an toàn, origin request sẽ được thực thi, ngược lại nó sẽ chặn original request.

Ngoài những HTTP request được gửi lên server sẽ kích hoạt preflight request thì nếu có bất kỳ một giá trị nào của header bị chỉnh sửa bởi trình duyệt thì preflight request cũng sẽ được thực thi.

Triển khai CORS

Việc triển khai CORS phụ thuộc vào ngôn ngữ, framework mà các bạn đang sử dụng. Cho ví dụ như bạn đang sử dụng NodeJS và Express Framework

var express = require('express');
var cors = require('cors');
var app = express();
 
app.use(cors());
 
app.get('/hello/:id', function (req, res, next) {
  res.json({msg: 'Hello world, we are CORS-enabled!'});
});
 
app.listen(80, function () {
  console.log('CORS-enabled web server is listening on port 80');
});

Kết bài

Chúng ta có rất nhiều giải pháp cho việc chia sẽ tài nguyên trong các ứng dụng web, tuy nhiên chúng vẫn dựa trên những khái niệm cơ bản này. Bằng cách hiểu được cơ chế CORS, chúng ta có thể dễ dàng tiếp cận các công nghệ mới.

Nguồn tham khảo

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

https://www.codecademy.com/articles/what-is-cors

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x