Я хочу туннелировать подкоманду через соединение, прослушивая порт, выполняя подкоманду (для подключения к этому порту), а затем пересылая данные через соединение:Последствия безопасности сокета при туннелировании подкоманды
package main
import (
"fmt"
"net"
"os"
"os/exec"
)
func main() {
ln, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: localhost})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer ln.Close()
port := ln.Addr().(*net.TCPAddr).Port
cmd := exec.Command(
"git",
"clone",
fmt.Sprintf("git://127.0.0.1:%d/project.git", port),
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer cmd.Process.Kill()
errs := make(chan error, 1)
go func() {
errs <- cmd.Wait()
}()
conns := make(chan net.Conn, 1)
go func() {
conn, err := ln.Accept()
if err == nil {
conns <- conn
} else {
fmt.Println(err)
errs <- err
}
}()
select {
case err := <-errs:
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
case conn := <-conns:
defer conn.Close()
// TODO Tunnel data from `conn` through another connection.
}
fmt.Println("done.")
}
var localhost = net.IPv4(127, 0, 0, 1)
Тем не менее, гонка здесь между временем, когда мы начинаем слушать и время, когда суб-команда фактически подключается к слушателю, где другой процесс может подключиться к слушателю. Я считаю, что эта гонка может быть использована злоумышленником для связи с процессом на другом конце соединения и достижения результатов, которые в противном случае требовали бы повышения привилегий для выполнения (например, атаки, требующие специальных разрешений, заменяют команду git
вредоносными программами или просто считывая содержимое клонированного каталога, в этом случае).
Должно ли это быть проблемой? Если да, то можно ли это предотвратить? Хотя вопрос задается с использованием Go в качестве примера, приветствуются ответы и комментарии на любом языке.
Как можно добавить аутентификацию в этом случае, так как я не могу изменить клиента? –