Bạn có thể tìm một nguồn tài liệu ở đây hay không?


8

Giả sử tôi có một tập lệnh bash hoạt động như một tập tin cấu hình cho một tập lệnh bash khác:

cấu hình

verbose=yes
echo "Malicious code!"
name=test

script.sh:

source config.sh
echo "After sourcing: verbose='$verbose', name='$name'"

Vấn đề là, điều này không an toàn lắm, vì mọi thứ được đặt trong config.sh đều được chạy:

$ ./script.sh
Malicious code!
After sourcing: verbose='yes', name='test'

Để làm cho nó an toàn hơn, tôi nghĩ rằng tôi đã thực hiện các hoạt động chuyển nhượng và chỉ thực hiện chúng. Tôi sẽ thực hiện bằng cách chuyển sourcemột "tài liệu ở đây":

script.sh:

source <<EOF
$(grep -P '^\s*\w+=' test.sh)
EOF
echo "After sourcing: verbose='$verbose', name='$name'"

(Vâng, tôi biết regex không mạnh đến thế; nó chỉ là một trình giữ chỗ.) Đáng buồn thay, nguồn dường như không chơi tốt với tài liệu ở đây:

./script.sh: line 1: source: filename argument required
source: usage: source filename [arguments]
After sourcing: verbose='', name=''

Rõ ràng là tôi có thể thực hiện bất kỳ số lượng nào để có được dữ liệu cấu hình từ một tệp và dù sao đó cũng có thể an toàn hơn.

Nhưng tôi vẫn còn ngứa với điều này; Tôi muốn tìm hiểu xem những gì tôi đã thử có thể làm việc. Bất kỳ đề xuất?


1
Trong trường hợp câu trả lời không rõ ràng, vấn đề của bạn là "tài liệu ở đây" ( <<EOF) hoạt động như một chuyển hướng đầu vào thông thường ( < file) và source < filekhông hoạt động - sourcecần phải có một đối số tên tệp. Do đó, bạn cần thay thế quá trình ( <(command)), trông giống như một đối số tên tệp.
G-Man nói 'Phục hồi Monica'

Một cách tiếp cận dễ dàng để làm cho an toàn rõ ràng: while IFS== read -r var value; do case $var in |*[!0-9A-Z_a-z]*) complain;; *) eval "config_$var=\$value";; esac; done <config(cảnh báo: đã nhập vào trình duyệt của tôi, hãy kiểm tra nó! ) Đừng quên không cho phép nhập các biến như PATH, IFStiền tố như config_một cách tiếp cận an toàn.
Gilles 'SO- ngừng trở nên xấu xa'

+1 Mặc dù bản thân kiểm soát bên ngoài các tệp cấu hình có thể là một triệu chứng của các vấn đề bảo mật nghiêm trọng hơn mà chỉ riêng việc xác thực đầu vào là không đủ để giải quyết. Điều này, tuy nhiên, sẽ có những ứng dụng khác ngoài các khía cạnh bảo mật.
Thomas Nyman

@ G-Man - bạn không cần thay thế quy trình - khác với đường ống tiêu chuẩn chủ yếu ở chỗ đó thay vì truyền dữ liệu đến stdin của quy trình, nó đưa ra một liên kết đến thiết bị xuất chuẩn của nó như một đối số, thường ở dạng /dev/fd/[num]. Thi đua này là đơn giản : 3<<HEREDOC . /dev/fd/3\n*file contents*\nHEREDOC\n. Sự thay thế quá trình thường một đường ống, trong khi heredocs thường là các nút xóa vỏ trước khi xóa chúng - vì vậy chúng chỉ tồn tại dưới dạng mô tả. trong dashchúng là đường ống. sự khác biệt lớn khác là bạn có thể chỉ định fd [num]cho heredocs.
mikeerv

Câu trả lời:


6

source cần một tên tệp, bạn không thể chuyển hướng đầu vào cho nó.

Trên hệ thống của tôi, tôi đã có thể sử dụng Thay thế quy trình thay thế:

source <( grep = test.sh )

Thay thế =bằng biểu thức chính quy thích hợp.


2
heh, và đây là mã độc:delete --recursively /this/important/dir #=
glenn jackman

@glennjackman: Đây =chỉ là một trình giữ chỗ.
choroba

Tại sao không chỉ cho nó một liên kết đến mô tả? Đó là tất cả các quy trình phụ của bạn dù thế nào đi nữa:3<<HEREDOC . /dev/fd/3\nand so on...
mikeerv

1
@mikeerv: Dễ đọc, có thể?
choroba

Nghiêm túc? Tất nhiên bạn có thể gọi nó là bất cứ điều gì bạn muốn - và đó là một trong số ít các cấu trúc vỏ không dễ dàng gửi đến ;nhồi. Hơn nữa, bạn có thể đặt tên và đánh số một cách rõ ràng mô tả mà không phải là điều tôi tin có thể được thực hiện với sự thay thế. Bạn cũng có thể có các tab hàng đầu tự động bị tước - và do đó, mã có thể được phân tích cú pháp - nó không đẹp trong một nhận xét vì tôi phải chém \ n, v.v., nhưng nó có nhiều tiềm năng hơn - và nó có thể mang theo được. Nếu bạn không thích .dotbạn nên bí danh nó - nó an toàn hơn bình sourcethường.
mikeerv

8
source <(cat << EOF
A=42
EOF
)
echo $A

Đầu ra:

42

1

Bạn có thể trực tiếp evalnó:

eval "$(grep -P '^\s*\w+=' config.sh)" 
#quotes needed if you want the full content of the file (including newlines etc.)

Tìm nguồn cung ứng về cơ bản giống như:

eval "$(cat file)"   

Tuy nhiên, lưu ý rằng mọi người có thể thực thi tất cả kinz của codez ở bên phải của dấu bằng:

a=$(evil_code_here)
b=`evil_code_here`
c="something" evil_code_here
#etc.

Bạn cần một bộ lọc tốt hơn.

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.