Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@
**Vulnerability:** Calling `open(2)` without `O_CLOEXEC` causes the file descriptor to leak to child processes, and passing Swift `String` paths implicitly to C functions can result in unsafe filesystem representations.
**Learning:** Child processes inheriting the PID lock file descriptor could prevent the lock from being released. Using `withUnsafeFileSystemRepresentation` is the only safe way to bridge file paths to POSIX APIs.
**Prevention:** Always include `O_CLOEXEC` when opening files with POSIX APIs, and use `URL(fileURLWithPath:).withUnsafeFileSystemRepresentation` to obtain the correct C-string pointer.
## 2024-06-03 - Unrestricted Permissions on Automatically Created Directories
**Vulnerability:** The `~/.cacheout` log directory was created without explicit restrictive permissions.
**Learning:** Directories created via `FileManager.default.createDirectory` without explicit `.posixPermissions` attributes inherit the user's default umask, potentially allowing other local users to read sensitive files. Furthermore, because `createDirectory` only applies attributes on newly created directories, `setAttributes` must be used afterward to ensure pre-existing directories are also secured.
**Prevention:** Always specify `attributes: [.posixPermissions: 0o700]` when creating directories that store sensitive user information, and follow it up with a `setAttributes` call to harden any pre-existing directories.
7 changes: 6 additions & 1 deletion Sources/Cacheout/Cleaner/CacheCleaner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ actor CacheCleaner {
private func logCleanup(category: String, bytesFreed: Int64) {
let logDir = FileManager.default.homeDirectoryForCurrentUser
.appendingPathComponent(".cacheout")
try? FileManager.default.createDirectory(at: logDir, withIntermediateDirectories: true)
try? FileManager.default.createDirectory(
at: logDir,
withIntermediateDirectories: true,
attributes: [.posixPermissions: 0o700]
)
try? FileManager.default.setAttributes([.posixPermissions: 0o700], ofItemAtPath: logDir.path)

let logFile = logDir.appendingPathComponent("cleanup.log")
let size = ByteCountFormatter.sharedFile.string(fromByteCount: bytesFreed)
Expand Down
Loading