GNU/Linux >> Belajar Linux >  >> Linux

Seberapa Aman Idiom `ssh … “$(typeset -f Foo); ''?

Misalkan beberapa fungsi shell foo didefinisikan dalam sesi shell saat ini. Kemudian perintah

typeset -f foo

mencetak kode sumber dari fungsi ini. Ini berarti bahwa, setidaknya pada prinsipnya, seseorang dapat menjalankan fungsi ini pada host jarak jauh melalui ssh seperti yang ditunjukkan di bawah ini:

ssh <REMOTE-HOST> "$(typeset -f foo); foo"

(Untuk keperluan pertanyaan ini, asumsikan bahwa semua perintah dan jalur sistem file yang disebutkan oleh foo tersedia di <REMOTE-HOST> . Juga, asumsikan bahwa bash adalah cangkang di kedua ujungnya.)

Naluri saya adalah bahwa secara membabi buta mencari beberapa kode sumber yang dihasilkan secara otomatis seperti ini akan sangat rapuh, tetapi saya belum dapat menemukan contoh fungsi foo di mana idiom ini gagal.

Pertanyaan saya adalah:Seberapa amankah idiom ini? Jika tidak aman, dapatkah seseorang memberi saya contoh konkret yang menggambarkan bagaimana gagal? (Pertanyaan keamanan mencakup hal berikut:apakah bash menjamin bahwa penggunaan typeset -f seperti itu aman?)

NB: Dalam posting ini saya tidak mencari alternatif; Saya hanya ingin memahami properti dari idiom khusus ini.

EDIT:mengklarifikasi bahwa bash adalah cangkang di kedua ujungnya.

Jawaban yang Diterima:

Tidak aman jika kode tidak ditafsirkan dalam lokal yang sama dengan kode yang dibuat (atau jika nama lokal adalah sama tetapi definisi lokal tersebut berbeda antara host klien ssh dan host server).

Yang sangat penting adalah pengkodean karakter dan keanggotaan karakter di blank , alpha dan alnum kategori.

Misalnya, α karakter (huruf Yunani huruf kecil alfa) dalam rangkaian karakter BIG5 dikodekan sebagai 0xa3 0x5c, 0x5c menjadi di ASCII (dan semua rangkaian karakter termasuk BIG5).

Jadi jika Anda memiliki foo fungsi yang didefinisikan dalam rangkaian karakter itu sebagai:

foo() {
  echo α
}

typeset -f akan menampilkannya seperti itu, tetapi jika ditafsirkan dalam lokal yang berbeda seperti C, 0xa3 0x5c itu tidak akan dianggap sebagai α tetapi sebagai karakter 0xa3 yang tidak diketahui diikuti oleh garis miring terbalik. Itu dapat dieksploitasi seperti dengan:

$ env LC_ALL=zh_TW.big5 $'BASH_FUNC_foo%%=() { echo xa3\\;}; echo gotcha; }' bash -c 'typeset -f foo' | bash
gotcha
bash: line 5: syntax error near unexpected token `}'
bash: line 5: `}'

foo() { echo α;}; echo gotcha; } menjadi foo() { echo <0xa3>\; }; echo gotcha; } ketika ditafsirkan dalam bahasa yang berbeda.

Masalah lain:

à karakter dalam UTF-8 dikodekan sebagai 0xc3 0xa0. Dalam iso8859-1 dan beberapa iso8859 lainnya set karakter, 0xa0 adalah karakter spasi non-breaking. Pada beberapa sistem, karakter tersebut disertakan dalam kosong kelas karakter, sangat dihormati oleh bash sebagai pembatas token dalam sintaksnya.

Terkait:Linux - Hanya izin file yang dieksekusi?

Solaris adalah salah satu sistem di mana U+00A0 dianggap kosong:

$ env $'BASH_FUNC_foo%%=() { nawk -v x=àBEGIN'{system("echo gotcha")}' 1;}' bash -c 'typeset -f foo; echo foo'  | ssh solaris LC_ALL=en_GB.ISO8859-1 bash
gotcha

Lihat caranya:

nawk -v x=àBEGIN... 1

diartikan sebagai:

nawk -v x=<0xc3> 'BEGIN{system("...")}' 1

Perhatikan bahwa jika fungsi didefinisikan di lokal di mana 0xa0 tidak kosong atau di mana 0xa3 0x5c adalah alfa, typeset -f akan tetap mengeluarkan output yang sama meskipun dipanggil di lokal yang kosong (menghasilkan output yang berbeda saat diinterpretasikan)

$ LC_ALL=zh_TW.big5 bash -c $'f() { echo xa3x5c$(uname); }; export LC_ALL=C; typeset -f f | bash'
bash: line 3: syntax error near unexpected token `('
bash: line 3: `    echo �$(uname)'

Secara umum, output dari typeset , alias , export -p , set , locale semuanya dimaksudkan agar sesuai untuk input ulang ke shell, tetapi selain masalah lokal tersebut, berbagai implementasi diketahui memiliki beberapa masalah, dan saya tidak akan terkejut jika masih banyak lagi.

Jadi, ya, saya setuju Anda benar untuk menganggapnya berbahaya, dan sebaiknya gunakan hanya dalam konteks di mana Anda tahu dari mana data yang dihasilkan berasal. Misalnya, dalam kasus typeset -f foo , hanya gunakan pada foo fungsi itu Anda telah ditentukan (dan hindari menggunakan karakter non-ASCII di dalamnya).


Linux
  1. Tujuan .bashrc Dan Bagaimana Cara Kerjanya?

  2. Bagaimana Menghentikan Skrip Loop Bash Di Terminal?

  3. Bagaimana Cara Mendapatkan Tty Di Bash Yang Sedang Berjalan?

  1. Bagaimana saya tahu nama file skrip dalam skrip Bash?

  2. Bagaimana saya bisa mengingat argumen dari perintah bash sebelumnya?

  3. Bagaimana cara membaca baris kedua hingga terakhir dalam file menggunakan Bash?

  1. Cara mendapatkan status keluar satu lingkaran di bash

  2. Bagaimana cara cepat mengubah kata pertama dalam perintah Bash?

  3. Apa yang setara dengan Bash's cat -n di PowerShell?