Skip to content

API Proposal: Add file and directory creation methods that take an ACL #31095

@JeremyKuhne

Description

@JeremyKuhne

Summary

.NET ACL (Access Control List) support is Windows specific (FileSecurity and DirectorySecurity). We keep support in System.IO.FileSystem.AccessControl and do not have references to the ACL types in base System.IO types in .NET Core (e.g. File, DirectoryInfo, FileStream). We have extension methods in System.IO.FileSystemAclExtensions to get and set ACLs instead. We do not, however, have methods that let you create files and directories with a specific ACL set.

This presents a few problems:

  • Potential security hole as files/directories can be accessed between creation and modification
  • Porting difficulties as there isn't a 1-1 API replacement
  • Stability issues with background processes (file filters) can prevent modifying ACLs right after creation (typically surfaces as a security exception)

We need to add helper methods that prevent these problems. Adding back API isn't feasible as FileStream lives in CoreLib and would require pulling down a rather large closure (above and beyond putting Windows specific API in front of Unix/cross-plat developers). Having these as extension methods also facilitates writing .NET Standard libraries.

Proposal

using System.Security.AccessControl;

namespace System.IO
{
    public static class FileSystemAclExtensions
    {
        // Add
        public static FileStream Create(
            this FileInfo fileInfo,
            FileMode mode,
            FileSystemRights rights,
            FileShare share,
            int bufferSize,
            FileOptions options,
            FileSecurity fileSecurity);

        public static void Create(
            this DirectoryInfo directoryInfo,
            DirectorySecurity directorySecurity);

        public static FileStream CreateFile(
            this FileSecurity fileSecurity,
            string path,
            FileMode mode,
            FileSystemRights rights,
            FileShare share,
            int bufferSize,
            FileOptions options);

        public static DirectoryInfo CreateDirectory(
            this DirectorySecurity directorySecurity
            string path);

        // Existing
        public static DirectorySecurity GetAccessControl(this DirectoryInfo directoryInfo);
        public static DirectorySecurity GetAccessControl(this DirectoryInfo directoryInfo, AccessControlSections includeSections);
        public static FileSecurity GetAccessControl(this FileInfo fileInfo);
        public static FileSecurity GetAccessControl(this FileInfo fileInfo, AccessControlSections includeSections);
        public static FileSecurity GetAccessControl(this FileStream fileStream);
        public static void SetAccessControl(this DirectoryInfo directoryInfo, DirectorySecurity directorySecurity);
        public static void SetAccessControl(this FileInfo fileInfo, FileSecurity fileSecurity);
        public static void SetAccessControl(this FileStream fileStream, FileSecurity fileSecurity);
}

Details

Heuristics would follow .NET Framework as closely as possible. Directory creation is the most important of the two as you can prevent malicious file access if the directory is locked from the start.

For directory creation we would likely include the same sources that System.IO.FileSystem uses as the directory creation helper there already sets a "default" security object and would just need to have an overload added (which would allow creation heuristics to match properly, including error states).

File creation is a bit more complicated as the logic may take a bit more refactoring, but we should strive to include the same sources as well.

Marking as 3.1 as internal partners are hitting this in porting efforts.

Related Issues

#27021

CC: @danmosemsft, @ericstj, @terrajobst

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions