Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions providers/os/resources/users/etcpasswd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ func ParseEtcPasswd(input io.Reader) ([]*User, error) {
// parse uid
uid, err := strconv.ParseInt(m[2], 10, 0)
if err != nil {
log.Error().Err(err).Str("user", m[0]).Msg("could not parse uid")
// Skip the entry rather than fall through with uid 0: a
// malformed line must not surface as a phantom root account.
log.Error().Err(err).Str("user", m[0]).Msg("could not parse uid, skipping user")
continue
}
gid, err := strconv.ParseInt(m[3], 10, 0)
if err != nil {
log.Error().Err(err).Str("user", m[0]).Msg("could not parse gid")
log.Error().Err(err).Str("user", m[0]).Msg("could not parse gid, skipping user")
continue
}

// bin:x:1:1:bin:/bin:/sbin/nologin
Expand Down
21 changes: 21 additions & 0 deletions providers/os/resources/users/etcpasswd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package users_test

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -13,6 +14,26 @@ import (
"go.mondoo.com/mql/v13/providers/os/resources/users"
)

func TestParseEtcPasswdSkipsMalformedUidGid(t *testing.T) {
// A line with a non-numeric uid/gid must be skipped, not surfaced as a
// phantom uid 0 (root) account.
const passwd = `root:x:0:0:root:/root:/bin/bash
broken:x:notanumber:1:broken uid:/home/broken:/bin/sh
brokengid:x:1001:notanumber:broken gid:/home/brokengid:/bin/sh
alice:x:1000:1000:Alice:/home/alice:/bin/bash
`

m, err := users.ParseEtcPasswd(strings.NewReader(passwd))
require.NoError(t, err)
require.Equal(t, 2, len(m), "malformed uid/gid lines should be skipped")

assert.Equal(t, "root", m[0].Name)
assert.Equal(t, int64(0), m[0].Uid)
assert.Equal(t, "alice", m[1].Name)
assert.Equal(t, int64(1000), m[1].Uid)
assert.Equal(t, int64(1000), m[1].Gid)
}

func TestParseLinuxEtcPasswd(t *testing.T) {
mock, err := mock.New(0, &inventory.Asset{}, mock.WithPath("./testdata/debian.toml"))
if err != nil {
Expand Down
Loading