Làm thế nào để chuyển các biến một cách an toàn cho các tập lệnh kích hoạt root?


13

Câu hỏi này hoàn toàn chung chung và không chỉ áp dụng cho trường hợp của tôi, nhưng ... Tôi có một thiết bị hộp bận nhỏ nơi tôi muốn một người dùng không phải root có thể thực thi một tập lệnh cụ thể với quyền riêng tư gốc. Ví dụ: một cái gì đó giống như tập lệnh nhỏ này để kích hoạt DHCP, trong đó biến duy nhất ( $1) để gửi trên cmdline (!!) là tên máy chủ cần gửi:

#!/bin/bash
udhcpc -b -i eth0 -h $1

chạy udhcpc như thế này đòi hỏi quyền truy cập root, vì vậy để làm điều này tôi có kế hoạch sửa đổi /etc/sudoersđể chứa dòng này:

joe ALL = NOPASSWD: /path/to/enable_dhcp.sh

sẽ kích hoạt "joe" để dễ dàng chạy tập lệnh đó với quyền root bằng cách chạy đơn giản:

sudo /path/to/enable_dhcp.sh

và không được yêu cầu nhập mật khẩu (đó là những gì tôi muốn, vì tôi muốn joe có thể viết kịch bản này).

Bây giờ .. tôi biết (hoặc ít nhất là nghĩ rằng tôi làm) rằng sử dụng $1trong một tập lệnh có thể dễ dàng chạy với quyền root là một ý tưởng HORRIBLE vì bạn có thể tiêm bất cứ thứ gì bạn muốn vào đó.

Vậy ... cách tốt nhất để giải quyết vấn đề này là gì? Làm cách nào để joe thực hiện những gì tôi muốn với quyền root, cho phép anh ta chuyển vào một biến (hoặc thực sự làm như vậy với biến môi trường), trong khi không mở rộng cho các cuộc tấn công tiêm chích?

Câu trả lời:


14

Chạy shell script bên dưới sudolà an toàn với điều kiện sudođược cấu hình để thiết lập lại môi trường . Ngược lại, nếu sudokhông thiết lập lại môi trường, thì việc chạy tập lệnh shell không an toàn, ngay cả khi tập lệnh của bạn không sử dụng tham số của nó (xem Cho phép setuid trên tập lệnh shell ). Hãy chắc chắn rằng bạn có Defaults env_resettrong /etc/sudoershoặc rằng tùy chọn này là mặc định thời gian biên dịch ( sudo sudo -V | grep envbao gồm Reset the environment to a default set of variables).

Không có nguy hiểm đặc biệt trong việc sử dụng các tham số tập lệnh. $1là một chuỗi, tất cả những gì bạn cần đảm bảo là bạn đang sử dụng nó như một chuỗi. (Ví dụ: không nên làm eval "$1".) Rõ ràng, điều đặc biệt quan trọng ở đây là không đưa ra các giả định về nội dung của biến và đặt dấu ngoặc kép xung quanh tất cả các thay thế biến (ví dụ viết "$1", không $1). Lưu ý rằng việc đặt dấu ngoặc kép xung quanh các thay thế thay đổi không dành riêng cho các tập lệnh đang chạy với các đặc quyền, đó là điều bạn phải làm mọi lúc.

Bạn có thể muốn xác thực tham số hơn nữa, tùy thuộc vào những gì udhcpckhông giống với tên máy chủ. Ví dụ: điều này sẽ thực hiện kiểm tra cú pháp đầu tiên:

#!/bin/sh
case "$1" in
  *[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;;
esac
udhcpc -b -i eth0 -h "$1"

Những thứ khác để xem xét có thể có tác động đến hành vi của lệnh đó: thư mục làm việc hiện tại và những gì stdin, stdout, stderr trỏ tới, xử lý tín hiệu và ulimits. Chẳng hạn, bằng cách cho phép các bãi chứa lõi (trên <kbd> Ctrl - \ </ kbd>), bạn có thể cho phép người dùng xả rác / chạy / khóa mà trên hệ thống của tôi là một tmpfs với kích thước rất hạn chế và có thể cho phép DoS.
Stéphane Chazelas

5

Bạn nên kết hợp đầu vào đã qua với một mẫu tốt.

Ví dụ: có vẻ như một địa chỉ IP có thể là đầu vào hợp lệ cho bạn. Vì vậy, bạn có thể sử dụng một cái gì đó như thế này:

if [[ "$1" =~ ^[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9]$ ]]
then
  udhcpc -b -i eth0 -h "$1"
else
  echo "Don't mess with me pork chop."
fi

Lưu ý, regrec đó chưa được kiểm tra, bạn có trách nhiệm đảm bảo regrec của bạn không cho phép bất cứ điều gì nguy hiểm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.