Cách phòng tránh Supply Chain attack trên NPM

tuantran

Moderator
Thành viên BQT
27/04/2017
29
76 bài viết
Cách phòng tránh Supply Chain attack trên NPM
Tấn công chuỗi cung ứng (supply chain attack) được coi là một xu hướng của tin tặc ngày nay. Nếu chúng ta không có những biện pháp để ngăn ngừa cách thức tấn công này thì hậu quả để lại sẽ rất nghiêm trọng. Trong bài viết này, tôi tham khảo bài viết của tác giả Isaac Z. Schlueter giới thiệu cho các bạn cách quản lý các package cẩn thận khi sử dụng npm.

upload_2021-6-16_13-58-21.png

Nếu các bạn chưa biết về NPM thì có thể tham khảo ở đây: https://topdev.vn/blog/npm-la-gi/

Bài viết này chủ yếu tập trung trên npm, nếu bạn muốn tìm hiểu nhiều hơn về cách phòng chống cho những package khác. Thì bạn có thể tham khảo ở đây: https://azure.microsoft.com/en-us/resources/3-ways-to-mitigate-risk-using-private-package-feeds/

Dưới đây là những cách giúp bạn có thể tránh được supply chain attack.

  1. Dùng Scope cho package nội bộ
  2. Dùng file .npmrc trong thư mục gốc của dự án để thiết lập đến registry mong muốn.
  3. Xem xét cẩn thận trong proxying.
  4. Phản ứng nhanh trước các bản dựng bị lỗi
Scope (Phạm vi truy cập):

Trong NPM, một scope được bắt đầu bằng tiền tố @, sau đó là tên của package đó, ví dụ @my-company/foo là scope package. Bạn có thể dùng scoped package (package bị giới hạn phạm vi truy cập) giống như các package khác trong file package.json và trong javascript code dưới đây:

Mã:
{
  "name": "@mycompany/foo",
  "version": "1.2.3",
  "description": "just a scoped package name example",
  "dependencies": {
    "@mycompany/bar": "2.x"
  }
}

Mã:
// es modules style
import foo from '@mycompany/foo'

// commonjs style
const foo = require('@mycompany/foo')
Scopes were introduced in 2014 and are supported by all popular npm clients today.

Scope được giới thiệu vào năm 2014 và được hỗ trợ bởi tất cả npm client ngày nay.

Tại sao nên dùng scope và sử dụng như thế nào?

Chỉ có người dùng hoặc một tổ chức có liên kết với scoped package mới có thể xuất bản nó công khai trên npm registry hoặc đặt nó ở chế độ riêng tư. Bên cạnh đó, tên của scope có thể gắn liền luôn với registry đó.

Ví dụ:

Để chắc chắn rằng tất cả request cho một package nào đó dưới định danh @mycompany scope sẽ tới https://registrey.mycompany.local registry thì phải đăng nhập vào registry trước. Những package khác, nếu như không được đăng kí trên scope sẽ đi đến registry mặc định.

Mã:
npm login --scope=mycompany --registry=https://registry.mycompany.local

Dòng lệnh trên sẽ lưu thông tin đăng nhập của bạn vào trong file ~/.npmrc có dạng như sau:

Mã:
@mycompany:registry = https://registry.mycompany.local/ //registry.mycompany.local:_authToken = xyzabc123-arbitrary-token-value

Sau khi thực hiện xong, hãy truy cập npm registry đã được công khai và tạo một tổ chức free với tên “mycompany”. Từ lúc này, không ai có thể xuất bản bất kỳ package nào dưới dạng scope @mycompany” và các dự án của bạn sẽ trả về lỗi 404 nếu như chúng bị cấu hình sai thay vì âm thầm tải về nội dung không đáng tin cậy. Bước này rất quan trọng vì nó sẽ ngăn kẻ tấn công giả mạo tên tổ chức của bạn trong cộng đồng registry.

Và biện pháp cuối cùng, bạn có thể tạo file .npmrc trong thư mục gốc của dự án với dòng lệnh sau:

Mã:
@mycompany:registry = https://registry.mycompany.local/

Nếu như bạn làm như vậy, npm sẽ kết nối tới scope với registry nội bộ khi làm việc với dự án đó.

Scope có thể giảm thiểu rủi ro của Supply chain attack nơi mà kẻ tấn công có thể giả mạo tên trên public registry mà bạn dự định dùng.

Nếu như bạn dùng npm registry riêng tư mà nó không hỗ trợ scope, hãy cho nhà cung cấp biết rằng họ cần phải có tính năng này để phòng tránh các tấn công này.

Proxying

Trên thực tế, thường thì sẽ sử dụng một registry nội bộ mà được cấu hình ủy quyền cho bất kỳ package nào từ registry đã public trong khi lại chưa thực sự biết về registry bội bộ này. Nếu bạn xuất bản các package riêng tư của mình vào trong registry nội bộ thì nó sẽ tạo ra bản registry public tương tự.

Nếu bạn đang dùng scope thì ổn rồi đó. Còn ngược lại, nên lo đi là vừa.

Không nên ghi và lưu các tên package nội bộ

Đầu tiên, đối với các package đã xuất bản, phải chắc chắn rằng registry nội bộ sẽ không bị lưu lại trên log của proxy. Nếu được lưu trên proxy server, kẻ tấn công có thể xuất bản 1 package với cùng tên trên registry công khai. Nếu như registry của bạn không lưu lại trên log của proxy server bất kỳ thông tin liên quan đến tên package thì bạn đã tự bảo vệ khỏi rủi ro cũng như chỉ request tới registry nội bộ của bạn.

Đặc biệt là, đừng cấu hình registry nội bộ “đúng” y như danh sách các registry public có cùng cấu hình được đẩy lên từ upstream. Vì nó đôi khi được dùng để khắc phục những xung đột về độ phân giải (resolution) nhưng lại là phương án rật tệ bởi đó là cách mà tin tặc thực hiện các vụ tấn công từ việc trùng tên. Nếu có thể, hãy sử dụng registry riêng không có tính năng này.

Bạn sẽ vẫn bị tấn công bởi sự xung đột về độ phân giải không độc hại, có thể tốn kém về chi phí và phiền toái để xử lý nhưng đổi lại không dễ gì để xâm nhập vào hệ thống của bạn.

Cấu hình dự án dùng registry nội bộ.

Thứ 2, chắc chắn rằng tất cả dự án nội bộ có file .npmrc trong thư mục gốc của dự án. Cài đặt giá trị registry trỏ tới registry nội bộ.

Mã:
registry = https://registry.my-company.local/

Điều này sẽ tránh được các lỗi phát sinh trong quá trình nhà phát triển thực hiện tải dự án và chạy lệnh npm install. Đồng thời, nó cũng ngăn chặn nhà phát triển vô tình tải về những nội dung không tin cậy từ registry public.

Bạn có thể kiểm tra cấu hình hiện tại của registry bất cứ lúc nào bằng việc chạy lệnh:

Mã:
Npm config get registry

Package nội bộ không nên thay đổi

Khi một package được xuất bản lên registry proxy nội bộ, điều quan trọng là bạn không được quay trở lại registry public nếu gói đó đã bị xóa.

Ví dụ: bạn có thể xuất bản mycompany-foo vào registry nội bộ của mình. Một thời gian sau, bạn quyết định không sử dụng package này nữa và xóa nó khỏi registry nội bộ. Nếu proxy sau đó bắt đầu cung cấp tên package này từ registry công khai, bạn đang ở trong tình huống kẻ tấn công có thể chiếm lấy tên và giành quyền truy cập vào bất kỳ hệ thống nào bị bỏ lại.

Đây là lý do tại sao registry npm công khai có các quy tắc nghiêm ngặt về những gì có thể bị xóa và ngay cả khi một gói bị xóa, tên và số phiên bản của nó không bao giờ có thể được sử dụng lại.

Xử lý dữ liệu được ủy quyền như là dữ liệu không đáng tin cậy

Npm CLI không có bất kỳ xử lý đặc biệt nào cho registry npm công khai, ngoài việc là một giá trị cấu hình mặc định. Nếu bạn ghi đè cài đặt cấu hình đó, thì npm sẽ sử dụng giá trị bạn cung cấp và bạn sẽ giảm một vector để nội dung bên ngoài xâm nhập vào.

Tuy nhiên, một proxy nội bộ phải được coi là đáng tin cậy chính xác như dữ liệu mà nó proxy. Nếu bạn đã cấu hình nó để hợp nhất các tệp kê khai ngược dòng với các package riêng tư cục bộ của mình hoặc cho phép các tên package nội bộ được ủy quyền, thì bạn rất dễ bị tấn công.

Không bao giờ bỏ qua các lỗi trong bản dựng

Nếu bạn định cấu hình các dự án của mình như chúng tôi đề xuất, bạn sẽ có xu hướng gặp lỗi 404 hơn là tìm nạp nội dung không đáng tin cậy.

Đừng bỏ qua những lỗi này! cấu hình hệ thống của bạn bị sập càng nhiều càng tốt nếu bản dựng bị lỗi và khắc phục nó ngay lập tức khi điều này xảy ra. Các cuộc tấn công vào chuỗi cung ứng dựa vào những cánh cửa luôn mở. Nếu bạn bỏ qua các cảnh báo thì bạn đang bỏ qua một công cụ mạnh mẽ để phát hiện lỗ hổng.

Cảm ơn bạn đã đọc đến đây. :p Nếu có gì thắc mắc thì có thể comment hoăc ib trực tiếp mình nhá.!!!
 
Chỉnh sửa lần cuối bởi người điều hành:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Thẻ
node.js npm prevention supply chain attack web security
Bên trên