mirror of
https://github.com/restic/restic.git
synced 2024-12-23 00:07:25 +00:00
Sanitize environment before starting backend processes (rclone, ssh)
The restic security model includes full trust of the local machine, so this should not fix any actual security problems, but it's better to be safe than sorry. Fixes #2192.
This commit is contained in:
parent
4875f7b659
commit
11fbaaae9a
5 changed files with 67 additions and 12 deletions
26
internal/backend/foreground.go
Normal file
26
internal/backend/foreground.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package backend
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StartForeground runs cmd in the foreground, by temporarily switching to the
|
||||
// new process group created for cmd. The returned function `bg` switches back
|
||||
// to the previous process group.
|
||||
//
|
||||
// The command's environment has all RESTIC_* variables removed.
|
||||
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
env := os.Environ() // Returns a copy that we can modify.
|
||||
|
||||
cmd.Env = env[:0]
|
||||
for _, kv := range env {
|
||||
if strings.HasPrefix(kv, "RESTIC_") {
|
||||
continue
|
||||
}
|
||||
cmd.Env = append(cmd.Env, kv)
|
||||
}
|
||||
|
||||
return startForeground(cmd)
|
||||
}
|
|
@ -7,10 +7,7 @@ import (
|
|||
"github.com/restic/restic/internal/errors"
|
||||
)
|
||||
|
||||
// StartForeground runs cmd in the foreground, by temporarily switching to the
|
||||
// new process group created for cmd. The returned function `bg` switches back
|
||||
// to the previous process group.
|
||||
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
// run the command in it's own process group so that SIGINT
|
||||
// is not sent to it.
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
|
|
38
internal/backend/foreground_test.go
Normal file
38
internal/backend/foreground_test.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
// +build !windows
|
||||
|
||||
package backend_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/backend"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
func TestForeground(t *testing.T) {
|
||||
err := os.Setenv("RESTIC_PASSWORD", "supersecret")
|
||||
rtest.OK(t, err)
|
||||
|
||||
cmd := exec.Command("env")
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
rtest.OK(t, err)
|
||||
|
||||
bg, err := backend.StartForeground(cmd)
|
||||
rtest.OK(t, err)
|
||||
defer cmd.Wait()
|
||||
|
||||
err = bg()
|
||||
rtest.OK(t, err)
|
||||
|
||||
sc := bufio.NewScanner(stdout)
|
||||
for sc.Scan() {
|
||||
if strings.HasPrefix(sc.Text(), "RESTIC_PASSWORD=") {
|
||||
t.Error("subprocess got to see the password")
|
||||
}
|
||||
}
|
||||
rtest.OK(t, err)
|
||||
}
|
|
@ -24,10 +24,7 @@ func tcsetpgrp(fd int, pid int) error {
|
|||
return errno
|
||||
}
|
||||
|
||||
// StartForeground runs cmd in the foreground, by temporarily switching to the
|
||||
// new process group created for cmd. The returned function `bg` switches back
|
||||
// to the previous process group.
|
||||
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
// open the TTY, we need the file descriptor
|
||||
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
|
|
|
@ -6,10 +6,7 @@ import (
|
|||
"github.com/restic/restic/internal/errors"
|
||||
)
|
||||
|
||||
// StartForeground runs cmd in the foreground, by temporarily switching to the
|
||||
// new process group created for cmd. The returned function `bg` switches back
|
||||
// to the previous process group.
|
||||
func StartForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
func startForeground(cmd *exec.Cmd) (bg func() error, err error) {
|
||||
// just start the process and hope for the best
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue