Skip to content

provisioner: don't pass CODER_ variables #4638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Refactor to less fragile canary approach
... and remove some dead frontend code
... and cleanup English in new UI
  • Loading branch information
ammario committed Oct 19, 2022
commit 7e839ad25db0982a655fe8b8c2a88ae0a938b42b
43 changes: 6 additions & 37 deletions provisioner/terraform/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type executor struct {
func (e executor) basicEnv() []string {
// Required for "terraform init" to find "git" to
// clone Terraform modules.
env := os.Environ()
env := safeEnviron()
// Only Linux reliably works with the Terraform plugin
// cache directory. It's unknown why this is.
if e.cachePath != "" && runtime.GOOS == "linux" {
Expand All @@ -41,41 +41,6 @@ func (e executor) basicEnv() []string {
return env
}

func envName(env string) string {
parts := strings.Split(env, "=")

if len(parts) > 0 {
return parts[0]
}
return ""
}

// sanitizeCoderEnv removes CODER_ environment variables to prevent accidentally
// passing in secrets. See https://github.com/coder/coder/issues/4635.
func sanitizeCoderEnv(env []string) []string {
var coderSafeEnv = map[string]struct{}{
"CODER_AGENT_URL": {},
"CODER_WORKSPACE_TRANSITION": {},
"CODER_WORKSPACE_NAME": {},
"CODER_WORKSPACE_OWNER": {},
"CODER_WORKSPACE_OWNER_EMAIL": {},
"CODER_WORKSPACE_ID": {},
"CODER_WORKSPACE_OWNER_ID": {},
}

strippedEnv := make([]string, 0, len(env))
for _, e := range env {
name := envName(e)
if strings.HasPrefix(name, "CODER_") {
if _, isSafe := coderSafeEnv[name]; !isSafe {
continue
}
}
strippedEnv = append(strippedEnv, e)
}
return strippedEnv
}

func (e executor) execWriteOutput(ctx, killCtx context.Context, args, env []string, stdOutWriter, stdErrWriter io.WriteCloser) (err error) {
defer func() {
closeErr := stdOutWriter.Close()
Expand All @@ -91,10 +56,14 @@ func (e executor) execWriteOutput(ctx, killCtx context.Context, args, env []stri
return ctx.Err()
}

if isCanarySet(env) {
return xerrors.New("environment variables not sanitized, this is a bug within Coder")
}

// #nosec
cmd := exec.CommandContext(killCtx, e.binaryPath, args...)
cmd.Dir = e.workdir
cmd.Env = sanitizeCoderEnv(env)
cmd.Env = env

// We want logs to be written in the correct order, so we wrap all logging
// in a sync.Mutex.
Expand Down
8 changes: 3 additions & 5 deletions provisioner/terraform/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ func provisionVars(start *proto.Provision_Start) ([]string, error) {
}

func provisionEnv(start *proto.Provision_Start) ([]string, error) {
env := os.Environ()
// Be sure to add any values here to `sanitizeCoderEnv`, otherwise they will not
// get passed into the execute.
env := safeEnviron()
env = append(env,
"CODER_AGENT_URL="+start.Metadata.CoderUrl,
"CODER_WORKSPACE_TRANSITION="+strings.ToLower(start.Metadata.WorkspaceTransition.String()),
Expand Down Expand Up @@ -234,12 +232,12 @@ var (
)

func logTerraformEnvVars(logr logger) error {
env := os.Environ()
env := safeEnviron()
for _, e := range env {
if strings.HasPrefix(e, "TF_") {
parts := strings.SplitN(e, "=", 2)
if len(parts) != 2 {
panic("os.Environ() returned vars not in key=value form")
panic("safeEnviron() returned vars not in key=value form")
}
if !tfEnvSafeToPrint[parts[0]] {
parts[1] = "<value redacted>"
Expand Down
55 changes: 55 additions & 0 deletions provisioner/terraform/safeenv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package terraform

import (
"os"
"strings"
)

// We must clean CODER_ environment variables to avoid accidentally passing in
// secrets like the Postgres connection string. See
// https://github.com/coder/coder/issues/4635.
//
// safeEnviron() is provided as an os.Environ() alternative that strips CODER_
// variables. As an additional precaution, we check a canary variable before
// provisioner exec.
//
// We cannot strip all CODER_ variables at exec because some are used to
// configure the provisioner.

const unsafeEnvCanary = "CODER_DONT_PASS"

func init() {
os.Setenv(unsafeEnvCanary, "true")
}

func envName(env string) string {
parts := strings.SplitN(env, "=", 1)
if len(parts) > 0 {
return parts[0]
}
return ""
}

func isCanarySet(env []string) bool {
for _, e := range env {
if envName(e) == unsafeEnvCanary {
return true
}
}
return false
}

// safeEnviron wraps os.Environ but removes CODER_ environment variables.
func safeEnviron() []string {
env := os.Environ()
strippedEnv := make([]string, 0, len(env))

for _, e := range env {
name := envName(e)
if strings.HasPrefix(name, "CODER_") {
continue
}
strippedEnv = append(strippedEnv, e)
}
return strippedEnv
}
4 changes: 2 additions & 2 deletions site/src/components/Resources/AgentLatency.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export const AgentLatency: FC<{ agent: WorkspaceAgent }> = ({ agent }) => {
>
<HelpTooltipTitle>Latency</HelpTooltipTitle>
<HelpTooltipText>
Latency from relay servers, used when connections cannot connect
peer-to-peer. Star indicates the preferred relay.
This is the latency overhead on non peer to peer connections. The star
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is the latency overhead on non peer to peer connections. The star
This is the latency overhead on non peer-to-peer connections. The star

indicates the preferred relay.
</HelpTooltipText>

<HelpTooltipText>
Expand Down
46 changes: 0 additions & 46 deletions site/src/components/Resources/ResourceAgentLatency.stories.tsx

This file was deleted.

70 changes: 0 additions & 70 deletions site/src/components/Resources/ResourceAgentLatency.tsx

This file was deleted.