ICFS-thesis/approach.tex
2025-05-23 13:30:01 +02:00

97 lines
8.1 KiB
TeX

\chapter{Interactively Controlled File System}
\label{icfs}
This chapter presents the solution developed for this thesis, the Interactively Controlled File System (ICFS), a filesystem layer designed to enhance access control through real-time user input.
ICFS provides users with direct control over filesystem access decisions. Unlike traditional systems relying on static policies, ICFS dynamically prompts users for authorisation via a graphical interface, ensuring decisions align with immediate contextual needs.
Key Features:
\begin{itemize}
\item User-Friendly Design: Requires no prior configuration or specialised knowledge. The intuitive interface eliminates complex terminology, enabling seamless interaction.
\item Dynamic Policy Enforcement: Permissions are established on-demand and stored for future reference, minimising repetitive prompts.
\item Granular Control: Policies apply at the process-file level, with options to generalise rules for broader categories, reducing user fatigue.
\item Backward Compatibility: Implemented via the FUSE framework, ICFS intercepts system calls without altering existing software workflows.
\end{itemize}
\section{Usage}
To deploy ICFS, the user selects a target directory and executes the command as shown in \autoref{icfs:usage:cmd}
\begin{figure}[!ht]
\begin{minted}{bash}
icfs <FUSE arguments> [mounpoint] [permission database] <ICFS arguments>
\end{minted}
\caption{Command that mounts ICFS over the folder denoted as [mounpoint], while using the permanent permission database stored in the file denoted as [permission database]. <ICFS arguments> and <FUSE arguments> denote ICFS arguments and libfuse arguments respectively.}
\label{icfs:usage:cmd}
\end{figure}
This mounts ICFS over the specified directory, enforcing access control for all subsequent interactions. While the name includes ``File System,'' ICFS operates as a filesystem layer , intermediating between the physical filesystem (e.g., ext4) and user processes. It preserves the appearance of the original filesystem while enforcing its own access logic (implementation details in \autoref{impl:fuse}).
\section{Access Control Model}
\label{icfs:model}
ICFS adopts a straightforward access control model:
\begin{itemize}
\item Subjects: Processes requesting access.
\item Objects: Files or directories undergoing access attempts.
\end{itemize}
When a process requests access (e.g., open, modify, delete) to a file without pre-existing permissions, ICFS generates an access dialogue (see Figure \ref{fig:dialogue}).
\begin{figure}[H]
\centering
\includegraphics[width=0.6\linewidth]{./images/icfs-dialogue-window.png}
\caption{ICFS Access Dialogue: Displays the process executable name, PID, and target file path. Users may adjust the file scope, toggle permanent permissions, or grant/deny access.}
\label{fig:dialogue}
\end{figure}
The dialogue contains three functional elements:
\begin{itemize}
\item Access Grant Buttons.
\begin{itemize}
\item Yes Button : Grants temporary access to the requested file to the requesting process only. If the user selects this option, the process is allowed to proceed with the requested access.
\item No Button : Denies access to the file for the current process. The filesystem returns an error (e.g., EACCES) to the requesting process, mimicking standard permission denial behavior.
\end{itemize}
\item Permanent Permission Checkbox: A toggle labelled ``Permanent'' allows the user to persist the access decision beyond the current process.
If checked , the permission rule (allow/deny) is stored in a local configuration database. The rule then applies to all future access attempts by processes (and any of their child processes) with an executable filename matching the requesting process.
If unchecked , the decision applies only to the requesting process and it's child processes. That is, the process can actually access the file multiple times with this permission.
Permissions granted with this box toggled on (off) will from now on be referred to as ``permanent'' (``temporary'').
\item File Path Substitution Field: A text input field pre-filled with the absolute path of the requested file. Users may edit this field to modify scope of the permission (e.g., granting access to all files in the parent directory instead of a single file). If user intends to allow the process to all files in a directory, its path has to end with ``\verb|/|'' character.
\end{itemize}
Behaviour changes slightly, if the operation is performed on a directory or a symbolic link: If the file is a directory, only changing the access mode and removal require permission from the user. With symbolic links, following is always permitted. If a process attempts to create a file, it is automatically granted temporary access to the file it has created.
To resolve situations, where user sets conflicting permissions with different scopes, only the more specific permission's effect is applied. For example, if user first allows a process to access \verb|~/Documents/book.pdf|, but later also denies access to \verb|~/Documents/|, then the process is allowed to access \verb|~/Documents/book.pdf|, but no other files in \verb|~/Documents/|.
This model addresses five key limitations of traditional systems:
\begin{itemize}
\item Reactive Configuration: No upfront setup required; permissions emerge organically.
\item Temporary Permissions: Users may limit access to a single instance of a program.
\item Scalable Granularity: Policies adapt from specific files to broader categories.
\end{itemize}
The remaining two criteria are analysed in the next section.
\section{Least Privilege vs. Usability}
Balancing the principle of least privilege with usability posed the greatest design challenge. Strict enforcement -- prompting for every access attempt -- would minimise risk but overwhelm users.
To reduce friction, ICFS needs to keep the number of dialogues to minimum. This necessitates avoiding prompts for actions likely to be safe. However, we still aim to avoid granting excessive privileges by default.
When ICFS is initially started, no user decisions are known, and thus no processes have access to protected files. Each new access attempt triggers a privilege escalation request via the access dialogue.
Applying this rule strictly to all filesystem objects -- including directories and symbolic links -- with intelligent user decisions, would perfectly adhere to the principle of least privilege. However, such strictness would render ICFS excessively cumbersome to use. To mitigate this, the rule has been relaxed to compromise user data as little as possible.
Firstly, Unlike POSIX, ICFS does not restrict directory visibility. While this exposes file structures, directory names rarely contain sensitive data.
Second, processes are permitted to create files without restriction. This decision is based on the observation that many programs create auxiliary and temporary files. For instance, the pdfLaTeX compiler creates 21 files in the source directory for this thesis, only 10 of which are human-editable; the remaining files are intermediary output of the compiler. Requiring the user to grant permissions for all these files would more than double the decision-making burden.
While this approach increases the potential for malicious processes to disrupt other processes, the risk is considered lower than the burden of constantly prompted permission requests. We discuss these limitations in \autoref{eval:sec:create}.
Thirdly, all access permissions apply to the child processes too. Since only the parent process has control over starting its children, it is theoretically safe to presume that non-malicious processes won't spawn malicious child processes. Of course, this presumption is not necessarily true in reality: programs contain a plethora of bugs some of which might as well allow for arbitrary code execution, and thus starting of unwanted programs as its children.
However, we decided that the burden caused by having to allow access to all its children is way too high. For example, the Neovim text editor may spawn up to five additional child processes that analyse the opened file, such as code linters, formatters and debuggers.