설명
멀티 유저 환경에서 파일에 전역 쓰기(world-writable) 권한이 있으면, 다른 사용자가 그 파일 내용을 임의로 바꿀 수 있습니다. 애플리케이션이 해당 파일을 신뢰하고 읽으면, 공격자는 설정값이나 데이터 조작을 통해 동작을 바꾸거나 오동작을 유도할 수 있습니다. 예를 들어 설정 파일, 토큰/키 파일, 허용 목록 등 신뢰 입력을 가정하는 파일을 월드 쓰기로 둔 뒤 읽으면, 제3자가 내용을 바꿔 서비스 설정 변조, 임의 경로 로드, 의도치 않은 외부 연결 등을 유발할 수 있습니다.
잠재적 영향
- 데이터 변조: 다른 사용자가 파일 내용을 바꿔 잘못된 설정/데이터로 애플리케이션 동작을 변경할 수 있음
- 설정 위·변조: config, allowlist 등을 조작해 기능 비활성화, 우회, 위험한 옵션 활성화를 유도할 수 있음
- 서비스 장애(DoS): 중요 파일을 빈 내용/쓰레기로 덮어써 애플리케이션 예외 발생 및 중단을 초래할 수 있음
- 보안 통제 우회: 인증/접속 제어 관련 파일을 조작해 우회 또는 권한 상승 상황을 만들 수 있음
해결 방법
- 최소 권한 원칙: 전역 쓰기를 허용하지 말고 POSIX 권한이나 ACL을 필요한 권한으로 정확히 설정하세요.
File.setWritable(true, true)만 호출하면 기존 그룹·다른 사용자 쓰기 권한은 제거되지 않습니다. - 안전한 생성: POSIX 파일 시스템에서는
Files.createFile/createTempFile에rw-------같은 파일 속성을 전달해 생성 시점부터 권한을 제한하세요. - 읽기 전 검증: 소유자, 실제 권한과 내용의 신뢰성을 확인하세요. 권한을 줄여도 이미 변조된 내용은 복구되지 않습니다. 권한 변경 실패를 처리하고, 신뢰할 수 없는 기존 파일은 검증하거나 교체하세요.
- 그룹/ACL 사용: 여러 사용자 쓰기가 꼭 필요하면 전역이 아닌 특정 그룹 또는 ACL로 제한
- 민감 파일 경로 보호: 신뢰 디렉터리(소유자만 쓰기 가능) 아래에 저장하고, 심볼릭 링크 따라가기 금지 옵션 고려
예시
변경 전
java
import java.io.*;
import java.nio.file.*;
public class InsecureConfigReader {
// 취약: 월드 쓰기 후 같은 파일을 신뢰하고 읽음
public static String loadApiToken() throws Exception {
File f = new File("/var/app/config/token.txt");
if (!f.exists()) {
f.getParentFile().mkdirs();
f.createNewFile();
}
// 잘못된 권한: 모든 사용자에게 쓰기 허용
f.setWritable(true, false); // world-writable
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
return br.readLine(); // 공격자가 바꾼 내용을 그대로 신뢰
}
}
}
변경 후
java
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
public class SecureConfigReader {
public static String loadApiToken() throws Exception {
Path path = Paths.get("/var/app/config/token.txt");
Files.createDirectories(path.getParent());
// 1) POSIX 권한을 소유자 전용으로 강제 (rw-------)
Set<PosixFilePermission> ownerOnly = PosixFilePermissions.fromString("rw-------");
if (Files.notExists(path)) {
Files.createFile(path, PosixFilePermissions.asFileAttribute(ownerOnly));
} else {
// 기존 파일이라면 Others/Group 쓰기 제거
Files.setPosixFilePermissions(path, ownerOnly);
}
// 2) 추가 방어: JVM File API로도 world write 제거 후, 소유자 쓰기만 허용
File f = path.toFile();
f.setWritable(false, false); // group/others 쓰기 제거
f.setWritable(true, true); // owner만 쓰기 허용
try (BufferedReader br = Files.newBufferedReader(path)) {
return br.readLine();
}
}
}
설명:
- 변경 전: 파일에 월드 쓰기 권한을 부여한 채로 같은 파일을 신뢰하고 읽습니다. 다른 사용자가 내용을 덮어쓸 수 있어 설정 변조, 잘못된 동작, 서비스 장애가 발생할 수 있습니다.
- 변경 후: POSIX 권한을
rw-------로 설정하여 그룹·다른 사용자의 읽기와 쓰기를 제한합니다. 예시는 신뢰할 수 있는 소유자와 상위 디렉터리를 전제로 합니다. 공격자가 경로를 교체할 수 없도록 보호하고, 기존 파일은 권한 변경만으로 내용까지 신뢰하지 마세요.