Làm cách nào tôi có thể tạo và truy cập các tệp tạm thời một cách an toàn từ các tập lệnh shell?


14

Tôi đã đọc rằng việc chuyển hướng đầu ra sang một tệp tên cố định /tmpcó thể là một rủi ro bảo mật, bởi vì nếu kẻ tấn công (hoặc kẻ xấu) thông báo rằng một tệp /tmp/tmpfileformyscript.tmpđược tạo khi tôi chạy tập lệnh của mình (ngay cả khi anh ta không đọc được quyền truy cập vào kịch bản), ví dụ anh ta có thể tạo một liên kết tượng trưng ln -s ~wildcard/.bashrc /tmp/tmpfileformyscript.tmpkhiến tôi phá hủy .bashrctệp của tôi khi tôi chạy tập lệnh của mình.

Vì vậy, thay vào đó tôi có thể sử dụng một cái gì đó như filename="tmpfile.tmp.$RANDOM" ; echo outputtext > "$filename".

Tuy nhiên, đôi khi tôi muốn sử dụng tệp tmp để lưu vào bộ đệm, trong trường hợp đó tôi muốn biết liệu "tmpfile.tmp. *" Có khớp với bất cứ điều gì không /tmpvà nếu có, hãy sử dụng tệp đó thay vì tạo tệp mới. Thật không may testvà tương đương [ -f filename ]không hỗ trợ tập tin toàn cầu như tôi có thể nói.

Vì vậy, câu hỏi của tôi là gấp đôi:

  1. Làm thế nào tôi có thể tạo tempfile một cách an toàn? Là "predictablename.$RANDOM"một thực tiễn có thể chấp nhận hoặc có một cách tốt hơn (an toàn hơn, dễ dàng hơn)?
  2. Làm thế nào tôi có thể dễ dàng truy cập tệp và / hoặc thiết lập sự tồn tại của nó sau này bằng cách kiểm tra predictablename?

Câu trả lời:


13

Sử dụng mktemptiện ích để tạo một tệp tạm thời với một tên không thể đoán trước. Nó không được chuẩn hóa bởi POSIX, nhưng nó có sẵn trên * BSD cũng như Linux.

> /tmp/predictable.$RANDOMkhông phải là một lựa chọn tốt vì nó hầu như có thể dự đoán được - nó mở kịch bản của bạn cho một cuộc tấn công trong đó kẻ tấn công có thể lừa kịch bản của bạn ghi đè lên một tệp mà bạn có quyền truy cập ghi hoặc cho chúng quyền truy cập vào tệp tạm thời. Đây là một lỗ hổng tập tin tạm thời không an toàn . mktempkhông có lỗ hổng này vì tạo tệp một cách an toàn (nó sẽ không ghi đè lên tệp hiện có, ngay cả khi có liên kết tượng trưng) và sử dụng tên đủ khó đoán để tránh bị từ chối dịch vụ.

Nếu việc tạo một tệp tạm thời và làm việc với nó không đủ tốt, hãy tạo một thư mục tạm thời mktemp -dvà làm việc trong đó.

mktempcũng cẩn thận sử dụng $TMPDIRnếu biến được đặt, quay lại /tmpnếu nó không được đặt.

Ngày càng có nhiều bản phân phối được thiết lập thành TMPDIRmột thư mục riêng, ví dụ UID của bạn /run/1234/tmpở đâu 1234. Điều này giúp loại bỏ nguy cơ lỗ hổng tệp tạm thời, với chi phí không còn có thể chia sẻ tệp tạm thời giữa người dùng (đôi khi hữu ích, nhưng không thường xuyên; /tmpvẫn có sẵn, chỉ là không có TMPDIR).

Nếu bạn cần một tên tệp có thể sao chép, thì hãy tạo một tệp có tên được xác định rõ (không có thành phần ngẫu nhiên) trong thư mục chính của người dùng. Quy ước hiện đại là đặc tả thư mục người dùng XDG . Nếu tệp có thể bị xóa mà không gây mất dữ liệu, hãy sử dụng XDG_CACHE_HOMEbiến môi trường, mặc định là ~/.cache. Bạn có thể nên tạo một thư mục con được đặt tên theo ứng dụng của bạn và làm việc ở đó.

CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"

¹ Không chỉ $RANDOMchỉ mất 32.767 giá trị có thể, nhưng đó là dễ dàng để dự đoán mà không cần cố gắng nhiều giá trị. Trình tạo số ngẫu nhiên của Bash là LCG được tạo mầm bởi PID và thời gian sử dụng đầu tiên. Zsh's là nền tảng được randgieo mầm bởi thời gian khởi động. ATT Ksh's là nền tảng được randgieo mầm bởi PID. Mksh's là một LCG với hạt giống phức tạp hơn nhưng vẫn không đảm bảo chất lượng. Tất cả chúng có thể được dự đoán bởi một quá trình khác với cơ hội thành công khá lớn.


Trên thực tế cuộc thảo luận của bạn $TMPDIR~/.cachechính xác là những gì tôi cần. Sau khi suy nghĩ thêm, tôi nhận ra rằng lý do duy nhất tôi muốn nó /tmplà phân vùng vì vậy bộ đệm không thể lấp đầy /homephân vùng. Nhưng đối với trường hợp sử dụng này thực sự không phải là vấn đề hoàn chỉnh, vì vậy một thư mục con ~/.cachephù hợp với nhu cầu của tôi một cách hoàn hảo và tránh được vấn đề bảo mật.
tự đại diện

mktempkhông có sẵn trên AIX hoặc Git shell trên Windows. Có vẻ như file.$RANDOM$RANDOMlà giải pháp di động. Các $RANDOM$RANDOMnên tăng không gian để 2 ^ 32, giả sử Bash kết quả ngẫu nhiên độc lập và không yếu đuối.

@jww Kết quả ngẫu nhiên của Bash rất yếu: đó là LCG, có thể dự đoán được trong khi nó đủ tốt cho nhiều ứng dụng không yêu cầu không thể đoán trước.
Gilles 'SO- ngừng trở nên xấu xa'

9

mktemp được thiết kế cho việc này. Từ trang người đàn ông:

TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1
echo "program output" >> $TMPFILE

mktemp sẽ tạo tập tin hoặc thoát với trạng thái thoát khác không. Logic hoặc (||) đảm bảo rằng tập lệnh sẽ thoát nếu mktemp không thể tạo tệp. Sau lệnh này, bạn có thể chắc chắn rằng tệp có sẵn. Không cần phải kiểm tra lại. Điều duy nhất bạn có thể cần thêm là dọn dẹp tệp ở cuối tập lệnh của bạn.

Và cũng có thể khi tập lệnh bị chấm dứt bởi một tín hiệu. Điều đó có cần thiết hay không là điều bạn phải quyết định.

Cả hai có thể được thực hiện bằng cách sử dụng traplệnh.


Ah! Điều đó rất hữu ích; sau đó tôi không cần phải gọi $RANDOM. Nhưng sau đó, phần 2 của câu hỏi của tôi, làm thế nào tôi có thể truy cập tệp đó sau hoặc kiểm tra xem nó đã tồn tại trong lần chạy tập lệnh tiếp theo chưa? (Để thực hiện bộ đệm rất đơn giản.)
Wildcard
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.