Skip to content

Commit 326880f

Browse files
Identify and block malformed NO_PROXY values (#962)
1 parent e1e25ee commit 326880f

File tree

4 files changed

+370
-0
lines changed

4 files changed

+370
-0
lines changed

docs.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,11 @@ The annotation `field.cattle.io/creatorId` must be set to the Username of the Us
558558

559559
If `field.cattle.io/no-creator-rbac` annotation is set, `field.cattle.io/creatorId` cannot be set.
560560

561+
##### NO_PROXY value
562+
563+
Prevent the creation of new objects with an env var (under `spec.agentEnvVars`) with a name of `NO_PROXY` if its value contains one or more spaces. This ensures that the provided value adheres to
564+
the format expected by Go, and helps to prevent subtle issues elsewhere when writing scripts which utilize `NO_PROXY`.
565+
561566
##### Data Directories
562567

563568
Prevent the creation of new objects with an env var (under `spec.agentEnvVars`) with a name of `CATTLE_AGENT_VAR_DIR`.
@@ -619,6 +624,13 @@ Both `minAvailable` and `maxUnavailable` must be a string which represents a non
619624
^([0-9]|[1-9][0-9]|100)%$
620625
```
621626

627+
##### NO_PROXY value
628+
629+
Prevent the update of objects with an env var (under `spec.agentEnvVars`) with a name of `NO_PROXY` if its value contains one or more spaces. This ensures that the provided value adheres to
630+
the format expected by Go, and helps to prevent subtle issues elsewhere when writing scripts which utilize `NO_PROXY`.
631+
632+
The only exception to this check is if the existing cluster already has a `NO_PROXY` variable which includes spaces in its value. In this case, update operations are permitted. If `NO_PROXY` is later updated to value which does not contain spaces, this exception will no longer occur.
633+
622634
### Mutation Checks
623635

624636
#### On Create

pkg/resources/provisioning.cattle.io/v1/cluster/Cluster.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ The annotation `field.cattle.io/creatorId` must be set to the Username of the Us
88

99
If `field.cattle.io/no-creator-rbac` annotation is set, `field.cattle.io/creatorId` cannot be set.
1010

11+
#### NO_PROXY value
12+
13+
Prevent the creation of new objects with an env var (under `spec.agentEnvVars`) with a name of `NO_PROXY` if its value contains one or more spaces. This ensures that the provided value adheres to
14+
the format expected by Go, and helps to prevent subtle issues elsewhere when writing scripts which utilize `NO_PROXY`.
15+
1116
#### Data Directories
1217

1318
Prevent the creation of new objects with an env var (under `spec.agentEnvVars`) with a name of `CATTLE_AGENT_VAR_DIR`.
@@ -69,6 +74,13 @@ Both `minAvailable` and `maxUnavailable` must be a string which represents a non
6974
^([0-9]|[1-9][0-9]|100)%$
7075
```
7176

77+
#### NO_PROXY value
78+
79+
Prevent the update of objects with an env var (under `spec.agentEnvVars`) with a name of `NO_PROXY` if its value contains one or more spaces. This ensures that the provided value adheres to
80+
the format expected by Go, and helps to prevent subtle issues elsewhere when writing scripts which utilize `NO_PROXY`.
81+
82+
The only exception to this check is if the existing cluster already has a `NO_PROXY` variable which includes spaces in its value. In this case, update operations are permitted. If `NO_PROXY` is later updated to value which does not contain spaces, this exception will no longer occur.
83+
7284
## Mutation Checks
7385

7486
### On Create

pkg/resources/provisioning.cattle.io/v1/cluster/validator.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ func (p *provisioningAdmitter) Admit(request *admission.Request) (*admissionv1.A
139139
return response, err
140140
}
141141

142+
if response = validateHTTPNoProxyVariable(request, oldCluster, cluster); !response.Allowed {
143+
return response, nil
144+
}
145+
142146
if response = p.validateDataDirectories(request, oldCluster, cluster); !response.Allowed {
143147
return response, err
144148
}
@@ -408,6 +412,29 @@ func (p *provisioningAdmitter) validateClusterName(request *admission.Request, r
408412
return nil
409413
}
410414

415+
func validateHTTPNoProxyVariable(request *admission.Request, oldCluster, newCluster *v1.Cluster) *admissionv1.AdmissionResponse {
416+
switch request.Operation {
417+
case admissionv1.Create:
418+
proxyValue := retrieveNoProxy(newCluster)
419+
if proxyValue != "" && strings.Contains(proxyValue, " ") {
420+
return admission.ResponseBadRequest("Malformed NO_PROXY environment variable value format: detected whitespace in value. Value must be a comma-delimited string with no spaces containing one or more IP address prefixes (1.2.3.4, 1.2.3.4:80), IP address prefixes in CIDR notation (1.2.3.4/8), domain names, or special DNS labels (*)")
421+
}
422+
case admissionv1.Update:
423+
// Block updating existing clusters with a malformed NO_PROXY, but
424+
// don't block existing clusters which already have a malformed value.
425+
oldProxyValue := retrieveNoProxy(oldCluster)
426+
newProxyValue := retrieveNoProxy(newCluster)
427+
428+
alreadyHadSpaces := oldProxyValue != "" && strings.Contains(oldProxyValue, " ")
429+
currentlyContainsSpaces := newProxyValue != "" && strings.Contains(newProxyValue, " ")
430+
if !alreadyHadSpaces && currentlyContainsSpaces {
431+
return admission.ResponseBadRequest("Malformed NO_PROXY environment variable value format: detected whitespace in value. Value must be a comma-delimited string with no spaces containing one or more IP address prefixes (1.2.3.4, 1.2.3.4:80), IP address prefixes in CIDR notation (1.2.3.4/8), domain names, or special DNS labels (*)")
432+
}
433+
}
434+
435+
return admission.ResponseAllowed()
436+
}
437+
411438
func (p *provisioningAdmitter) validateMachinePoolNames(request *admission.Request, response *admissionv1.AdmissionResponse, cluster *v1.Cluster) error {
412439
if request.Operation != admissionv1.Create {
413440
return nil
@@ -863,3 +890,15 @@ func isValidName(clusterName, clusterNamespace string, clusterExists bool) bool
863890
// RFC-1123 will fail to deploy required fleet components and should not be accepted.
864891
return len(clusterName) <= 63 && fleetNameRegex.MatchString(clusterName)
865892
}
893+
894+
func retrieveNoProxy(cluster *v1.Cluster) string {
895+
if cluster == nil {
896+
return ""
897+
}
898+
for _, envVar := range cluster.Spec.AgentEnvVars {
899+
if strings.ToLower(envVar.Name) == "no_proxy" {
900+
return envVar.Value
901+
}
902+
}
903+
return ""
904+
}

0 commit comments

Comments
 (0)