Control: tag -1 - security

[Please drop team@security from CCs in replies, for the reasons given below.]

On Sat, May 09, 2026 at 12:16:30PM -0500, Sebastian EM wrote:
Package: debconf
Version: 1.5.92
Severity: important
Tags: security patch
X-Debbugs-Cc: [email protected],
[email protected]

Dear debconf maintainers,

I would like to report an input-validation issue in debconf 1.5.92,
confirmed at runtime in a fresh debian:sid container.

Several debconf database driver initialization paths interpolate
attacker-influenced format or driver names into Perl eval STRING:

In general, debconf doesn't attempt to implement any kind of security boundary, and an unprivileged user being able to control DEBCONF_* environment variables would already be a significant problem on its own: they would be able to substitute their own answers to debconf questions asked by packages, which could have arbitrarily complex consequences. Any arrangements that allow users to run debconf in privileged contexts _must_ forbid them from setting those environment variables.

Therefore, I'm not inclined to treat poor validation of those environment variables, which already must not be allowed to be set at all by unprivileged users, as a security problem. I'm happy to treat it as a quality-of-implementation problem, though.

The patch touches:

 Debconf/DbDriver/File.pm
 Debconf/DbDriver/Directory.pm
 Debconf/DbDriver/Pipe.pm
 Debconf/Db.pm

I'd like to see if we can avoid the string eval entirely. All other things being equal, it's usually better to avoid the need for validation in the first place; this is analogous to the well-known reasons that it's better to avoid system()-style interfaces (where one has to sanitize shell metacharacters first) in favour of things with an execve()-style interface.

So, how about using this sort of construct (which I've tested lightly at an interactive prompt, but not in any detail) instead of string eval?

  use File::Spec;

  my @parts = split /::/, $this->{format};
  my $module = File::Spec->catfile('Debconf', 'Format', $this->{format});
  eval { require "$module.pm"; };

Of course, that has a path traversal vulnerability: you could supply a format beginning with "../../" and then load whatever module you like. (Or add further "../" and potentially get anything on the system, although this would be hard to do much with since you'd need something with the ".pm" suffix.) So that becomes something like:

  use File::Spec;

  my @parts = split /::/, $this->{format};
  my $module = File::Spec->catfile('Debconf', 'Format', $this->{format});
  if ($module !~ m{\A[A-Za-z0-9/_]+\Z}) {
          $this->error("Invalid plugin name: $this->{format}");
          return;
  }
  eval { require "$module.pm"; };

Now, that's taken us right back to doing up-front validation, which I just said I wanted to avoid! Still, I think it's worth avoiding string eval on general principles anyway, so maybe this is worth the effort.

This is enough code that it would definitely need to go into a utility module somewhere. There's no very obvious existing module that would suit, but if the code were generalized a little bit then it could go into a new Debconf::Plugin module. As well as the code your patch already touches, this could potentially be used in Debconf::AutoSelect::make_frontend and Debconf::FrontEnd::_loadelementclass.

What do you think? If this is too much refactoring then I'm happy to do it, but I thought I'd give you the opportunity.

Thanks,

--
Colin Watson (he/him)                              [[email protected]]

Reply via email to