# GNU InetUtils Security Advisory: remote authentication by-pass in telnetd

The telnetd server invokes /usr/bin/login (normally running as root)
passing the value of the USER environment variable received from the
client as the last parameter.

If the client supply a carefully crafted USER environment value being
the string "-f root", and passes the telnet(1) -a or --login parameter
to send this USER environment to the server, the client will be
automatically logged in as root bypassing normal authentication
processes.

This happens because the telnetd server do not sanitize the USER
environment variable before passing it on to login(1), and login(1)
uses the -f parameter to by-pass normal authentication.

Severity: High

Vulnerable versions: GNU InetUtils since version 1.9.3 up to and
including version 2.7.

## Example

On a Trisquel GNU/Linux 11 aramo laptop:

root@kaka:~ sudo apt-get install inetutils-telnetd telnet
root@kaka:~ sudo sed -i 's/#<off># telnet/telnet/' /etc/inetd.conf 
root@kaka:~ sudo /etc/init.d/inetutils-inetd start
root@kaka:~ USER='-f root' telnet -a localhost
...
root@kaka:~# 

## History

The bug was introduced in the following commit made on 2015 March 19:

https://codeberg.org/inetutils/inetutils/commit/fa3245ac8c288b87139a0da8249d0a408c4dfb87

Based on mailing list discussions:

https://lists.gnu.org/archive/html/bug-inetutils/2014-12/msg00012.html
https://lists.gnu.org/archive/html/bug-inetutils/2015-03/msg00001.html

It was included in the v1.9.3 release made on 2015 May 12.

## Recommendation

Do not run a telnetd server at all.  Restrict network access to the
telnet port to trusted clients.

Apply the patch or upgrade to a newer release which incorporate the
patch.

## Workaround

Disable telnetd server or make the InetUtils telnetd use a custom
login(1) tool that does not permit use of the '-f' parameter.

## Further research

The template for invoking login(1) is in telnetd/telnetd.c:

```
/* Template command line for invoking login program.  */
char *login_invocation =
#ifdef SOLARIS10
  /* TODO: `-s telnet' or `-s ktelnet'.
   *       `-u' takes the Kerberos principal name
   *       of the authenticating, remote user.
   */
  PATH_LOGIN " -p -h %h %?T{-t %T} -d %L %?u{-u %u}{%U}"
#elif defined SOLARIS
  /* At least for SunOS 5.8.  */
  PATH_LOGIN " -h %h %?T{%T} %?u{-- %u}{%U}"
#else /* !SOLARIS */
  PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
#endif
  ;
```

The variable expansion happens in telnetd/utility.c:

```
/* Expand a variable referenced by its short one-symbol name.
   Input: exp->cp points to the variable name.
   FIXME: not implemented */
char *
_var_short_name (struct line_expander *exp)
{
  char *q;
  char timebuf[64];
  time_t t;
  switch (*exp->cp++)
    {
    case 'a':
#ifdef AUTHENTICATION
      if (auth_level >= 0 && autologin == AUTH_VALID)
        return xstrdup ("ok");
#endif
      return NULL;
    case 'd':
      time (&t);
      strftime (timebuf, sizeof (timebuf),
                "%l:%M%p on %A, %d %B %Y", localtime (&t));
      return xstrdup (timebuf);
    case 'h':
      return xstrdup (remote_hostname);
    case 'l':
      return xstrdup (local_hostname);
    case 'L':
      return xstrdup (line);
    case 't':
      q = strchr (line + 1, '/');
      if (q)
        q++;
      else
        q = line;
      return xstrdup (q);
    case 'T':
      return terminaltype ? xstrdup (terminaltype) : NULL;
    case 'u':
      return user_name ? xstrdup (user_name) : NULL;
    case 'U':
      return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup ("");
    default:
      exp->state = EXP_STATE_ERROR;
      return NULL;
    }
}
```

Thus there is potential for similar vulnerabilities for other
variables.

On non-GNU/Linux systems, only the remote hostname field is of
interest.  The `remote_hostname` variable is populated in the function
`telnetd_setup` from telnetd/telnetd.c by calling getnameinfo() or
gethostbyaddr() depending on platform.  This API is generally not
considered to return trusted data, thus relying on it to not return a
value such as 'foo -f root' is not advisable.

## Patch

We chose to sanitize all variables for expansion.  The following two
patches are what we suggest:

https://codeberg.org/inetutils/inetutils/commit/fd702c02497b2f398e739e3119bed0b23dd7aa7b
https://codeberg.org/inetutils/inetutils/commit/ccba9f748aa8d50a38d7748e2e60362edd6a32cc

## Credits

This vulnerability was found and reported by Kyu Neushwaistein aka
Carlos Cortes Alvarez on 2026-01-19.

Initial patch by Paul Eggert on 2026-01-20.  Simon Josefsson improved
the patch to also cover similar concerns with other expansions.

This advisory was drafted by Simon Josefsson on 2026-01-20.

Attachment: signature.asc
Description: PGP signature

  • Hello GNU I... Kyu Neushwaistein
    • GNU In... Simon Josefsson via Bug reports for the GNU Internet utilities
      • Re... Kyu Neushwaistein

Reply via email to