사용하는 -execdir
동안 찾기 동작 조합을 사용하는 것이 안전하지 않은 이유는 무엇 -exec
입니까?
아래 명령을 실행하면 다음과 같은 프롬프트 메시지가 나타납니다.
/path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +
find: The current directory is included in the PATH environment variable, which is insecure
in combination with the -execdir action of find. Please remove the current directory
from your $PATH (that is, remove "." or leading or trailing colons)
이 메시지가 나타나는 원인은 무엇입니까?
답변
잘못된 프로그램을 실행할 수 있습니다. 누군가 당신이 그들의 프로그램을 실행하도록 만들 수 있습니다.
-execdir
조치는 파일 (들)을 발견 들어있는 디렉토리에서 명령을 실행합니다. 때 $PATH
상대와 같은 경로를 포함 .
또는로 시작하지 않는 것도/
, -execdir
파일이 발견 된 디렉토리 또한 당신이하려고하는 일 같은 이름의 실행 파일을 포함 할 수있다 (또는 다른 디렉토리가 상대적 해결)하기 때문에 안전하지 않습니다 실행합니다. 그러면 잠재적으로 신뢰할 수없는 실행 파일이 대신 실행됩니다.
이것은 다른 사용자가 의도적으로 악용하여 프로그램을 실행하게 만들 수 있으며, 이로 인해 실행하려는 프로그램 대신 데이터 보안이 손상되거나 위반 될 수 있습니다. 또는 덜 자주, 문제를 일으키려는 사람이 없어도 실수로 잘못된 프로그램이 실행될 수 있습니다.
PATH
환경 변수의 모든 것이 절대 경로 인 경우, 검색하고있는 디렉토리 가에 포함되어 -execdir
있어도이 오류가 발생하지 않아야합니다 . (이것이 작동하는지 확인했습니다.) 상대 디렉토리가 없다고 생각 하지만 여전히이 오류가 발생하는 경우의 출력을 포함하여 세부 사항으로 질문을 업데이트하십시오 .PATH
$PATH
echo "$PATH"
구체적인 예입니다.
무엇이 잘못 될 수 있는지에 대한 예로서 다음과 같이 가정하십시오.
- 앨리스가
.
그녀에$PATH
그녀는 그녀의 어떤 디렉토리에 프로그램을 실행할 수 있도록 원하기 때문에cd
자신의 이름을 씁니다 귀찮게하지 않고,에 ‘D를./
. - Alice의 열광적 인 Eve는
/home/eve/shared
Alice와 공유 했습니다. - Alice는
.c
Eve가 공유 한 파일 에 대한 통계 (줄, 단어, 바이트)를 원합니다 .
그래서 Alice는 다음을 실행합니다.
find ~eve/shared -name \*.c -execdir wc {} \;
불행히도 Eve의 경우 자체 스크립트를 작성하고 이름을 wc
지정하고 실행 파일 ( chmod +x
)을 설정하고 아래 디렉토리 중 하나에 비밀리에 배치했습니다 /home/eve/shared
. 이브의 스크립트는 다음과 같습니다 :
#!/bin/sh
/usr/bin/wc "$@"
do_evil # Eve replaces this command with whatver evil she wishes to do
따라서 Alice가 Eve와 공유 한 파일 을 실행하기 위해 find
with -execdir
를 사용 하고 wc
Eve의 사용자 지정 wc
스크립트 와 동일한 디렉토리에있는 파일을 가져 오면 wc
Alice의 모든 권한을 가진 Eve의 실행이 이루어집니다!
(교활한 Eve는 자신의 wc
스크립트가 시스템의 래퍼 역할을 wc
하도록했기 때문에 Alice는 무언가 잘못되었다는 사실조차 알지 do_evil
못하지만 더 단순하고 더 복잡한 변형이 가능합니다. )
어떻게 find
이 문제를 방지 할 수 있습니다.
find
상대 디렉토리 -execdir
가 $PATH
포함 된 경우 조치 를 거부 하여이 보안 문제가 발생하지 않도록합니다 .
find
특정 상황에 따라 두 가지 진단 메시지를 제공합니다.
-
경우
.
에$PATH
(당신이 보았 듯이)는 말한다 다음 :find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)
.
특히 일반적인 경우에 대한 특별한 메시지가있을 수 있습니다 . -
–say
.
,- 이외의 상대 경로가foo
나타나고로$PATH
실행하면 다음find
과-execdir
같이 나타납니다.find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH
상대 경로를 전혀 사용하지 않는 것이 좋습니다 $PATH
.
디렉토리를 자동으로 변경하는 유틸리티를 사용할 때 특히 .
다른 상대 경로 $PATH
가있을 위험이 높아 지므로이 상황 find
에서는 사용할 수 없습니다 -execdir
.
그러나 상대 경로를 갖는 특히 .
, 당신이에 $PATH
본질적으로 위험하다 정말 최고의 어쨌든 피할 수있다. 위의 예에서 가상의 상황을 고려하십시오. 대신 실행하는 가정 find
, 앨리스는 단순히 cd
에이야 ~eve/shared/blah
및 실행됩니다 wc *.c
. blah
Eve의 wc
스크립트 가 포함 된 경우 do_evil
Alice로 실행됩니다.
답변
여기에 자세한 정보가 있습니다 . 또 다른 훌륭한 참고 자료는 여기에 있습니다 . 첫 번째 참조에서 인용하려면 :
-execdir 옵션은 GNU find에 도입 된보다 현대적인 옵션으로,보다 안전한 버전의 -exec를 작성하려는 시도입니다. -exec와 동일한 의미를 가지며 두 가지 중요한 개선 사항이 있습니다.
항상 파일에 대한 절대 경로를 제공합니다 (파일에 대한 상대 경로 사용은 -exec의 경우 실제로 위험합니다).
절대 경로를 제공하는 것 외에도 PATH 변수의 안전성을 검사합니다 (PATH env 변수에 점이 있으면 잘못된 디렉토리에서 실행 파일을 선택할 수 있음)
두 번째 참조에서 :
‘-execdir’조치는 현재 디렉토리가 $ PATH 환경 변수에 포함 된 경우 아무것도 수행하지 않습니다. ‘-execdir’은 파일을 찾는 동일한 디렉토리에서 프로그램을 실행하기 때문에 필요합니다. 일반적으로 이러한 디렉토리는 신뢰할 수없는 사용자가 쓸 수 있습니다. 비슷한 이유로 ‘-execdir’을 사용하면 실행할 명령 이름에 ‘{}’이 (가) 표시되지 않습니다.
답변
주요 문제는 시스템 PATH
폴더 의 값에 상대 폴더가 포함되어 있기 때문에 보안상의 이유로 find
명령은 바이너리를 실행할 수 없습니다. 잠재적으로 잘못된 프로그램을 실행할 수 있기 때문입니다.
예를 들어, 경고에 따라 PATH에 현재 디렉토리가있는 경우 다음과 같이 나타납니다.
현재 디렉토리는 PATH 환경 변수에 포함됩니다.
그리고 당신은 당신의 명령을 실행합니다 :
find . -type f -name 'partOfFileNames*' -execdir rm -- {} +
경우에 당신이 (로컬 스크립트해야합니다 rm
포함 된 실행 플래그를) rm -fr /
그것에서, 그것 때문에 대신 예상 실행, 모든 파일을 제거 할 수 있습니다 /bin/rm
당신이 실행하는 것, rm
그래서 아마 당신이 원하는 게 아니에요, 현재 디렉토리에서.
참고로, Travis CI ( GH # 2811 )에서 다음 오류로 실패하면 알려진 문제입니다 .
find : 상대 경로`./node_modules/.bin ‘은 PATH 환경 변수에 포함되어 있으며 find의 -execdir 액션과 결합하여 안전하지 않습니다. $ PATH에서 해당 항목을 제거하십시오
따라서 해결책은 PATH 변수에서 영향을받는 항목을 제거하는 것입니다.
PATH=`echo $PATH | sed -e 's/:\.\/node_modules\/\.bin//'`
drogus가 제안한 대로 . 이 버그의 진행 상황은 GH # 4862 에서 확인할 수 있습니다 .
Bash 버전 해결 방법은 다음과 같습니다.
PATH=${PATH//:\.\/node_modules\/\.bin/}
사용법 예 ( PATH
특정 명령으로 필터링 된 전달 ) :
env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f
답변
xargs
및 bash -c cd
해결 방법
좋아, 나는 포기한다.
find . -type f |
xargs -I '{}' bash -c 'cd "$(dirname "{}")" && pwd && echo "$(basename "{}")"'
sed
해결 방법
이전 해결 방법보다 약간 좋지 않습니다.
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" find . -execdir echo '{}' \;
테스트 케이스 :
[ "$(printf '/a/b::c/d:/e/f\n' | sed -E 's/(^|:)[^\/][^:]*//g')" = '/a/b:/e/f' ] || echo fail
에 대한 rename
: 특히, 당신은 또한 약간의 펄 정규식-FU으로 해결할 수 있습니다 /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971
RTFS 희망 분쇄
무시할 방법이 있기를 희망하는 사람들을 위해 find
하도록하겠습니다.
- https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847
- https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944
이것으로부터 우리는 경로 확인을 해제 할 수있는 방법이없는 것으로 보입니다.
검사하는 정확한 규칙은 다음 PATH
과 같습니다 /
. 가 비어 있거나로 시작하지 않으면 실패합니다 .