Here is a capsule summary of the problem of the confused deputy.

When I wrote The Confused Deputy in 1988, I was unaware of the Unix system call setuid(). Hal Finney pointed out that setuid() solved the problem that I had described. This is true but setuid() fails to solve slightly more general problems. Hal’s note leads to other interesting observations as well.

This page has an excellent brief definition of the problem.

Fred Spiessens has written this explanation of the confused deputy. Kragen Sitaker has written about capability security and included some interesting variations on the confused deputy.

A particular problem is that a process whose saved and real UIDs differ, cannot invoke other files that perform setuid. Such a process has two authority sources and will in general need to convey each (or parts of each) to its sub sub contractor. Execing another program in set_uid mode fails to convey the invoker’s authority that stems from the invoker’s saved uid process value. Here is some code to summarize how the Unix kernel treats the various user IDs.

Endowing a file with the “set user ID” property as in “chmod 4755 file” is analogous to arranging for machine code to run in privileged mode. The program in the endowed file is thereby allowed to take actions beyond those that its invoker could, just as a system call invokes code running in privileged mode so as to obey privileged machine instructions that it may contain. The setuid() system call even helps such programs avoid the analog to a frequent security bug in operating systems.

But the two state mode is suitable only when there is a program, such as the privileged Unix kernel, to mediate between multiple interests. The Unix kernel does this but its rules for interactions do not support patterns such as described above. Capability systems may be build on the same two state foundation and support such interactions.

A Concrete Scenario

We extend the Confused Deputy scenario:
Just as the compiler user in the original scenario needs to invoke the compiler which requires authority not held by the user, so may the compiler need to invoke code with more authority than the compiler. Suppose that the compiler needs to invoke data base functionality to encode the feature usage data and update a file in the compiler’s directory. The data base functionality is in a file owned by yet another user and that file is endowed with setuid mode. As the encoding program begins, its real user ID is that of the compiler user and its effective and saved user IDs are each that of the owner of the data base code. This code now lacks the authority to deposit the formatted data in the compiler’s directory. The data base code has only the authority of the data base code owner and the compiler user. This problem might be handled by the Multics rings but only at the cost of fixed ring assignments to each piece of code.

The http problem

Browsers and their plugins want to fetch code, in some form, from web sites and execute it. Such code may itself need to refer to the same or other web sites for legitimate ends. Browsers frequently run behind firewalls on behalf of users who are trusted to visit internal sites accessible by virtue of intranet connectivity. Various plugin authors who interpret such imported code want to censor such fetches from sites in order to support the obligations of the browser user to not allow visitors unlimited access to internal (behind the firewall) secrets. The imported code is just such a visitor. Such imported code is in a position to report to places outside the firewall what it finds within. These plugin authors have an infeasible task. They cannot tell from looking at the requested URL whether it is internal. They can judge how much the requested URL looks like the URL from which the guest code was fetched. This is a fuzzy test and will certainly preclude valid useful patterns.

A closely related problem is that the imported code will use the cookies of the user of the browser to make its accesses. Cookies supply a sort of authority that the guest program should not wield without the user’s explicit permission.

Another Description

Here is the above pattern that is unsupported by Unix setuid functionality. We wish to use Unix authority mechanism to enforce the modularity described by C’s scope rules, and we use int * to stand in for file names. Consider the following:
int m1(int * a, int * b){
    static aa=0;
    aa += *a;
    return *a + *b + aa;}

int m2(int * a){
   int q = 20;
   static int aa=0;
   aa += *a;
   return m1(a, &q);}

int m3(){int r = 22; return m2(&r);}
Routine m1 requires authority from both m2 and m3 to fetch its input. In the capability analog the authority would come along with the “name”. In Java parameters really do convey authority just like capabilities.

Another setuid problem

We learn here about the lack of conventions between libraries and their callers about the current state of effective user ID.
Things to be integrated somewhere:

See another hardware deputy problem.

The deputy must always know whose authority it acts with!

More pitfalls with setuid.
A note by Dieter Gollmann on such problems.

There are many good confused deputy descriptions on the web now, 2008. There are subtle modifications in the retelling but they seldom miss the important point. Some of the modifications are actually better in some aspect. The story is evolving and improving.