@@ -415,7 +415,7 @@ func TestProvision(t *testing.T) {
415
415
// nolint:paralleltest
416
416
func TestProvision_ExtraEnv (t * testing.T ) {
417
417
// #nosec
418
- secretValue : = "oinae3uinxase"
418
+ const secretValue = "oinae3uinxase"
419
419
t .Setenv ("TF_LOG" , "INFO" )
420
420
t .Setenv ("TF_SUPERSECRET" , secretValue )
421
421
@@ -459,3 +459,76 @@ func TestProvision_ExtraEnv(t *testing.T) {
459
459
}
460
460
require .True (t , found )
461
461
}
462
+
463
+ // nolint:paralleltest
464
+ func TestProvision_SafeEnv (t * testing.T ) {
465
+ // #nosec
466
+ const (
467
+ passedValue = "superautopets"
468
+ secretValue = "oinae3uinxase"
469
+ )
470
+
471
+ t .Setenv ("VALID_USER_ENV" , passedValue )
472
+
473
+ // We ensure random CODER_ variables aren't passed through to avoid leaking
474
+ // control plane secrets (e.g. PG URL).
475
+ t .Setenv ("CODER_SECRET" , secretValue )
476
+
477
+ const echoResource = `
478
+ resource "null_resource" "a" {
479
+ provisioner "local-exec" {
480
+ command = "env"
481
+ }
482
+ }
483
+
484
+ `
485
+
486
+ ctx , api := setupProvisioner (t , nil )
487
+
488
+ directory := t .TempDir ()
489
+ path := filepath .Join (directory , "main.tf" )
490
+ err := os .WriteFile (path , []byte (echoResource ), 0o600 )
491
+ require .NoError (t , err )
492
+
493
+ request := & proto.Provision_Request {
494
+ Type : & proto.Provision_Request_Start {
495
+ Start : & proto.Provision_Start {
496
+ Directory : directory ,
497
+ Metadata : & proto.Provision_Metadata {
498
+ WorkspaceTransition : proto .WorkspaceTransition_START ,
499
+ },
500
+ },
501
+ },
502
+ }
503
+ response , err := api .Provision (ctx )
504
+ require .NoError (t , err )
505
+ err = response .Send (request )
506
+ require .NoError (t , err )
507
+ var (
508
+ foundUserEnv = false
509
+ // Some CODER_ environment variables used by our Terraform provider
510
+ // must make it through.
511
+ foundCoderEnv = false
512
+ )
513
+ for {
514
+ msg , err := response .Recv ()
515
+ require .NoError (t , err )
516
+
517
+ if log := msg .GetLog (); log != nil {
518
+ t .Log (log .Level .String (), log .Output )
519
+ if strings .Contains (log .Output , passedValue ) {
520
+ foundUserEnv = true
521
+ }
522
+ if strings .Contains (log .Output , "CODER_" ) {
523
+ foundCoderEnv = true
524
+ }
525
+ require .NotContains (t , log .Output , secretValue )
526
+ }
527
+ if c := msg .GetComplete (); c != nil {
528
+ require .Empty (t , c .Error )
529
+ break
530
+ }
531
+ }
532
+ require .True (t , foundUserEnv )
533
+ require .True (t , foundCoderEnv )
534
+ }
0 commit comments