현재 다음을 사용하는 bash 스크립트를 작성 중입니다.inotifywait
사용자가 제공한 파일 및 디렉터리 목록에 대해 특정 작업을 수행합니다.
그게 내 관심을 끌었어많은 쉘 도구와 달리 inotifywait
사용할 수 없습니다 \0
.주입 공격 가능성특별히 고안된 법적 파일 이름(줄바꿈 포함)을 갖습니다.
내 스크립트가 불필요한 취약점을 유발하지 않도록 이 문제를 해결하고 싶습니다. 내가하는 방법은 다음과 같습니다.
inotifywait
watch에 전달된 모든 파일/경로 의 후행 백슬래시가 제거되었는지 확인하세요 .- 다음과 같이 출력을 생성
inotifywait
하도록 출력 형식을 지정합니다 .--format "%e %w%f//"
<EVENT LIST> <FILE PATH>//
- 줄 끝에서 발견된
inotifywait
모든 항목을 sed로 파이프 출력합니다.//
\0
- Bash
while read
루프를 사용하여\0
구분된 레코드 읽기 - 이는 첫 번째 레코드 이후의 모든 후속 레코드에 추가 선행 개행 문자가 있음을 의미합니다. 이건 벗겨진거네
- 그런 다음 각 레코드는 첫 번째 공백에서 분할될 수 있습니다. 공백이 이벤트 목록(inotifywait에 따라 쉼표로 구분됨)이 되기 전, 공백이 이벤트와 연결된 전체 경로 이름 이후
#!/bin/bash
shopt -s extglob
watchlist=("${@}")
# Remove trailing slashes from any watchlist elements
watchlist=("${watchlist[@]%%+(/)}")
# Reduce multiple consecutive slashes to singles as per @meuh
watchlist=("${watchlist[@]//+(\/)/\/}")
printf -vnewline "\n"
inotifywait -qrm "${watchlist[@]}" --format "%e %w%f//" | \
sed -u 's%//$%\x00%' | \
while IFS= read -r -d '' line; do
line="${line#${newline}}"
events="${line%% *}"
filepath="${line#* }"
printf "events=%s\nfilepath=%q\n" "$events" "$filepath"
done
내가 아는 한, 이것은 공백, 개행, 따옴표 등 흥미로운 문자가 포함된 파일/경로 이름을 처리합니다. 그러나 이것은 다소 촌스러운 패치워크처럼 보입니다.
이 질문의 목적에 따라 ${watchlist[]}
배열은 명령줄 인수에서 복사되었지만 배열은 다른 방식으로 구성될 수 있으며 "흥미로운" 문자가 포함될 수 있습니다.
이를 깨뜨릴 수 있는 악의적인 경로가 있나요? 특정 이벤트에 대해
$events
및 변수의 내용이 올바르지 않은 경우에도 마찬가지입니까 ?$filepath
이것이 방수라면 더 깨끗한 방법이 있습니까?
나는 쉽게 글을 쓸 수 있다는 것을 알고 있습니다.씨inotify_add_watch()
이 문제를 해결하려면 Friend 프로그램을 호출하세요 . 하지만 지금은 다른 종속성으로 인해 bash에서 작업하고 있습니다.
나는 이것을 여기에 게시할지, codereview.SE 또는 심지어 메인 so.SE에 게시할지에 대해 갈등을 겪었습니다.
답변1
가지다십자가NUL로 구분된 출력이 지원되며 다음과 같이 사용할 수 있습니다.
#!/bin/bash
shopt -s extglob
watchlist=("${@}")
# Remove trailing slashes from any watchlist elements
watchlist=("${watchlist[@]%%+(/)}")
printf -vnewline "\n"
inotifywait -qrm "${watchlist[@]}" --format "%e %w%f%0" | \
while IFS= read -r -d '' line; do
events="${line%% *}"
filepath="${line#* }"
printf "events=%s\nfilepath=%q\n" "$events" "$filepath"
done
--format이 사용될 때 이 버전은 기본적으로 줄바꿈을 추가하지 않습니다.
답변2
로 watchlist
교체하려면 정리가 필요합니다 . 다음과 같은 이름의 디렉토리를 고려하십시오 ( 여기서 개행 문자는 어디에 있습니까).//
/
\nabc
\n
$ mkdir t
$ mkdir t/$'\nabc'
$ touch t/$'\nabc'/x
디렉터리를 살펴보면 t//$'\nabc'
줄 끝에 가짜 출력이 표시됩니다.//
$ inotifywait -m -r t//$'\nabc' --format "%e %w%f//"
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
OPEN t//
abc/x//
ATTRIB t//
abc/x//
CLOSE_WRITE,CLOSE t//
abc/x//
얻는 -c
대신에 참고하세요.--format
데이터 세트스타일 출력은 파일 이름을 줄 바꿈으로 큰따옴표로 묶었지만 구문 분석하기가 더 어렵습니다. 제 경우에는 위 예의 코어 덤프입니다.
-c
합계 출력 예 touch t/$'new\nfile'
:
t/,CREATE,"new
file"