분명히 다음을 실행하십시오.
perl -n -e 'some perl code' *
또는
find . ... -exec perl -n -e '...' {} +
( -p
대체와 동일 -n
)
또는
perl -e 'some code using <>' *
이 사이트에 게시된 농담에 자주 나타나며 보안 위험을 초래합니다. 어떻게 되어가나요? 그것을 피하는 방법?
답변1
문제는 무엇입니까
첫째, 많은 유틸리티와 마찬가지로 -
.
sh -c 'inline sh script here' other args
에 전달된 다른 인수는 다음과 같습니다 inline sh script
.perl
perl -e 'inline perl script here' other args
더 많은 옵션을 보려면 다른 매개변수를 스캔하세요.진주우선, 인라인 스크립트가 아닙니다. 예를 들어 -eBEGIN{do something evil}
현재 디렉터리에 호출된 파일이 있는 경우
perl -ne 'inline perl script here;' *
(가 있든 없든 -n
) 나쁜 일을 할 것입니다.
--
다른 유틸리티와 마찬가지로 해결 방법은 닫는 태그( ) 옵션을 사용하는 것입니다 .
perl -ne 'inline perl script here;' -- *
그러나 그럼에도 불구하고 (in-place) 없이 ( 모드), ( 모드), / ( 모드) 중 하나를 사용할 <>
때마다 어떤 연산자를 사용하는지 에 따라 여전히 위험합니다 .-n
sed -n
-p
sed
-a
-F
awk
-i
문제는 perldoc perlop
설명서에 설명되어 있습니다.
이 특수 연산자는 시퀀스에 전달된 각 인수에서 입력의 한 줄(기본적으로 레코드는 행임)을 읽는 데 사용됩니다 @ARGV
.
존재하다:
perl -pe '' a b
-p
while (<>)
코드 주위에 루프가 있음을 의미합니다 (여기서는 비어 있음).
<>
먼저 a
파일을 열고 파일이 모두 소진될 때까지 한 번에 한 줄씩 레코드를 읽은 다음 엽니다 b
.
문제는 파일을 열 때 첫 번째 안전하지 않은 형식을 사용한다는 것입니다 open
.
open ARGV, "the file as provided"
인수가 다음과 같은 경우 이 형식을 사용하세요.
"> afile"
,afile
쓰기 모드로 열립니다."cmd|"
, 실행되고cmd
출력을 읽습니다."|cmd"
, 에 쓸 입력 스트림을 엽니다cmd
.
예를 들어:
perl -pe '' 'uname|'
라는 파일의 내용 uname|
(완전히 유효한 파일 이름)을 출력하지 않고 명령의 출력을 출력합니다 uname
.
실행 중인 경우:
perl -ne 'something' -- *
누군가가 현재 디렉터리에 (역시 완벽하게 유효한 파일 이름)이라는 이름의 파일을 생성했습니다 rm -rf "$HOME"|
(예를 들어, 디렉터리에 다른 사람이 한 번 쓴 경우, 신뢰할 수 없는 아카이브를 추출한 경우, 신뢰할 수 없는 명령을 실행한 경우, 또는 다른 취약점이 있는 경우). 다른 소프트웨어가 악용되고 있는 경우) 큰 문제가 발생합니다. 문제 영역은 자동으로 파일을 처리하는 도구라는 점을 인식하는 것이 중요합니다.사람들유사한 영역 /tmp
(또는 이러한 도구가 호출할 수 있는 도구).
> foo
이름이 인 foo|
파일 |foo
에 문제가 있습니다. 그러나 어느 정도는 < foo
앞 foo
이나 뒤에 ASCII 공백 문자(공백, 탭, 줄 바꿈, cr... 포함)가 있으면 이러한 파일이 처리되지 않거나 잘못된 파일이 생성된다는 의미입니다.
또한 일부 멀티바이트 문자 세트(예: ǖ
BIG5-HKSCS)의 일부 문자는 바이트 0x7c로 끝납니다 |
.
$ printf ǖ | iconv -t BIG5-HKSCS | od -tx1 -tc
0000000 88 7c
210 |
0000002
따라서 이 문자 집합을 사용하는 로캘에서는
perl -pe '' ./nǖ
./n\x88
명령을 실행하려고 시도합니다perl
아니요사용자의 로캘로 파일 이름을 해석해 보세요!
수정/해결 방법
perl
AFAIK, 시스템 전체의 안전하지 않은 기본 동작을 완전히 변경할 수는 없습니다 .
첫째, 파일 이름의 시작과 끝 부분에 있는 문자에서만 문제가 발생합니다. 그렇다면 언제 perl -ne '' *
또는 perl -ne '' *.txt
질문이 있습니까?
perl -ne 'some code' ./*.txt
이제 모든 매개변수가 ./
, , , 공백이 아닌 것으로 시작하고 끝나기 때문이 아닙니다. 보다 일반적으로는 접두사를 추가하는 것이 좋습니다..txt
-
<
>
|
구체그리고 ./
. 이는 또한 처음에 다른 많은 유틸리티 호출이나 파일과 관련된 -
문제를 방지합니다 -
(여기서는 더 이상 옵션 닫는( --
) 태그가 필요하지 않음을 의미합니다).
-T
개방형 모드를 사용하면 taint
도움이 될 수 있습니다. 이러한 악성 파일이 발견되면 명령이 중단됩니다( >
and |
케이스 에만 해당되고 <
or 공백에는 해당되지 않음).
이는 위험한 일이 진행되고 있음을 경고하므로 이러한 명령을 대화식으로 사용할 때 매우 유용합니다. 그러나 일부 자동화된 처리를 수행할 때는 이상적이지 않을 수 있습니다. 누군가가 이를 수행할 수 있다는 의미이기 때문입니다.처리파일을 생성하는 것만으로는 실패합니다.
이름에 관계없이 모든 파일을 처리하려면 다음을 사용할 수 있습니다.ARGV::readonly
perl
CPAN의 모듈(불행히도 일반적으로 기본적으로 설치되지 않습니다.) 이것은 매우 짧은 모듈이며, 수행되는 작업은 다음과 같습니다.
sub import{ # Tom Christiansen in Message-ID: <24692.1217339882@chthon> # reccomends essentially the following: for (@ARGV){ s/^(\s+)/.\/$1/; # leading whitespace preserved s/^/< /; # force open for input $_.=qq/\0/; # trailing whitespace preserved & pipes forbidden }; };
기본적으로 예를 들어 " foo|"
변환하여 @ARGV를 정리합니다 ."< ./ foo|\0"
BEGIN
명령문에서도 동일한 작업을 수행할 수 있습니다 perl -n/-p
.
perl -pe 'BEGIN{$_.="\0" for @ARGV} your code here' ./*
여기서는 우리가 사용하는 가정을 기반으로 이를 단순화합니다 ./
.
그러나 이것(and)의 부작용은 후행 NUL 문자가 에 표시된다는 것 ARGV::readonly
입니다 .$ARGV
your code here
업데이트 2015-06-03
perl
v5.21.5 이상에는 <<>>
유사하게 작동하는 새로운 연산자가 <>
있지만아니요특별대우를 받습니다. 매개변수는 파일 이름으로만 처리됩니다. 따라서 이러한 버전을 사용하면 이제 다음과 같이 작성할 수 있습니다.
perl -e 'while(<<>>){ ...;}' -- *
--
(잊 거나 사용 하지 마세요 ./*
) 파일을 덮어쓰거나 예상치 못한 명령을 실행하게 될 것을 걱정하지 마세요.
-n
/그러나 -p
여전히 위험한 <>
형식을 사용합니다. 그리고 심볼릭 링크가 여전히 추적되고 있으므로 신뢰할 수 없는 디렉토리에서 사용해도 안전하다는 의미는 아닙니다.
답변2
또한@Stéphane Chazelas의 답변-i
, 명령줄 옵션을 사용하면 이에 대해 걱정할 필요가 없습니다.
$ perl -pe '' 'uname|'
Linux
$ perl -i -pe '' 'uname|'
Can't open uname|: No such file or directory.
-i
옵션을 perl
사용할 때통계자료파일을 처리하기 전에 파일 상태를 확인하십시오.
$ strace -fe trace=stat perl -pe '' 'uname|'
stat("/home/cuonglm/perl5/lib/perl5/5.20.1/x86_64-linux", 0x7fffd44dff90) = -1 ENOENT (No such file or directory)
stat("/home/cuonglm/perl5/lib/perl5/5.20.1", 0x7fffd44dff90) = -1 ENOENT (No such file or directory)
stat("/home/cuonglm/perl5/lib/perl5/x86_64-linux", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
Process 6106 attached
Linux
Process 6105 suspended
Process 6105 resumed
Process 6106 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
$ strace -fe trace=stat perl -i -pe '' 'uname|'
stat("/home/cuonglm/perl5/lib/perl5/5.20.1/x86_64-linux", 0x7fffdbaf2e50) = -1 ENOENT (No such file or directory)
stat("/home/cuonglm/perl5/lib/perl5/5.20.1", 0x7fffdbaf2e50) = -1 ENOENT (No such file or directory)
stat("/home/cuonglm/perl5/lib/perl5/x86_64-linux", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("uname|", 0x785f40) = -1 ENOENT (No such file or directory)
Can't open uname|: No such file or directory.