This is actually an extremely difficult problem to solve.
Agreed
How do you distinguish between the actions of a user [...] and the
actions of a program [...]
You can't.
However, you can constrain what actions a program can accomplish. I
see this as what UAC (and MIC, and related technologies)
fundamentally accomplish - Windows is finally acknowledging that yes,
applications ARE the user's agent and receive their authority to
perform actions from the permissions granted to the user; but, ALL
applications that the user runs do not need to be granted ALL of
these permissions, and it should be up to the user to decide how
their authority to do things is delegated.
I think that allowing the user to choose whether a program runs with
super-limited or super-elevated permissions is a good start, but is a
pretty blunt instrument where a precision instrument is needed.
I would like to see this support expanded. I think every .exe should
have an SID associated with it, and the user should be able to set
grant/deny privileges for programs to the securable objects that THAT
USER has access to. These program security permissions don't REPLACE
user permissions; I see them augmenting them. If a user has access to
a securable object, they should be able to choose which programs can
use that access. I see these permissions being assigned to an object
on a per-user basis (i.e. how one user decides to allow programs to
access the securable objects they have access to should not affect
other user accounts).
Also think files should be assigned two owners - one the user who
created it, and two the program that created it (wouldn't that be
useful - even if it wasn't used for anything security-wise!).
And, the user should be able to choose what specific access
privileges each .exe can have based on the access privileges assigned
the user (i.e. the user has SeDebug privilege, but only visual studio
can use the SeDebug privilege)
I also think you should be able to group programs into program groups
(similar to user groups), and then have appropriate default
application security attributes on files (i.e. say for program files:
All programs read-only, installers create new directory and full
access to created folders).
This way, programs could specify the built-in group they want to
belong to in their manifest, and then the UAC prompt would be able to
specify how much access they are requesting, and the user would be
able to say yes/no, or even change that access level from the dialog
box ("no, i dont want you to be in the installers group, I want you
to be in this custom security group that I have defined...")
The way I see it, whenever a process is created, it receives the
access token of the user, and then filters that access to the
specific access the user wants it to be able to have (based on the
SID assigned to its .exe file, what program-group(s) it belongs to,
even based on what access token the process creating it has). When
the process accesses a securable object, if the user has the desired
access to the object, it then checks to see if the program has the
desired access, and if not returns access denied.
To guard against privilege escalation, a process that spawns another
process that is in a different program-group or has less restrictive
privileges could throw UAC, but not the other way around (and/or, any
program that spawns another program that meets or exceeds certain
privileges always throws UAC, and does not meet/exceed never throws
UAC).
You could also give the user the choice to not prompt with UAC when
certain programs/program groups spawns another process, but instead
only allow the spawned processes the least common denominator
security privileges afforded both processes (this way you don't bug
the user but the spawned process has no way of exceeding the
privileges the spawning process has).
And, all of these UAC settings could be customized for each program
group. And, you might even allow for adding UAC-spawn metadata into
file/registry/object attributes (i.e. for program files, write always
spawns UAC).
In any case, having multple privilege levels available via UAC and
expanding the amount of granular control these privilege levels have
over the programs, however implemented, should result in more
security (no more full-admin or no-admin, a true 'least privileged
access' environment) and better customization and saneness for the
user (the ability to assign programs to a wider range of privilege
levels and then control when and how UAC is prompted should create a
nice way to reduce the amount of UAC prompts without loosing much
security).