`find -exec sh -c`를 안전하게 사용할 수 있습니까?


29

내가 사용하려고 해요 findecho 0일부 파일에,하지만 분명히 이것은 단지와 함께 작동합니다 sh -c:

find /proc/sys/net/ipv6 -name accept_ra -exec sh -c 'echo 0 > {}' \;

그러나 sh -cwith find -exec을 사용 하면 인용 문제가 의심되므로 매우 불편합니다. 나는 그것으로 조금 바이올린을 썼고 분명히 내 의심은 정당화되었다.

  • 내 테스트 설정 :

    martin@dogmeat ~ % cd findtest 
    martin@dogmeat ~/findtest % echo one > file\ with\ spaces
    martin@dogmeat ~/findtest % echo two > file\ with\ \'single\ quotes\'
    martin@dogmeat ~/findtest % echo three > file\ with\ \"double\ quotes\"
    martin@dogmeat ~/findtest % ll
    insgesamt 12K
    -rw-rw-r-- 1 martin martin 6 Sep 17 12:01 file with "double quotes"
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with 'single quotes'
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with spaces
  • find -exec없이 사용하면 sh -c문제없이 작동하는 것 같습니다.

    martin@dogmeat ~ % find findtest -type f -exec cat {} \;
    one
    two
    three
  • 그러나 내가 사용할 때 sh -c {}어떤 종류의 인용이 필요한 것 같습니다.

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat {}' \;
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: spaces: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: single quotes: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: double quotes: No such file or directory
  • 큰 따옴표는 파일 이름에 큰 따옴표가없는 한 작동합니다.

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c 'cat "{}"' \;
    one
    two
    cat: findtest/file with double: No such file or directory
    cat: quotes: No such file or directory
  • 작은 따옴표는 파일 이름에 작은 따옴표가 포함되지 않는 한 작동합니다.

    martin@dogmeat ~ % LANG=C find findtest -type f -exec sh -c "cat '{}'" \;
    one
    cat: findtest/file with single: No such file or directory
    cat: quotes: No such file or directory
    three

모든 경우에 작동하는 솔루션을 찾지 못했습니다. 내가 간과하거나 본질적으로 안전하지 않은 것을 사용 sh -c하고 find -exec있습니까?

답변:


40

{}쉘 코드에 포함시키지 마십시오 ! 명령 주입 취약점이 발생합니다. 주를 위해 것을 cat "{}"그것의의에 대해서뿐만 아니라 "문자, \, `, $또한 문제가 있습니다 (예를 들어라는 파일을 고려 ./$(reboot)/accept_ra).

(그런데, 일부 find구현에서는 그렇게 할 수 없으며 POSIX{} 는에 대한 인수에서 자체가 아닌 경우 동작을 지정 하지 않은 채로 둡니다find )

여기에서 파일 이름을 별도의 인수로 sh( 코드 인수가 아닌 ) 및 sh인라인 스크립트 ( 코드 인수)로 전달하여 위치 매개 변수를 사용하여 파일 이름 을 참조하려고합니다.

find . -name accept_ra -exec sh -c 'echo 0 > "$1"' sh {} \;

또는 sh파일 당 하나를 실행하지 않으려면 다음을 수행 하십시오.

find . -name accept_ra -exec sh -c 'for file do
  echo 0 > "$file"; done' sh {} +

동일 적용 xargs -I{}또는 zshzargs -I{}. 쓰지 마십시오 :

<list.txt xargs -I {} sh -c 'cmd> {}'

find위와 같은 방법으로 명령 주입 취약점이 될 수 있지만,

<list.txt xargs sh -c 'for file do cmd > "$file"; done' sh

또한 sh파일 당 하나를 실행 list.txt하지 않고 파일이 포함되지 않은 경우 오류 를 피할 수 있다는 이점이 있습니다.

함께 zshS ' zargs, 당신은 아마 호출보다는 기능을 사용하고자하는 것입니다 sh -c:

do-it() cmd > $1
zargs ./*.txt -- do-it

위의 모든 예제에서 위의 두 번째 예제 sh는 인라인 스크립트로 이동합니다 $0. 당신이 관련 일을 (같이 사용해야 sh또는 find-sh)가 아닌 상황이 좋아 _, -, --, 또는 빈 문자열 값으로 $0쉘의 오류 메시지에 사용됩니다 :

$ find . -name accept_ra -exec sh -c 'echo 0 > "$1"' inline-sh {} \;
inline-sh: ./accept_ra: Permission denied

GNU parallel는 다르게 작동합니다. 그것으로, 당신은 이미 쉘을 실행하는 것처럼 사용하고 싶지 않으며 에 대한 올바른 구문에서 인용 된 인수 로 대체하려고합니다 .sh -cparallel{}

<list.txt PARALLEL_SHELL=sh parallel 'cmd > {}'

두 번째 sh는 일종의 자리 표시 자 인 것 같습니다. _예를 들어 대체하면 작동합니다 -bash internals를 호출하려는 경우 매우 유용합니다 find /tmp -name 'fil*' -exec bash -c 'printf "%q\n" "$1"' _ {} \;. 그러나 이것이 어디에 기록되어 있는지 아는 사람이 있습니까?
Florian Fida

1
@FlorianFida 쉘에 대한 첫 번째 인수는 $0(일반적으로 쉘 의 이름입니다.이 시나리오에서는 생략해야합니다. 따라서 일반적인 위치 인수 중 하나를 먹지 않습니다 -c.
Etan Reisner


1
@phk, argv[0]여기 없어요 $0. 스크립트 일뿐 입니다. Sven의 페이지가 여기에 정확하지 않으므로을 기반으로 모드를 r알려주고 zsh변경하지 않는 한 쉘을 제한 모드로 전환하지 않습니다 $0. (exec -a rksh ksh -c 'cd /')제한 ksh되지는 않지만 실행 되지는 않습니다 ksh -c 'cd /' rksh).
Stéphane Chazelas

1
마음에 들지 않는다면 Stéphane은 "쉘 코드에 {}을 (를) 포함하지 않는 이유"를 설명하는 대답이 있습니까? 나는 당신의 모든 답변을 찾기로 갔지만 맹세 할 수는 있지만 하나를 찾을 수 없었습니다.이 주제에 관해 쓴 것들을 보았지만 답변, 채팅의 의견 또는 compunix와 같은 다른 사이트의 경우 회상 할 수 없습니다 ... 시간이 있다면 "Never embed {}"부분을 확장 하겠습니까, 아니면 "find-exec sh -c{} Q 와 함께 사용 하고 쉘 코드에 임베드 하는 보안 영향"과 같은 전용 Q가 있어야한다고 생각 하십니까?
don_crissti
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.