Skip to content

[P1] init의 .dpt/.gitignore 심볼릭 링크 대상 덮어쓰기 방지 #18

Description

@leehyowon14

요약

dpt init.dpt/.gitignore가 심볼릭 링크인지 확인하지 않고 os.WriteFile을 호출합니다. 기존 링크가 다른 파일을 가리키면 대상이 고정된 gitignore 내용으로 truncate됩니다.

  • 검토 기준: main@4e87765f95c106edb3c956cfad2abc1db64c0c39
  • 판정: CONFIRMED
  • 우선순위: P1

영향

공격자가 임의 바이트를 선택할 수 있는 쓰기는 아니지만, 실행 사용자가 쓸 수 있는 파일을 다음 14바이트로 교체할 수 있습니다.

*
!.gitignore

발생 조건 및 확인 범위

  • 유효한 pack.mcmeta가 있을 것
  • dpt.json은 없을 것
  • .dpt/.gitignore가 쓰기 가능한 파일을 가리키는 링크일 것
  • 사용자가 dpt init을 실행할 것

macOS에서 파일 링크와 .dpt -> .. 형태를 확인했습니다. Windows reparse point는 확인하지 않았습니다.

재현 및 검증 방법

go build -o /tmp/dpt-init-repro ./cmd/dpt
pack="$(mktemp -d /tmp/dpt-init-pack.XXXXXX)"
printf '%s\n' '{"pack":{"pack_format":71,"description":"repro"}}' > "$pack/pack.mcmeta"
printf 'ORIGINAL IMPORTANT CONTENT\n' > "$pack/important.txt"
mkdir -p "$pack/.dpt"
ln -s ../important.txt "$pack/.dpt/.gitignore"
/tmp/dpt-init-repro init --pack "$pack"
cat "$pack/important.txt"
readlink "$pack/.dpt/.gitignore"

현재 대상 내용이 *\n!.gitignore\n로 변경되고 링크 자체는 유지됩니다.

기대 동작

기존 .dpt/.gitignore가 일반 파일인지 확인하고 링크나 특수 파일이면 중단해야 합니다. 새 파일을 만들 때도 링크를 따라가지 않는 원자적 생성 방식을 사용해야 합니다.

완료 조건

  • .dpt/.gitignore가 링크이면 명확한 오류로 종료한다.
  • 링크 대상 내용은 변경되지 않는다.
  • .dpt 자체가 링크인 경우도 외부에 쓰지 않는다.
  • 상대·절대·중첩 링크 회귀 테스트를 추가한다.
  • 기존 정상 일반 파일 처리 정책을 명시한다.
  • go test ./..., go vet ./..., 관련 race 테스트가 통과한다.

관련 코드

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions