Giải ngố API – Phần 5: Những điều cần biết trước khi sờ mó vào GraphQL

Tiếp theo nội dung Giải ngố API – Phần 4: Ngắn gọn thì GraphQL hoạt động kiểu gì?, kỳ này tôi sẽ giới thiệu tiếp các vấn đề quan trọng cần lưu ý trước khi đụng chạm với đối tượng GraphQL.

#1. Chuẩn bị đồ nghề phục vụ demo minh họa

Để hỗ trợ demo minh họa cho đám lý thuyết chán ngán bên dưới, tôi nhận thấy cần chuẩn bị một số đồ nghề hỗ trợ. Vì mục tiêu chính là để minh họa cho các khái niệm liên quan của GraphQL nên phần này tôi sẽ ngắn gọn hết mức có thể chứ không sa đà giới thiệu chi tiết. Các nội dung liên quan tôi sẽ nghiên cứu giới thiệu sau.

#1.1 Dựng GraphQL Server với Damn Vulnerable GraphQL Application

Đầu tiên, hiển nhiên tôi phải có một cái GraphQL server để tương tác thử nghiệm. Về phần này, tôi có 2 lựa chọn:

  • #1: Tìm xem thiên hạ có ai tốt bụng dựng sẵn GraphQL server cho tôi thử nghiệm chùa hay không;
  • #2: Tự dựng GraphQL server rồi “tự ăn”.

Với phong cách ưa chuộng các pha xử lý cồng kềnh như thường lệ, tôi sẽ chọn phương án #2. Và để phục vụ phương án #2 cũng như các nội dung demo dự kiến trong các kỳ sau, tôi sẽ sử dụng một mục tiêu giả lập phổ biến là Damn Vulnerable GraphQL Application.

Damn Vulnerable GraphQL Application
Damn Vulnerable GraphQL Application

Lưu ý:

  • Damn Vulnerable GraphQL Application có khá nhiều thứ hay ho nên tôi sẽ quay lại bàn chi tiết về đối tượng này sau;
  • Tôi sẽ sử dụng docker để dựng con hàng Damn Vulnerable GraphQL Application cho nhanh gọn;
  • Như tôi nói trên, bài này không phải tập trung demo dựng GraphQL lab nên tôi sẽ không đi sâu vào chi tiết. Có thể tôi sẽ giới thiệu thêm về docker trong một nội dung khác.

Rồi, sau khi đã cài cắm và thiết lập docker ngon lành, tôi sẽ ngay lập tức tung ra combo các command sau đây để build docker imagestart Damn Vulnerable GraphQL Application container:

  • git clone https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application.git
  • cd Damn-Vulnerable-GraphQL-Application
  • sudo docker build -t dvga .
  • sudo docker run -t --rm -d --name dvga -p 5013:5013 -e WEB_HOST=0.0.0.0 dvga
Start Damn Vulnerable GraphQL Application container
Start Damn Vulnerable GraphQL Application container

Nếu bạn nhìn thấy kết quả chạy sudo docker ps giống ở như trên là ngon. Lúc này, để xem thành quả lao động, bạn có thể mở http://localhost:5013/ lên thử.

Damn Vulnerable GraphQL Application interface
Damn Vulnerable GraphQL Application interface

#1.2 Cài cắm GraphQL client Altair

Để thuận tiện trong việc dạo đầu với GraphQL, tôi sẽ cần một phương án GraphQL client thân thiện với người dùng. Bạn có thể chọn tùy thuộc khẩu vị mặn nhạt của mình nhưng ở đây tôi sẽ quất cái Firefox add-ons Altair GraphQL Client cho nhanh.

Firefox add-ons Altair GraphQL Client
Firefox add-ons Altair GraphQL Client

Lưu ý: Bạn có thể xem thêm thông tin tại link Altair GraphQL Client, nếu cần.

Sau khi trải qua quá trình cài cắm nhạt nhẽo bạn có thể click chọn vào biểu tượng của Altair add-ons để mở cái http://localhost:5013/graphql như sau.

GraphQL client Altair interface
GraphQL client Altair interface

Đến đây coi như tôi đã chuẩn bị xong các yêu cầu cần thiết để phục vụ việc demo làm rõ phần lý thuyết bên dưới.

#2. Quyền lực tột đỉnh với GraphQL Introspection query

Về cơ bản, việc thực thi thành công Introspection query trong GraphQL tương đương với việc nắm REST API Swagger (OpenAPI) definition file. Tức là tôi gần như có thể nắm hết toàn bộ thông tin về GraphQL service.

Cụ thể, Introspection cho phép client query GraphQL server để lấy thông tin về schema bao gồm các dạng data như queries, mutations, subscriptions, directives, types, fields, vân vân. Các thể loại Introspection phổ biến bao gồm:

  • __schema: Cung cấp tất cả thông tin về schema của GraphQL service;
  • __type: Cung cấp tất cả thông tin về một type cụ thể;
  • __TypeKind: Cung các các dạng type khác nhau như scalars, objects, interface, union, enum,…
  • __Field: Cung cấp tất cả thông tin cho mỗi field của một object/interface type;
  • __InputValue: Cung cấp thông tin fielddiretive argument;
  • __EnumValue: Cung cấp một trong các giá trị có thể chọn của 1 enum;
  • __Directive: Cung cấp tất cả thông tin của các custom hoặc builtin directive.

Vâng, tôi biết bạn đang chán ngán với đám lý thuyết này. Để thay đổi không khí, tôi sẽ xúc ngay một cái ví dụ query __Schema Introspection như sau để demo hốt tên của đám types từ schema của một GraphQL service. Để làm việc này, tôi sẽ quất cái query bên dưới vô giao diện của GraphQL client Altair đã cài cắm ở phần đầu.

query {

     __schema {

     types{

     name

}

}

}

Schema Introspection
Schema Introspection

Sau khi nhập thông tin và click Send query, tôi thấy server phun ra response với cả tấn thông tin liên quan đến đám types name.

Với đám name thu thập được, tôi có thể dựng tiếp một query với  __type Introspection để xem chi tiết, ví dụ với cái PasteObject theo kiểu như sau.

query {

     __type(name: "PasteObject") {

     name

     kind

     fields {

     name

     type {

     name

     kind

}

}

}

}

type Introspection
type Introspection

Tương tự như trên, sau khi nhập query và click chọn Send query trên GraphQL client Altair , server nó phụt ra toàn bộ những thông tin liên quan đến đối tượng tôi đang quan tâm (tức là cái PasteObject. với đám thông tin name, kind, fields).

Hy vọng với phần demo mì ăn liền này, tôi đã giúp bạn hình dung sơ bộ ra “mặt mũi” của cái GraphQL Introspection query cũng như mức độ công lực của nó.

Lưu ý: Tôi thấy cần phải nói ngay là thực tế thì không phải lúc nào bạn cũng được phép chạy Instropection tẹt ga như trên mà việc này tùy thuộc vào việc triển khai GraphQL cụ thể như phần trình bày sau đây.

#3. Làm sao để không vỡ mồm với implementation flaws của GraphQL

Implementation flaw (tạm dịch là sai sót trong việc triển khai) so với các specifications (tạm dịch là đặc tính) cụ thể của GraphQL là một vấn đề nhức nhói (thật ra cái này cả tỷ thứ khác cũng đều bị chứ không phải chỉ mỗi GraphQL).

Cơ bản đây là phần “chênh lệch” giữa ý tưởng thiết kế với các specifications siêu cấp vô địch và thực tế nghiệt ngã là mấy ông phụ trách không hiểu rõ specifications (hoặc hiểu rõ nhưng gì lí do gì đó vẫn không tuân thủ các chỉ dẫn) trong quá trình thực thi.

May mắn thay cho mấy ông triển khai và bảo vệ hệ thống, hiện tại đã có một phương án trợ giúp để hạn chế Implementation flawGraphQL Threat Matrix (nicholasaleks/graphql-threat-matrix: GraphQL threat framework used by security professionals to research security gaps in GraphQL implementations (github.com)).

GraphQL Threat Matrix
GraphQL Threat Matrix

Về cơ bản, GraphQL Threat Matrix sẽ hỗ trợ phân tích, theo dõi và so sánh các phương thức triển khai phổ biến (ví dụ Apollo hay graphene), kiểm tra supported validations, default security configurations, featuresnotable vulnerabilities từ đó hạn chế bớt các sai lầm trong quá trình triển khai.

Lưu ý:

  • GraphQL Threat Matrix hỗ trợ cho mấy ông bảo vệ hệ thống hạn chế bớt các sai lầm trong quá trình triển khai nhưng cũng sẽ đồng thời hỗ trợ cho các ông đang lăm le đâm thọt vào các lỗ hổng;
  • Các thông tin liên kết trong GraphQL Threat Matrix rất thú vị nên tôi sẽ quay lại giới thiệu kỹ về chỗ này sau (lại hứa hẹn?!).

 

#4. Và rồi GraphQL còn thường gặp vấn đề gì nữa?

Như lẽ thường, cái gì cũng có 2 mặt của nó nên bên cạnh các “lợi thế cạnh tranh” trình bày trong kỳ trước, GraphQL chắc chắn cũng tồn tại các vấn đề. Ngoài cái vụ Implementation flaw tôi vừa đề cập ở trên, GraphQL cũng sẽ bị các vấn đề thường gặp khác của thiên hạ như:

  • Vấn đề Denial of Service (tạm dịch là từ chối dịch vụ);
  • Vấn đề Information Disclosure (rò rỉ thông tin);

Ngoài ra, cũng sẽ gặp các vấn đề tương tự như các API truyền thống (ví dụ như RESTful API):

  • Vấn đề lỗi trong quá trình Authentication & Authorization (xác thực và phân quyền);
  • Vấn đề với Injection (các thể loại chích choách).

Tôi sẽ sắp xếp để lần lượt bàn chi tiết về các vấn đề này khi xem xét cụ thể đặc tính của GraphQL trong các kỳ tiếp theo.

Leave a Reply

Your email address will not be published. Required fields are marked *