Чи завжди безпечно використовувати `eval echo`?


20

Використовувати evalчасто не рекомендується, оскільки це дозволяє виконувати довільний код. Однак якщо ми використовуємо eval echo, то, схоже, решта рядка стане аргументами, echoтому це повинно бути безпечним. Чи правильно я в цьому ставлюсь?


1
не завжди безпечно ви можете загорнути вилкову бомбу або неприємну rm -fR *
μολὼν.λαβέ

Можливо, це лише продуманий експеримент, але якщо ви насправді думали зробити це, щоб передати йому декілька аргументів на кшталт -n, ви можете просто зробити це з нецитованою змінною на кшталт echo $argumentsабо якщо $argumentsце масив echo "${arguments[@]}". Використовувати eval echoбезглуздо, навіть якщо це було б безпечно.
JoL

Відповіді:


40

Контрприклад:

DANGEROUS=">foo"
eval echo $DANGEROUS

Довільні аргументи echoмогли зробити щось більш шкідливе, ніж створити файл під назвою "foo".


6
Також: DANGEROUS="hello;ls"для довільних команд замість ls.
Kusalananda

2
Також: DANGEROUS='$(ls)'(може знадобитися більше втечі).
wizzwizz4

Було б eval echo '"'"$DANGEROUS"'"'працювати? Здається, на goo.gl/L2pPQP
Ісмаель Мігель

@IsmaelMiguel Це не працює для прикладів wizzwizz, Cyker або sorontar або для чого-небудь з подвійними лапками в рядку (наприклад DANGEROUS='">foo"').
Гордон Девіссон

Дарн. Я хоч знайшов щось, що трохи допомогло
Ісмаель Мігель

26

@Celada дав чудову відповідь. Демонструвати evalце справді зло, ось щось більш шкідливе, ніж створення файлу під назвою "foo" :

DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"

І звичайно, може бути щось більш шкідливе, ніж щось більш шкідливе, ніж створення файлу під назвою "foo" .


8
+1 за демонстрацію, що котирування змінної типу, "$THIS"а не просто її як $THIS, навіть не допомагає!
Селада

Надсилання додаткової пари цитат, здається, допомагає. Щось подібне eval echo '"'"$DANGEROUS"'"'. Спробуйте на goo.gl/L2pPQP
Ісмаель Мігель

Насправді, ваш приклад не є більш грізним, ніж >foo"створення файлу під назвою" foo "- це не обов'язково все, що >fooробить. Єдина реальна відмінність вашого прикладу - це те, що він не залишає порожній файл позаду. Вмісту все ще немає.
flarn2006

12

Ні, це не завжди безпечно. Евал може виконати будь-яку команду.

Безпечна команда, подібна до цієї (дата не виконується так, як вона знаходиться в одних цитатах):

$ echo '$(date)'
$(date)

Стає небезпечним при використанні з eval:

$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016

Звичайно, дата може бути будь-якою командою.

Один із способів покращити це - додатково навести аргументи на eval:

$ eval echo '\$(date)'
$(date)

Але зазвичай важко правильно двічі висловити вираз.

І неможливо контролювати правильне цитування, якщо вираз може бути встановлений зовнішнім зловмисником, наприклад:

$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!

1

Хоча це правда, що evalдо цього завжди потрібно підходити обережно, eval echoбудівництво не завжди є безглуздим і його можна використовувати безпечно. Нещодавно мені це було потрібно, щоб отримати декілька розширень підтяжок в оцінці в тому порядку, в якому я їх потребував.

bash робить кілька розширень дужок зліва направо, так

xargs -I_ cat _/{11..15}/{8..5}.jpg

розширюється до

xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg

але мені було потрібно друге розширення дужок, зроблене першим, поступаючись

xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg

Найкраще, що я міг придумати, щоб це зробити

xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)

Це працює, тому що одиничні лапки захищають перший набір дужок від розширення під час розбору evalкомандного рядка, залишаючи їх розширювати за допомогою підпрограми, на яку посилається eval.

Можливо, існує якась хитра схема, що включає вкладені розширення дужок, що дозволяє це статися за один крок, але якщо є я занадто старий і дурний, щоб це бачити. Є й інші снаряди, окрім bashяких дозволяють охайніші способи досягнення подібного роду. Але у будь-якому випадку це використання evalє безпечним, оскільки його аргументи - це всі фіксовані рядки, що не містять розширень параметрів.


Тут вам не потрібна ехо та підміна команд (яка також залежить від $ IFS). Ви могли зробитиeval xargs -I_ cat _/'{11..15}'/{8..5}.jpg
Стефан Шазелас

Це теж працює, але це робить процес підрозділу породженим eval stick, поки процес xargs не буде закінчений; версія eval echo змушує підзарядку відійти ще до того, як xargs навіть буде запущений. Це, мабуть, важливо лише для тих, хто настільки ж анальний, як і я, про те, що з’являється у переглядах дерев на htop-дереві та встановити -x журнали, хоча :-)
flabdablet
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.