`eval echo`를 사용하는 것이 항상 안전한가요?


20

eval임의 코드를 실행할 수 있으므로 사용을 권장하지 않습니다. 그러나을 사용 eval echo하면 나머지 문자열이 인수가되는 것처럼 보이 echo므로 안전해야합니다. 내가 맞습니까?


1
항상 안전 당신은 -fr * 포크 폭탄 또는 더러운 RM을 포장 할 수
μολὼν.λαβέ

어쩌면 이것은 단지 생각 실험 일 수도 있지만 실제로 여러 인수를 전달하기 위해이 -n작업을 수행하려는 경우 인용되지 않은 변수 echo $arguments또는 $arguments배열이 if 인 경우 에만 수행 할 수 있습니다 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"'.
Gordon Davisson

꿰매다. 조금 도움이 된 것을 찾았지만
Ismael Miguel

26

@Celada는 훌륭한 답변을 제공했습니다. eval실제로는 악의 를 나타 내기 위해 "foo"라는 파일을 만드는 것보다 더 사악한 것이 있습니다 .

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

물론 "foo"라는 파일을 만드는 것보다 더 사악한 것보다 더 사악한 것이 있을 수 있습니다 .


8
+1 "$THIS"대신 변수를 인용하는 $THIS것이 도움이되지 않는다는 것을 보여주기 위해 +1하십시오 !
Celada

추가 견적 쌍을 보내는 것이 도움이 될 것 같습니다. 같은 것 eval echo '"'"$DANGEROUS"'"'. goo.gl/L2pPQP
Ismael Miguel

실제로, >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인수는 모두 매개 변수 확장이 포함되지 않은 고정 문자열이기 때문에 이러한 사용 은 안전합니다.


여기서 echo 및 명령 대체가 필요하지 않습니다 ($ IFS에 대한 종속성도 있음). 당신은 할 수 있습니다eval xargs -I_ cat _/'{11..15}'/{8..5}.jpg
Stéphane Chazelas

이것도 작동하지만 xargs 프로세스가 완료 될 때까지 eval에 의해 서브 쉘 프로세스가 생성됩니다. eval echo 버전은 xargs가 시작되기 전에 서브 쉘이 사라지게합니다. 이것은 아마도 htop tree views에 무엇이 나타나고 -x logs를 설정했는지에 관해 나만큼 항문적인 다른 사람들에게만 중요 할 것입니다 :-)
flabdablet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.