Excessive file read and write permissions

Trusting files that other users can modify

Description

In a multi-user environment, world-writable files allow other users to change their contents. If an application trusts and reads such a file, an attacker can alter configuration or data to change its behavior. Configuration files, token or key files, and allow-lists are examples where tampering can disable controls, load unintended paths, or cause external connections.

Potential impact

  • Data tampering that changes application behavior through false configuration or input.
  • Modified configuration or allow-lists that disable features, bypass checks, or enable dangerous options.
  • Denial of service when important files are overwritten with empty or invalid content.
  • Bypass of authentication or access controls, potentially leading to privilege escalation.

Remediation

  • Do not grant world-write access. Set POSIX permissions or ACLs to the exact permissions needed. Calling File.setWritable(true, true) alone does not remove existing group or other-user write permissions.
  • On POSIX file systems, pass attributes such as rw------- to Files.createFile or createTempFile so permissions are restricted at creation.
  • Verify the owner, actual permissions, and trustworthiness of existing content before reading. Reducing permissions does not undo tampering. Handle permission-change failures and validate or replace untrusted existing files.
  • If several users need write access, restrict it to a specific group or ACL rather than everyone.
  • Store sensitive files beneath trusted directories that only the owner can modify, and consider options that prevent following symbolic links.

Examples

Before

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(); // 공격자가 바꾼 내용을 그대로 신뢰
        }
    }
}

After

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();
        }
    }
}

Explanation:

  • Before: The application grants world-write access and then trusts the file when reading it. Another user can overwrite its contents, changing configuration or disrupting the service.
  • After: POSIX permissions of rw------- restrict group and other-user reads and writes. This example assumes a trusted owner and parent directory. Protect the path from replacement, and do not assume that tightening permissions makes an existing file's contents trustworthy.

References