-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Updated by @adamsitnik:
Background and motivation
Since .NET 6, File.CreateSymboliLink allows for creating symbolic links (see the details below if you are interested about differences).
Details
| Feature | Hard Link | Symbolic Link | Junction |
|---|---|---|---|
| Points to | File data | Path | Path |
| Works for | Files only | Files & directories | Directories only |
| Cross-volume support | ❌ No | ✅ Yes | ❌ No |
| Broken if target is deleted | ❌ No | ✅ Yes | ✅ Yes |
| Requires admin privileges | ❌ No | ✅ Yes (usually) | ❌ No |
| Command | mklink /H | mklink or /D | mklink /J |
But on Windows, it is required to have "Create symbolic links" user right (typically granted only to administrators). However, starting with Windows 10 (build 14972) and later, non-admin users can create symbolic links if Developer Mode is enabled
This is because symbolic links can be exploited in security attacks, such as:
- Time-of-check/time-of-use (TOCTOU) race conditions.
- Privilege escalation by redirecting file operations.
To mitigate these risks, Microsoft restricted symlink creation to trusted users (admins) unless explicitly overridden by Developer Mode.
Creating hard links does not require special privileges beyond write access to the file system. Any user with write permissions to the source and destination directories can create hard links.
Hard links are less risky from a security standpoint:
- They point to the same file content on disk (same inode), not a path.
- They cannot span volumes or point to directories.
Symbolic links, by contrast, can point to arbitrary paths (including network shares), making them more prone to abuse.
Other languages offer the ability to create hard links, plenty of C# users like MSBuild implement their own helpers for that.
API Proposal
namespace System.IO;
public static partial class File
{
public static FileInfo CreateHardLink(string path, string pathToTarget);
}
public partial class FileInfo
{
public void CreateAsHardLink(string pathToTarget);
}API Usage
using System.IO;
// craete hard link
FileInfo fileInfo = File.CreateHardLink("./from.txt", "./to.txt");Alternative Designs
On Windows it's impossible to create a hard link for directory, that is why the API would be added only to the File class.
Risks
A file can be deleted only when all hard links pointing to it were deleted. This can lead into situation where users are unaware of that, keep creating files that are impossible to delete and eventually run out of space (potential DDoS?).