sudo option "tty_tickets" gives false sense of security due to reused pts numbers
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
sudo (Ubuntu) |
Fix Released
|
Wishlist
|
Unassigned |
Bug Description
Binary package hint: sudo
When we have the option "tty_tickets" in '/etc/sudoers', for each new terminal (tty) or pseudo-
Also, when we invoke a graphical instance of 'sudo' through e.g. 'kdesu', new pts's are reserved for this purpose. Applications started through 'kdesu' require _two_ pts's, and sudo tickets are assigned corresponding to the numbers of these pts's.
This report affects, as I understand it, both 'sudo' and 'kdesu'. I do not know what is the behaviour of 'gksudo' in relation to this bug, so I don't know if this report should also affect it.
Now, I will give three different scenarios in which 'sudo' or a graphical application requiring sudo capabilities can be run without a password, but when the user would _not_ expect to be able to do so.
N.B.: Before each scenario, we must be sure we have no active sudo tickets in the above mentioned directory. Doing 'sudo su', 'rm /var/run/
Useful commands for demonstrating what happens are:
'sudo ls --full-time /var/run/
'ps au' (to show which pts's are in use, and by what processes)
'tty' (run e.g. in Konsole to show which pts we are on)
Scenario 1:
- Open a Konsole (or Yakuake).
- Do 'sudo ls --full-time /var/run/
- Do 'tty'
- Do 'exit'. If you are in Konsole, this should close it completely -> now, start a new Konsole. If you are in Yakuake, it should do this automatically for you (spawn a new shell).
- _Now_, we have closed the console we used. It _seems_ reasonable to expect that after we closed the console where 'sudo' was used, the sudo capability would expire.
- Do 'sudo foo' or 'sudo ls --full-time /var/run/
- If we again do 'tty', we will see that we are re-using the previous pts number, which is the cause of this phenomenon.
Scenario 2:
- Open a Konsole (or Yakuake).
- Add a new terminal tab, and in this tab do 'sudo foo', giving your password. Do not close this tab.
- Add a third terminal tab, and in this tab do 'sudo foo', giving your password. Now we have three tabs open in Konsole or Yakuake.
- Close tabs two and three. (This will free two pts's.)
(- In the first tab, just to illustrate, run 'sudo ls --full-time /var/run/
- Run e.g. Adept or Synaptic, expecting to give your password. You should be able to do this without giving your password.
- If we again do 'sudo ls --full-time /var/run/
Scenario 3:
(Optional: - Open a Konsole or Yakuake.)
- Run e.g. Adept or Synaptic, this time giving your password. Close it.
- Open two new Yakuake tabs or Konsole windows or tabs.
(- In the already opened terminal, do 'sudo ls --full-time /var/run/
- In the second newly opened terminal, you should be able to run 'sudo foo' without giving your password. (IIRC, I have done this in the first new terminal instance sometime, possibly. It all depends on which pts number we are given. N.B. Normally 'kdesu' leaves behind only one valid sudo ticket, as in this scenario.)
(- You can do 'tty' to verify that this is the same terminal that we saw had the valid sudo ticket.)
I discovered this misbehaviour in sudo and applications that require sudo capabilities while investigating bug #72545 (and bug #50971).
There are two separate issues here, as I understand it.
Issue 1. As implied by the title of this bug, this gives the user a false sense of security under some conditions.
Case 1.1: The user can (IMO rightly) expect that closing the terminal should _remove sudo capabilities_. It isn't intuitive to expect that a _new_ terminal instance should inherit previously affirmed sudo capabilities. When pts numbers get re-used and sudo tickets are not cleared, this is the resulting problem.
Case 1.2: The user can expect that launching a graphical application that requires sudo capability should _always_ ask for the password. (I won't go into separate password caching capabilities of these, I fear it may be an entirely separate can of worms.) As previously, it isn't intuitive to expect that this should inherit previously affirmed sudo capabilities. This case isn't _necessarily_ all that damaging, e.g. in the case of running Adept or Synaptic, _but_ wrong nonetheless; however, we can imagine a situation where a graphically launched application requiring sudo capabilities could harm the user's system, and would _normally_ alert the user's attention by requiring the user's password.
Case 1.3: Running a graphical application that requires sudo capability should _not_, in my opinion, leave behind a used sudo ticket that can be re-used in a terminal.
Issue 2. This is at least a theoretical vulnerability in the system, if this _same_ user's account can be exploited. As I understand it, pts numbers are assigned to remote connections as well, so by coincidence a remote connection could receive a used but recently freed pts that has a valid sudo tty_ticket.
Case 2.0: If this user's account (in the "admin" group) and _password_ have been compromised, this is a _non-issue_. If the password is out, trying to exploit _this_ behaviour isn't necessary.
Case 2.1: If this user's account can be accessed otherwise, but the password isn't known, this would appear to be an issue. I don't think I can think of many scenarios where this could happen, but I imagine it is still at least a possibility. (Using 'tty_tickets' is in this case of course more secure than the system would be without it.)
Changed in sudo: | |
status: | Unconfirmed → Confirmed |
Changed in sudo (Ubuntu): | |
importance: | Undecided → Wishlist |
security vulnerability: | yes → no |
As this issue seems somewhat hard to remedy completely, I decided to comment on possible remedies separately.
It would seem beneficial that unused tty_tickets from '/var/run/ sudo/youruserna me' should be cleared. More specifically, the tickets for such tty's and pts's that _are not in use_ at any point in time should be cleared.
Now, what process could be responsible for doing this?
A. The kernel and "devpts", which is responsible for assigning new pts's at '/dev/pts/*'. It could be argued that this would be the right place, to tackle the authorisation issue at a low level. It could also be argued the opposite, that authorisation issues do not belong here, that it is not the kernel's job to do things for sudo. This would mean that this should be handled in userspace.
B. A root level "sudo daemon" that would keep an eye on tty's and pts's on one hand and sudo's tty_tickets on the other hand. Whenever a terminal or a pseudo-terminal is freed, the daemon would clear the appropriate sudo tty_ticket for all users, and possibly make a note in a log. (The tty's probably would need to be handled differently than the pts's.)
C. For graphical applications requiring sudo access, the application that granted the access could also clear the ticket when the sudo capability isn't needed anymore. (E.g. 'kdesu' or 'kdesud'. It seems the 'kdesud' is used for caching the password given to 'kdesu'.)
D. A work-around is to use "timestamp_ timeout= 0" in '/etc/sudoers', but this takes away a usability feature from sudo.
A couple non-working "solutions" follow:
E. "The command 'sudo' should be responsible for clearing the ticket." This can't be done, because sudo is not running when the terminal is freed.
F. "The terminal or 'bash' should be responsible." This can't be done because the terminal or the shell are not root-level processes, and so can't remove root-owned tty_tickets.