Skip to content

VNX-277: Insecure Inherited Permissions

Detects permission sets that everything created afterwards inherits and that let anyone write: a process umask that leaves others-write open (umask(0), os.umask(0), process.umask(0), shell or Dockerfile umask 000, systemd UMask=0000), a Windows NULL DACL, an inheritable SDDL allow ACE for Everyone, and a .NET FileSystemAccessRule/RegistryAccessRule granting Everyone or Users write with inheritance.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-277
Severity Low
SARIF level note
Kind sast
Languages C, C++, Python, Go, PHP, Ruby, JavaScript / TypeScript, Rust, Shell, Dockerfile, C#
CWE CWE-277
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags inherited-permissions umask acl file-permissions cwe-277
Source internal/sast/rules/vnx-277.rego

Overview

VNX-277 maps to CWE-277: Insecure Inherited Permissions. Some permission settings are not applied to one object but inherited by every object created after them. If that inherited set is too broad, every file, directory, pipe or registry key the program creates is too broad as well, including those created by libraries and child processes that never asked for it.

Reported:

  • A umask that leaves others-write open. umask(0), umask(0000), umask(020) in C and C++, os.umask(0) and python-daemon DaemonContext(umask=0o000) in Python, libc::umask(0), nix umask(Mode::empty()) and a Daemonize builder’s .umask(0o000) in Rust, syscall.Umask(0)/unix.Umask(0) in Go, umask(0) in PHP, File.umask(0) in Ruby, process.umask(0)/process.umask("0000") in Node.js, umask 000/umask 0/umask a=rwx in shell scripts and Dockerfile RUN lines, and UMask=0000 in a systemd unit. Libraries create files with mode 0666 and directories with 0777 and rely on the umask to remove group and other write; with a zero umask they become world-writable.
  • A Windows NULL DACL. SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE) grants everyone full access to whatever is created with that descriptor.
  • An inheritable SDDL ACE for a broad group. An allow ACE with OI/CI that gives Everyone (WD), Anonymous (AN), Authenticated Users (AU) or Users (BU) generic all or write rights, such as D:(A;OICI;GA;;;WD).
  • A .NET access rule inherited by children. new FileSystemAccessRule(...) or new RegistryAccessRule(...) that allows Everyone, Users, Authenticated Users or the World SID FullControl, Modify or write rights with ContainerInherit/ObjectInherit.

What Gets Flagged

setsid();
umask(0);            // FLAGGED: everything the daemon creates later inherits it
chdir("/");
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);   // FLAGGED: NULL DACL
// FLAGGED: Everyone gets FullControl on the directory and everything below it
security.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.None, AccessControlType.Allow));
umask 000            # FLAGGED
[Service]
UMask=0000           # FLAGGED: every file the service creates is world-writable

What Is Not Flagged

  • A umask that masks others-write: 022, 027, 077, 002.
  • Reading the umask (old = os.umask(0); os.umask(old), $mask = umask();), and a zero umask restored within a few statements, to the saved value or to a closing literal (umask(0); mkfifo(p, 0620); umask(022);), such as around an os.open(path, flags, 0o600) in a try/finally: that sets one exact mode on purpose and leaves nothing behind.
  • A umask taken from a variable, a real DACL (SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE)), ACEs for SYSTEM or Administrators, read-only or non-inheritable rules, and deny rules.
  • Test code and the calls in comments or strings.

Remediation

umask(027);   /* or 077 for private data */
var rule = new FileSystemAccessRule(serviceAccountSid, FileSystemRights.Modify,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.None, AccessControlType.Allow);

Build a security descriptor that names the principals that need access instead of passing a NULL DACL.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-277
// nosec vnx-277

Or record an ignore rule: vulnetix ignore add --rule vnx-277 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-277.rego, cli/internal/sast/docs/vnx-277.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.