쉘 스크립트에서 임시 파일을 안전하게 작성하고 액세스하려면 어떻게해야합니까?


14

스크립트를 실행할 때 /tmp공격자 (또는 악의적 인 내용)가 파일 /tmp/tmpfileformyscript.tmp을 생성 한 것으로 확인한 경우 (파일 에 대한 읽기 권한이없는 경우에도 ) 고정 된 이름 파일로 출력을 리디렉션 하면 보안 위험이 발생할 수 있음 을 읽었습니다. 예를 들어 스크립트를 실행할 때 파일 ln -s ~wildcard/.bashrc /tmp/tmpfileformyscript.tmp을 손상 시키는 심볼릭 링크 를 만들 수 있습니다 .bashrc.

대신에 다음과 같은 것을 사용할 수 있습니다 filename="tmpfile.tmp.$RANDOM" ; echo outputtext > "$filename".

그러나 캐싱을 위해 tmp 파일을 사용하고 싶을 때가 있습니다.이 경우 "tmpfile.tmp. *"가 일치하는 항목이 있는지 알고 싶은 경우 /tmp새 파일을 만드는 대신 해당 파일을 사용하십시오. 불행히도 test이에 상응하는 [ -f filename ]것은 내가 말할 수있는 한 파일 글 로빙을 지원하지 않습니다.

따라서 내 질문은 두 가지입니다.

  1. 임시 파일을 안전하게 만드는 방법은 무엇입니까? 가 "predictablename.$RANDOM"허용 연습이나 더 나은 (더 안전한, 쉬운) 방법은 무엇입니까?
  2. 파일을 쉽게 액세스하고 나중에 확인하여 파일의 존재를 확인하려면 predictablename어떻게해야합니까?

답변:


13

mktemp유틸리티를 사용하여 예측할 수없는 이름으로 임시 파일을 작성 하십시오 . POSIX에 의해 표준화되지는 않았지만 Linux뿐만 아니라 * BSD에서도 사용 가능합니다.

> /tmp/predictable.$RANDOM공격자가 스크립트를 통해 쓰기 권한이있는 파일을 덮어 쓰거나 임시 파일에 대한 액세스 권한을 부여 할 수있는 공격에 스크립트를 여는 ¹이기 때문에 좋은 선택이 아닙니다. 이것은 안전하지 않은 임시 파일 취약점입니다. mktemp파일을 안전하게 생성하고 (기호 링크가 포함되어 있어도 기존 파일을 덮어 쓰지 않음) 서비스 거부를 피하기 위해 충분히 예측할 수없는 이름을 사용하기 때문에이 취약점이 없습니다.

하나의 임시 파일을 작성하고 작업하기에 충분하지 않은 경우을 사용하여 임시 디렉토리를 작성 mktemp -d하고 작업하십시오.

mktemp$TMPDIR변수가 설정되어 /tmp있으면 설정을 다시 사용하도록주의를 기울 입니다.

점점 더 많은 배포판 TMPDIR이 개인 디렉터리로 설정되었습니다 ( 예 : UID /run/1234/tmp위치 1234). 이렇게하면 더 이상 사용자간에 임시 파일을 공유 할 수 없어 일시적인 파일 취약점의 위험이 사라집니다 (때로는 유용하지만 자주 사용되지 /tmp는 않지만 여전히 사용할 수는 없지만 TMPDIR).

재현 가능한 파일 이름이 필요한 경우 사용자의 홈 디렉토리 아래에 임의의 구성 요소없이 잘 정의 된 이름으로 파일을 작성하십시오. 최신 규칙은 XDG 사용자 디렉토리 사양 입니다. 데이터 손실없이 파일을 제거 할 수있는 경우 XDG_CACHE_HOME환경 변수를 기본값으로 사용하십시오 ~/.cache. 아마도 응용 프로그램의 이름을 딴 하위 디렉토리를 작성하고 거기에서 작업해야합니다.

CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"

¹ 뿐만 아니라 않습니다 $RANDOM만 32767 개 가능한 값이 필요하지만 그것도 많은 값을 시도하지 않고 예측하기 쉽다. Bash의 난수 생성기는 PID 및 최초 사용 시간에 의해 시드 된 LCG 입니다. Zsh는 rand시작 시간에 의해 시드 된 플랫폼 입니다. ATT Ksh는 randPID에 의해 시드 된 플랫폼 입니다. Mksh는 더 복잡하지만 여전히 보안 품질의 시드가없는 LCG입니다. 이들 모두는 상당히 큰 성공 가능성을 가진 다른 프로세스에 의해 예측 될 수 있습니다.


실제로 당신의 토론 $TMPDIR~/.cache내가 필요한 것입니다. 좀 더 생각한 후에 /tmp는 내가 원하는 유일한 이유 는 파티셔닝 이라는 것을 깨달았습니다. 따라서 캐시가 /home파티션을 채울 수 없었습니다 . 그러나이 유스 케이스의 경우 실제로 완전한 비 이슈이므로 하위 디렉토리는 ~/.cache필자의 요구에 완벽하게 부합하며 보안 문제를 피합니다.
와일드 카드

mktempAIX에서는 또는 Windows의 Git 쉘에서 사용할 수 없습니다. file.$RANDOM$RANDOM휴대용 솔루션 인 것 같습니다 . 는 $RANDOM$RANDOM배시 랜덤 결과 독립적 약한없는 가정하면, 2 ^ 32의 공간이 증가한다.

@jww Bash의 무작위 결과는 약합니다. LCG이며 예측할 수없는 많은 응용 프로그램에 충분히 적합하면서도 예측 가능한 수준입니다.
Gilles 'SO- 악마 그만해

9

mktemp는 이것을 위해 설계되었습니다. 매뉴얼 페이지에서 :

TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1
echo "program output" >> $TMPFILE

mktemp는 파일을 작성하거나 0이 아닌 종료 상태로 종료합니다. 논리 또는 (||)는 mktemp가 파일을 작성할 수없는 경우 스크립트가 종료되도록합니다. 이 명령 후에 파일을 사용할 수 있는지 확인할 수 있습니다. 다시 확인할 필요가 없습니다. 추가해야 할 유일한 것은 스크립트 끝에서 파일을 정리하는 것입니다.

그리고 아마도 스크립트가 신호에 의해 종료 될 때도 가능합니다. 그것이 필요한지 아닌지를 결정해야합니다.

둘 다 trap명령을 사용하여 수행 할 수 있습니다 .


아! 매우 유용합니다. 전화를 걸 필요가 없습니다 $RANDOM. 그러나 내 질문의 2 부 — 나중에 해당 파일에 액세스하거나 후속 스크립트 실행시 파일이 이미 존재하는지 확인할 수 있습니까? (매우 간단한 캐시를 구현하려면)
Wildcard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.