Tại sao sử dụng bảo mật hành động '-execdir' cho thư mục nằm trong PATH?


19

Tại sao không an toàn khi sử dụng kết hợp -execdirhành động tìm trong khi sử dụng -execkhông?

Khi tôi đang chạy lệnh dưới đây, tôi nhận được thông báo nhắc nhở sau:

/path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

find: The current directory is included in the PATH environment variable, which is insecure 
in combination with the -execdir action of find.  Please remove the current directory 
from your $PATH (that is, remove "." or leading or trailing colons)

Điều gì có thể gây ra nhắc nhở này xuất hiện?

Câu trả lời:


22

Bạn có thể chạy chương trình sai. Ai đó có thể làm cho bạn chạy chương trình của họ.

Các -execdirhành động chạy lệnh của bạn từ thư mục có chứa các file (s) được tìm thấy. Khi $PATHchứa các đường dẫn tương đối, chẳng hạn như .hoặc bất cứ thứ gì không bắt đầu/ , -execdirđều không an toàn vì một thư mục tìm thấy tệp (hoặc thư mục khác được giải quyết liên quan đến nó) cũng có thể chứa tệp thực thi cùng tên với tên bạn đang thử chạy. Điều đó có khả năng thực thi không đáng tin cậy sau đó sẽ được chạy.

Điều này có thể được người dùng khác cố tình khai thác để khiến bạn chạy chương trình của họ, điều này có thể gây tổn hại hoặc vi phạm bảo mật dữ liệu, thay vì chương trình bạn đang cố chạy. Hoặc, ít thường xuyên hơn, nó có thể chỉ đơn giản là dẫn đến chương trình sai do vô tình được chạy, thậm chí không có ai cố gắng làm cho vấn đề xảy ra.

Nếu mọi thứ trong PATHbiến môi trường của bạn là một đường dẫn tuyệt đối, lỗi này sẽ không xảy ra, ngay cả khi thư mục bạn đang tìm kiếm và nhập -execdirtừ được chứa trong đó PATH. (Tôi đã kiểm tra xem cái này có hoạt động không.) Nếu bạn tin rằng bạn không có bất kỳ thư mục tương đối nào $PATHnhưng vẫn gặp lỗi này, vui lòng cập nhật câu hỏi của bạn với các chi tiết bao gồm đầu ra của echo "$PATH".

Một ví dụ cụ thể.

Như một ví dụ về những gì có thể đi sai, giả sử:

  • Alice có .trong cô ấy $PATHvì cô ấy muốn có thể chạy các chương trình trong bất kỳ thư mục nào mà cô ấy cdmuốn, mà không bận tâm đến việc đặt trước tên của họ ./.
  • Đêm giao thừa của Alice đã chia sẻ /home/eve/sharedvới Alice.
  • Alice muốn số liệu thống kê (dòng, từ, byte) trên các .ctệp mà Eve đã chia sẻ với cô.

Vì vậy, Alice chạy:

find ~eve/shared -name \*.c -execdir wc {} \;

Thật không may cho Alice, Eve đã tạo ra kịch bản của riêng mình, đặt tên cho nó wc, đặt nó có thể thực thi được ( chmod +x) và đặt nó một cách trắng trợn vào một trong các thư mục bên dưới /home/eve/shared. Kịch bản của Eve trông như thế này:

#!/bin/sh
/usr/bin/wc "$@"
do_evil    # Eve replaces this command with whatver evil she wishes to do

Vì vậy, khi Alice sử dụng findvới -execdirchạy wctrên các tập tin Eve đã chia sẻ, và nó được các tập tin trong thư mục tương tự như tùy chỉnh Eve của wckịch bản, Eve wcchạy - với tất cả các đặc quyền của Alice!

(Thật xảo quyệt, Eve đã làm cho wckịch bản của cô ấy hoạt động như một trình bao bọc cho hệ thống wc, vì vậy Alice thậm chí sẽ không biết có gì đó không ổn, tức là do_evilđã chạy. Tuy nhiên, các biến thể đơn giản hơn - và cũng phức tạp hơn là có thể. )

Làm thế nào để findngăn chặn điều này.

findngăn vấn đề bảo mật này xảy ra bằng cách từ chối thực hiện -execdirhành động khi $PATHchứa một thư mục tương đối.

find cung cấp hai thông điệp chẩn đoán tùy thuộc vào tình huống cụ thể.

  • Nếu .là trong $PATH, thì (như bạn đã thấy) nó nói:

    find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)

    Nó có thể có một thông điệp đặc biệt cho .trường hợp vì nó đặc biệt phổ biến.

  • Nếu một đường dẫn tương đối khác với .--say, - fooxuất hiện $PATHvà bạn chạy findtheo -execdir, nó nói:

    find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH

Tốt hơn hết là không nên có đường dẫn tương đối $PATH.

Nguy cơ có .hoặc các đường dẫn tương đối khác $PATHđặc biệt tăng cao khi sử dụng tiện ích tự động thay đổi thư mục, đó là lý do tại sao findsẽ không cho phép bạn sử dụng -execdirtrong tình huống này.

Nhưng có những con đường tương đối, đặc biệt ., trong bạn $PATHvốn dĩ rất mạo hiểm và thực sự tốt nhất nên tránh. Hãy xem xét tình huống hư cấu trong ví dụ trên. Giả sử thay vì chạy find, Alice chỉ đơn giản cd~eve/shared/blahchạy và chạy wc *.c. Nếu blahchứa wckịch bản của Eve , do_evilchạy như Alice.


2
Tôi không biết nếu bạn đã nghe điều này trước đây rằng bạn sẽ làm một giáo viên rất giỏi :)
heemayl

5
@heemayl tất cả những người viết nội dung hữu ích trên mạng, đã là giáo viên :-)
Ciro Santilli 改造

5

Có một thông tin chi tiết ở đây . Một tài liệu tham khảo tuyệt vời là ở đây . Để trích dẫn từ tài liệu tham khảo đầu tiên:

Tùy chọn -execdir là một tùy chọn hiện đại hơn được giới thiệu trong GNU find là một nỗ lực để tạo ra một phiên bản -exec an toàn hơn. Nó có cùng ngữ nghĩa như -exec với hai cải tiến quan trọng:

Nó luôn cung cấp đường dẫn tuyệt đối đến tệp (sử dụng đường dẫn tương đối đến tệp thực sự nguy hiểm trong trường hợp -exec).

Ngoài việc cung cấp đường dẫn tuyệt đối, nó cũng kiểm tra biến PATH để đảm bảo an toàn (nếu dấu chấm có trong biến Pv env, bạn có thể chọn thực thi từ thư mục sai)

Từ tài liệu tham khảo thứ hai:

Hành động '-execdir' từ chối làm bất cứ điều gì nếu thư mục hiện tại được bao gồm trong biến môi trường $ PATH. Điều này là cần thiết bởi vì '-execdir' chạy các chương trình trong cùng thư mục mà nó tìm thấy các tệp - nói chung, một thư mục như vậy có thể được ghi bởi những người dùng không tin cậy. Vì những lý do tương tự, '-execdir' không cho phép '{}' xuất hiện trong tên của lệnh sẽ được chạy.


Bạn có thể vui lòng mở rộng câu trả lời của mình tại sao "nếu dấu chấm xuất hiện trong biến env PATH, bạn có thể chọn thực thi từ thư mục sai" không? mà sai thư mục ? Và tại sao chúng ta phải làm điều này để làm cho nó an toàn ? Cảm ơn
aғsнι

Tôi hy vọng liên kết thứ hai trong bài đăng được cập nhật của tôi sẽ trả lời câu hỏi của bạn
Ron

3

Vấn đề chính là với giá trị của biến hệ thống PATHchứa các thư mục tương đối trong đó, vì lý do bảo mật, findlệnh sẽ không cho phép bạn thực thi nhị phân, vì có khả năng nó có thể thực thi các chương trình sai.


Vì vậy, ví dụ, nếu bạn có thư mục hiện tại trong PATH theo cảnh báo mà bạn nhận được:

Thư mục hiện tại được bao gồm trong biến môi trường PATH.

và bạn sẽ chạy lệnh của bạn:

find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

trong trường hợp bạn sẽ có tập lệnh cục bộ ( rmcó cờ thực thi) chứa rm -fr /trong đó, nó có thể xóa tất cả các tệp của bạn, vì thay vì thực thi như mong đợi /bin/rm, bạn sẽ thực thi rmtừ thư mục hiện tại, vì vậy có lẽ đó không phải là điều bạn muốn.


Là một lưu ý phụ, đây là sự cố đã biết trong Travis CI ( GH # 2811 ) khi nó không thành công với lỗi:

find: Đường dẫn tương đối `./node_modules/.bin 'được bao gồm trong biến môi trường PATH, không an toàn khi kết hợp với hành động -execdir của find. Vui lòng xóa mục nhập đó khỏi $ PATH

Vì vậy, giải pháp là loại bỏ mục bị ảnh hưởng khỏi biến PATH, vd

PATH=`echo $PATH | sed -e 's/:\.\/node_modules\/\.bin//'`

theo đề xuất của drogus . Tiến trình của lỗi này, có thể được theo dõi tại GH # 4862 .


Đây là cách giải quyết của Bash:

PATH=${PATH//:\.\/node_modules\/\.bin/}

Ví dụ sử dụng (chuyển qua bộ lọc PATHcho lệnh cụ thể):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f

Đây là một sedthứ dường như loại bỏ tất cả những thứ findkhông thích: Askubfox.com/questions/621132/ Khăn
Ciro Santilli 改造

3

xargsbash -c cdcách giải quyết

Được tôi từ bỏ:

find . -type f |
  xargs -I '{}' bash -c 'cd "$(dirname "{}")" && pwd && echo "$(basename "{}")"'

sed cách giải quyết

Một chút ít tốt đẹp hơn so với cách giải quyết trước đây:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" find . -execdir echo '{}' \;

Một bản thử nghiệm:

[ "$(printf '/a/b::c/d:/e/f\n' | sed -E 's/(^|:)[^\/][^:]*//g')" = '/a/b:/e/f' ] || echo fail

Đối với renameđặc biệt, bạn cũng có thể làm việc xung quanh với một số Perl regex-fu: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS hy vọng nghiền

Đối với những người có hy vọng rằng có một cách để bỏ qua ý kiến findcủa mình, hãy để tôi nghiền nát điều đó với một số nguồn:

Từ đó chúng ta thấy rằng dường như không có cách nào để tắt kiểm tra đường dẫn.

Quy tắc chính xác mà nó kiểm tra là: thất bại nếu PATHtrống hoặc không bắt đầu bằng /.

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.