Lỗ hổng path traversal trên GitLab cho phép đọc file trái phép mà không cần xác thực

Vừa qua, GitLab đã phát hành bản vá khẩn cấp cho lỗ hổng path traversal tối đa nghiêm trọng CVE-2026-85706 trong Repository Commits API của GitLab Community Edition và Enterprise Edition. Lỗ hổng cho phép kẻ tấn công không cần xác thực đọc bất kỳ file nào trên GitLab server chỉ bằng một HTTP request duy nhất, bao gồm file cấu hình chứa toàn bộ secret, credential, và cryptographic key của hệ thống. Đây là lỗ hổng GitLab nghiêm trọng thứ hai chỉ trong vài tuần, tiếp nối CVE-2026-19478 (GraphQL code injection) cũng bị khai thác gần như ngay lập tức sau khi được công bố, cho thấy threat actor đã có sẵn công cụ nhắm vào GitLab khi CVE-2026-85706 được disclosure.
Thông tin chi tiết
CVE-2026-85706 — GitLab Repository Commits API Unauthenticated Arbitrary File Read
Định danh lỗ hổng: CVE-2026-85706
Điểm CVSS(3.1): 10.0
Mức độ nghiêm trọng: CRITICAL – Cực kỳ nghiêm trọng (điểm tuyệt đối)
Mô tả: CVE-2026-85706 là lỗ hổng kết hợp hai lỗi trong Repository Commits API của GitLab CE/EE: path traversal không đúng cách (CWE-22) và thiếu kiểm tra xác thực (missing authentication). Lỗ hổng bắt nguồn từ lỗi thứ tự thực thi trong Rails handler: hàm
File.open(params['file.path'])được gọi để đọc file từ đường dẫn do người dùng cung cấp trước khiauthenticate!được thực thi. Tham sốfile.pathđược lấy trực tiếp từ request mà không có kiểm tra hay làm sạch nào, kẻ tấn công có thể đặt bất kỳ đường dẫn tuyệt đối nào (ví dụ:/etc/gitlab/gitlab.rb) và server sẽ đọc file đó, trả nội dung trong HTTP response trước khi nhận ra người dùng chưa xác thực. Điều kiện duy nhất để khai thác là GitLab instance phải có ít nhất một public project, một điều kiện cực kỳ phổ biến trong môi trường thực tế. Kẻ tấn công không cần tài khoản, không cần session, không cần bất kỳ tương tác người dùng nào. Một HTTP POST request duy nhất là đủ để đọc bất kỳ file nào trên server mà GitLab service account có quyền đọc.Phiên bản bị ảnh hưởng:
| Branch | Phiên bản bị ảnh hưởng |
|---|---|
| GitLab CE/EE 18.x | 18.7 đến trước 19.1.8 |
| GitLab CE/EE 19.2 | 19.2 đến trước 19.2.6 |
| GitLab CE/EE 19.3 | 19.3 đến trước 19.3.2 |
Bản vá phát hành: GitLab CE/EE 19.1.8, 19.2.6, 19.3.2 (10/09/2026)
Lưu ý: GitLab.com (SaaS) không bị ảnh hưởng. Chỉ ảnh hưởng đến self-managed GitLab CE/EE.
CVE-2026-87719 — GitLab EE Insecure Deserialization (GraphQL Subscription Serializer)
Định danh lỗ hổng: CVE-2026-87719
Điểm CVSS(3.1): 9.9
Mức độ nghiêm trọng: CRITICAL – Cực kỳ nghiêm trọng
Mô tả: Lỗ hổng insecure deserialization trong GraphQL subscription serializer của GitLab Enterprise Edition, có thể làm lộ cấu hình Advanced Search và credential thông qua tính năng Duo Chat. Chỉ ảnh hưởng đến phiên bản Enterprise Edition; được vá trong cùng đợt phát hành 19.1.8, 19.2.6, 19.3.2.
GitLab là nền tảng DevSecOps phổ biến hàng đầu thế giới, tích hợp source code management, CI/CD pipeline, container registry, package registry, security scanning, và project management trong một nền tảng duy nhất. Hàng trăm nghìn tổ chức trên toàn cầu self-host GitLab CE/EE làm trung tâm phát triển phần mềm nội bộ, lưu trữ toàn bộ source code, pipeline configuration, deployment secret, và infrastructure credential của họ. GitLab server thực sự là một trong những hệ thống có mật độ secret cao nhất trong kiến trúc enterprise, mọi project đều có thể chứa API key, database password, cloud credential, và private key được nhúng trực tiếp hoặc lưu trong CI/CD variables.
CVE-2026-85706 nguy hiểm không phải vì nó cho phép ghi hay thực thi mã, mà vì những gì có thể bị đọc. Trên một GitLab server điển hình, một đường dẫn tuyệt đối duy nhất như /etc/gitlab/gitlab.rb chứa toàn bộ cấu hình GitLab: database connection string với password, SMTP credential, object storage credential (S3, GCS), LDAP bind password, OAuth client secret, JWT signing key, và nhiều hơn nữa. File /etc/gitlab/gitlab-secrets.json chứa cryptographic root keys, bao gồm root encryption key, OTP key base, và DB key base. Với những secret này trong tay, kẻ tấn công không cần thêm bất kỳ CVE nào khác: họ có thể giải mã toàn bộ dữ liệu được mã hóa trong database, forge authentication token để mạo danh bất kỳ user nào kể cả admin, và truy cập toàn bộ private repository.
Lỗ hổng bắt nguồn từ một lỗi thứ tự code cổ điển: authentication check được đặt sau file read operation thay vì trước. Trong Rails framework, đây là loại lỗi tinh tế nhưng có hậu quả nghiêm trọng, developer viết handler xử lý file upload và đặt authentication trong middleware chain, nhưng không nhận ra rằng file read xảy ra ở bước early trong chain trước khi middleware authentication chạy. Bản vá fix bằng cách đơn giản là di chuyển authentication check lên trước file_params_from_body_upload trong tất cả ba endpoint bị ảnh hưởng, một thay đổi nhỏ nhưng tốn kém.
Thời gian từ patch đến exploitation chỉ vài giờ là dấu hiệu rõ ràng: threat actor đã có tooling nhắm vào GitLab sẵn sàng từ CVE-2026-19478 trước đó. Khi bản vá được phát hành, diff analysis cho phép tái tạo lỗ hổng gần như tức thì. Đây cũng là lỗ hổng path traversal CVSS 10.0 thứ hai trong GitLab trong vòng ba năm, cho thấy API endpoint xử lý file path là attack surface cần được audit thường xuyên hơn.
Tổng quát quá trình khai thác CVE-2026-85706
Quá trình khai thác có thể được chia thành các giai đoạn sau:
Thu thập thông tin (Reconnaissance)
Mục tiêu: xác định các self-managed GitLab CE/EE instance internet-facing chưa vá, có ít nhất một public project.
Hành động: kẻ tấn công quét Internet tìm GitLab instance qua fingerprint HTTP header, trang login, hoặc API
/api/v4/version. Kiểm tra xem có public project nào tồn tại, đây là điều kiện cần duy nhất để khai thác. Xác nhận phiên bản GitLab chưa được vá lên 19.1.8, 19.2.6, hoặc 19.3.2.
Gửi một HTTP Request duy nhất (Exploitation)
- Kẻ tấn công gửi HTTP POST request tới Repository Commits API endpoint của GitLab không cần bất kỳ authentication header nào:
POST /[owner]/[public-repo]/-/commits HTTP/1.1
Content-Type: application/x-www-form-urlencoded
file=&file.path=/etc/gitlab/gitlab.rb&file.size=1
Rails handler xử lý
file.pathparameter, gọiFile.open('/etc/gitlab/gitlab.rb')và đọc toàn bộ nội dung file.Nội dung file được trả về trong HTTP response, trước khi authentication check chạy.
Thu thập Secret và Credential (Data Harvesting)
Từ
/etc/gitlab/gitlab.rb: database password, SMTP credential, LDAP bind password, OAuth secret, S3/object storage credential, JWT signing key.Từ
/etc/gitlab/gitlab-secrets.json: root encryption key, OTP key base, DB key base.Từ các vị trí khác:
/home/git/.ssh/id_rsa(SSH private key), CI/CD variable files được materialize trên disk, Redis configuration, SSL certificate private key.
Leo thang từ File Read sang Full Compromise (Escalation)
Với root encryption key và DB key base, kẻ tấn công giải mã toàn bộ dữ liệu sensitive trong GitLab database.
Forge session token hoặc personal access token để đăng nhập với quyền admin, không cần password hay 2FA.
Với quyền admin GitLab, đọc toàn bộ private repository trên instance, bao gồm source code, CI/CD pipeline, Terraform state, Kubernetes manifest, và deployment config.
Hậu khai thác (Post-Exploitation)
Đánh cắp toàn bộ source code private của tổ chức.
Inject backdoor vào CI/CD pipeline để lan rộng vào production environment (supply chain attack).
Sử dụng cloud credential thu thập được (AWS/GCP/Azure) để truy cập cloud infrastructure.
Đọc SSH deploy key để truy cập các server deploy trong CI/CD pipeline.
Lấy database credential để truy cập trực tiếp production database của tổ chức.
Khuyến nghị & Khắc phục
GitLab đã phát hành bản vá và CISA đã đưa CVE-2026-85706 vào danh sách KEV với deadline 14/09/2026. Đội ngũ FPT Threat Intelligence khuyến nghị người dùng và quản trị viên cần cân nhắc thực hiện ngay các hành động sau:
Cập nhật bản vá khẩn cấp: nâng cấp ngay GitLab CE/EE self-managed lên phiên bản 19.3.2, 19.2.6, hoặc 19.1.8 tùy theo branch đang sử dụng. GitLab.com không bị ảnh hưởng và không cần hành động từ phía người dùng SaaS.
Treat mọi instance internet-facing chưa vá là đã bị đọc: bất kỳ GitLab instance nào có public project, truy cập được từ Internet, và chưa vá trước ngày 11/09/2026 phải được coi là có khả năng đã bị khai thác. Việc vá lỗ hổng không thu hồi được thông tin đã bị đọc trước đó.
Rotate toàn bộ secret ngay lập tức (nếu có khả năng bị ảnh hưởng): đây là bước quan trọng nhất, thực hiện song song với việc vá:
Regenerate
gitlab_rails['secret_key_base'],gitlab_rails['otp_key_base'], vàgitlab_rails['db_key_base']trong gitlab.rb, sau đó chạygitlab-ctl reconfigure.Đổi database password.
Rotate tất cả OAuth application secret.
Regenerate LDAP/SAML credential và API integration key.
Revoke và tái tạo tất cả SSH deploy key.
Rotate AWS/GCP/Azure credential nếu được lưu trong GitLab CI/CD variables hoặc gitlab.rb.
Reset tất cả personal access token và project access token của tất cả user.
Rà soát access log: kiểm tra GitLab production log tại
/var/log/gitlab/nginx/gitlab_access.logtìm các POST request tới Commits API endpoint (/-/commits) vớifile.pathparameter từ IP không nhận dạng, đặc biệt trong khoảng thời gian 10/09–ngày vá.Kiểm tra public project: rà soát lại danh sách project public trên instance. Nếu không có nhu cầu, đặt instance về Internal hoặc Private visibility để loại bỏ điều kiện tiên quyết của lỗ hổng, đây cũng là biện pháp defense-in-depth cho các lỗ hổng tương tự trong tương lai.
Vá CVE-2026-87719 cùng lúc: phiên bản vá 19.1.8/19.2.6/19.3.2 cũng giải quyết CVE-2026-87719 (CVSS 9.9, insecure deserialization trong GitLab EE) và CVE-2026-88765 (CVSS 8.5, buffer overflow trong Unicode conversion dẫn đến RCE qua crafted Git export). Một lần upgrade xử lý cả ba lỗ hổng.
Giám sát CI/CD pipeline: nếu có khả năng credential đã bị lộ, rà soát toàn bộ CI/CD pipeline log để phát hiện thay đổi bất thường trong pipeline definition, execution từ IP/runner không nhận dạng, hoặc deployment bất thường đến production.
Tham khảo





