Trong bài viết trước của chúng tôi, Hướng dẫn về biến môi trường của Rubyist, chúng tôi đã chỉ cho bạn cách thức hoạt động của hệ thống biến môi trường và phá vỡ một số lầm tưởng phổ biến. Nhưng như một độc giả hữu ích đã chỉ ra, chúng tôi không nói nhiều về bảo mật.
Vì việc sử dụng env vars để lưu trữ các khóa API bí mật và các thông tin có giá trị khác đã trở nên phổ biến, điều quan trọng là phải hiểu các tác động bảo mật. Hãy cùng xem:
Tình huống tồi tệ nhất
Hãy tưởng tượng rằng một hacker đã giành được quyền truy cập vào máy chủ của bạn với tư cách là người chủ hoặc với tư cách là người dùng sở hữu các ứng dụng web của bạn. Trong trường hợp đó, các biến môi trường của bạn sẽ bị xâm phạm, cùng với mọi thứ khác không được mã hóa cao.
Giải pháp ở đây là ngăn mọi người truy cập root vào máy chủ của bạn. :)
Con ngựa thành Troy
Một anh chàng nào đó mà bạn gặp trong một con hẻm cạnh bến tàu đã cho bạn một phiên bản imagemagick được bổ sung đặc biệt. Anh ấy tuyên bố nó sẽ chạy nhanh gấp đôi so với imagemagick trong stock.
... Vì vậy, bạn làm những gì mọi người sẽ làm. Bạn cài đặt nó trong sản xuất. Vấn đề duy nhất là nó được thiết kế để lấy cắp các biến môi trường của bạn.
Ở đây, tôi đang chạy lệnh mogrify "độc hại" của chúng tôi từ Ruby, sử dụng cú pháp back-tick. Sau đó, Mogrify đánh cắp các biến môi trường của tôi và in ra một thông báo chế nhạo.
Các biến môi trường được sao chép từ quy trình mẹ (irb) sang quy trình con (mogrify)
Đây thực sự không phải là một "hack". Đây chỉ là cách hoạt động của các biến môi trường. Chúng được sao chép từ quy trình mẹ sang quy trình con. Nếu bạn tình cờ chạy phần mềm độc hại, chúng sẽ kế thừa các biến môi trường giống như bất kỳ ứng dụng nào khác.
Có hai cách để điều này xảy ra:
-
Ai đó thuyết phục bạn cài đặt một phần mềm độc hại trong chuỗi công cụ của bạn
-
Một phần "lành tính" trong chuỗi công cụ của bạn có lỗ hổng và bị lợi dụng để tiết lộ các biến môi trường của bạn.
Giải pháp thực sự là chủ động ngăn chặn một trong hai điều đó xảy ra. Nhưng có một bước đề phòng mà bạn có thể thực hiện để hạn chế thiệt hại trong trường hợp một số tên cướp ăn cắp ENV xuất hiện trong chuỗi công cụ của bạn.
Vệ sinh môi trường
Bất cứ khi nào bạn thoát khỏi Ruby để chạy imagemagick hoặc bất kỳ chương trình nào khác, chương trình đó sẽ kế thừa một bản sao ENV của ứng dụng của bạn. Nếu bạn có bất kỳ bí mật nào trong ENV, nó cũng sẽ nhận được những bí mật đó. Trừ khi bạn loại bỏ chúng.
Bạn có thể ghi đè các biến môi trường cụ thể khi tạo quy trình mới, bằng cách chuyển một hàm băm cho phương thức hệ thống:
Cách chuyển các biến môi trường tùy chỉnh vào phương thức hệ thống của Ruby
Nếu bạn muốn dừng gửi bất kỳ biến môi trường nào khi bạn thoát ra, bạn có thể làm điều gì đó giống như ví dụ bên dưới. Ở đây chúng tôi tạo một băm sao chép ENV, ngoại trừ việc tất cả các giá trị của nó đã được đặt thành nil. Nó không đẹp, nhưng đó là cách duy nhất tôi tìm thấy để loại bỏ tất cả các env vars khi thực hiện một lệnh shell.
Cách dừng gửi bất kỳ biến môi trường nào khi bạn chạy lệnh shell từ ruby
Đừng ném em bé ra ngoài bằng nước tắm
Tính kế thừa là một trong những tính năng hữu ích nhất của các biến ENV.
Giả sử bạn cần chạy một lệnh ghi vào S3. Kế thừa biến môi trường có nghĩa là lệnh có thể chia sẻ các khóa API từ ứng dụng Ruby của bạn một cách liền mạch. Bạn sẽ mất khả năng đó nếu bạn không bao giờ cho phép kế thừa.
Tính bền bỉ
Mọi quy trình đều có một tập hợp các biến môi trường riêng của nó, các biến môi trường sẽ chết khi quy trình chết. Bạn có thể đặt các biến môi trường trong ứng dụng Ruby của mình, nhưng chúng sẽ biến mất ngay sau khi ứng dụng đó thoát.
Nếu bạn cần một biến môi trường để tồn tại sau khi khởi động lại, nó cần được lưu trữ ở đâu đó. Đó là nơi nào đó thường nằm trên hệ thống tệp.
Không sử dụng git repo của ứng dụng của bạn
Tôi chắc rằng những người ở github cũng trung thực như những người còn lại trong chúng ta, nhưng bạn có thực sự muốn tất cả những người có quyền truy cập vào mã nguồn của bạn đều có thể nhận được các khóa API của bạn và nhận được hóa đơn AWS 10.000 đô la không?
Tránh sử dụng .bashrc hoặc .bash-profile cho bí mật
Khi bạn lưu trữ bí mật trong các tệp như .bashrc, chúng được gửi dưới dạng biến môi trường cho mọi chương trình mà bạn chạy với tư cách người dùng đó. Hầu hết các chương trình này không cần biết bí mật của bạn. Vậy tại sao lại đưa chúng cho họ?
Chỉ tiết lộ bí mật của bạn cho các quy trình cần chúng
Nếu ứng dụng Rails của bạn là quy trình duy nhất cần biết HONEYBADGER_API_KEY của bạn, thì bạn nên chỉ cung cấp cho quy trình đó.
Có một số đá quý cho phép bạn thêm các biến môi trường vào tệp được tải khi Rails khởi động. Các env vars này chỉ có sẵn cho quy trình Rails của bạn và các quy trình con của nó. Có một phần về đá quý figaro và dotenv ở cuối Hướng dẫn về các biến môi trường của Rubyist.
Bảo mật các tệp cấu hình của bạn
Nếu bạn đang tải môi trường của mình từ một tệp cấu hình, bạn sẽ muốn đảm bảo rằng các quyền của nó được đặt để chỉ người dùng đang chạy ứng dụng web của bạn có thể đọc được.
Ở đây, tôi đang làm cho tệp cấu hình của mình chỉ có thể đọc và ghi được bởi người dùng đã tạo ra nó. Trong trường hợp này, chính người dùng sở hữu ứng dụng Rails của tôi:
Chỉ người dùng cần đọc các tệp cấu hình mới có thể đọc được
Vì bạn không kiểm tra nó vào github, bạn sẽ cần phải SSH vào máy chủ và chỉnh sửa nó theo cách thủ công hoặc sử dụng một công cụ như Chef để quản lý nó cho bạn.
Xây dựng "tường lửa" nếu có thể
Một trong những điều thực sự tuyệt vời về AWS là nó cho phép bạn tạo các chính sách kiểm soát truy cập siêu chi tiết. Rất nhiều nhà cung cấp dịch vụ có các tính năng như thế này.
Điều đó nghĩa là gì? Điều đó có nghĩa là bạn có thể có một bộ khóa API sẽ chỉ cho phép bất kỳ ai có chúng tải lên một nhóm duy nhất trên S3. Bạn nên tạo các cặp khóa riêng biệt cho các hoạt động riêng biệt. Một keypair để tải lên hình ảnh. Một cái khác để sao lưu cơ sở dữ liệu của bạn. Và như vậy.
Bằng cách vận hành theo cách này, bạn có thể hạn chế thiệt hại của bất kỳ vi phạm bảo mật nào.