I'm creating a small program that requires privileged access to a network port below 1024, so it runs with sudo.
If part of what the utility will need to do requires knowing who the user is that invoked the application, I would need a way to query who the actual user is; using the OS/user
method of getting the user points to "System Administrator" or other root user because it's running in a sudo context.
Is there a way in GoLang to pull the user who is running the application under sudo? (Go 1.4.2, running on OS X 10.10.3).
Here's how I check if the current user is root
in the latest Golang version go1.16.1
:
package main
import (
"fmt"
"log"
"os/user"
)
func isRoot() bool {
currentUser, err := user.Current()
if err != nil {
log.Fatalf("[isRoot] Unable to get current user: %s", err)
}
return currentUser.Username == "root"
}
func main() {
fmt.Printf("Am I root? %v", isRoot())
}
https://play.golang.org/p/tRMR5IW6GAc
sudo creates the SUDO_UID
/SUDO_GID
and the SUDO_USER
environment variables for this, which contains the user id, group id and username of the account invoking sudo. See e.g. here
So in Go you can read those environment variables with os.Getenv().
You might want to trust those variables only if running as root, i.e. if os.Geteuid() returns 0
Since anyone can set SUDO_UID
, SUDO_GID
and SUDO_USER
, an attacker can just export those themselves and bypass the security you're trying to implement.
The way that I've found, is to find the pid of the Go program you're currently running, get the name of the user that owns that pid, then check if its root
.
import (
"fmt"
"os"
"os/exec"
"strconv"
)
func main() {
if getProcessOwner() == "root" {
fmt.Println("You're sudo!")
}
}
func getProcessOwner() string {
stdout, err := exec.Command("ps", "-o", "user=", "-p", strconv.Itoa(os.Getpid())).Output()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return string(stdout)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With