mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
nomad: defensive check for namespaces in job registration call
In a job registration request, ensure that the request namespace "header" and job namespace field match. This should be the case already in prod, as http handlers ensures that the values match [1]. This mitigates bugs that exploit bugs where we may check a value but act on another, resulting into bypassing ACL system. [1] https://github.com/hashicorp/nomad/blob/v0.9.5/command/agent/job_endpoint.go#L415-L418
This commit is contained in:
@@ -905,6 +905,7 @@ func TestFS_Logs_TaskPending(t *testing.T) {
|
||||
args := &structs.JobRegisterRequest{}
|
||||
args.Job = job
|
||||
args.WriteRequest.Region = "global"
|
||||
args.Namespace = job.Namespace
|
||||
var jobResp structs.JobRegisterResponse
|
||||
require.NoError(s.RPC("Job.Register", args, &jobResp))
|
||||
|
||||
|
||||
@@ -88,6 +88,11 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||
return fmt.Errorf("missing job for registration")
|
||||
}
|
||||
|
||||
// defensive check; http layer and RPC requester should ensure namespaces are set consistently
|
||||
if args.Namespace != args.Job.Namespace {
|
||||
return fmt.Errorf("mismatched request namespace in request: %q, %q", args.Namespace, args.Job.Namespace)
|
||||
}
|
||||
|
||||
// Run admission controllers
|
||||
job, warnings, err := j.admissionControllers(args.Job)
|
||||
if err != nil {
|
||||
@@ -343,6 +348,11 @@ func (j *Job) Summary(args *structs.JobSummaryRequest,
|
||||
func (j *Job) Validate(args *structs.JobValidateRequest, reply *structs.JobValidateResponse) error {
|
||||
defer metrics.MeasureSince([]string{"nomad", "job", "validate"}, time.Now())
|
||||
|
||||
// defensive check; http layer and RPC requester should ensure namespaces are set consistently
|
||||
if args.Namespace != args.Job.Namespace {
|
||||
return fmt.Errorf("mismatched request namespace in request: %q, %q", args.Namespace, args.Job.Namespace)
|
||||
}
|
||||
|
||||
job, mutateWarnings, err := j.admissionMutators(args.Job)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -363,8 +363,11 @@ func TestJobEndpoint_Register_ACL(t *testing.T) {
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
codec := rpcClient(t, s1)
|
||||
req := &structs.JobRegisterRequest{
|
||||
Job: tt.Job,
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
Job: tt.Job,
|
||||
WriteRequest: structs.WriteRequest{
|
||||
Region: "global",
|
||||
Namespace: tt.Job.Namespace,
|
||||
},
|
||||
}
|
||||
req.AuthToken = tt.Token
|
||||
|
||||
@@ -407,8 +410,11 @@ func TestJobEndpoint_Register_InvalidNamespace(t *testing.T) {
|
||||
job := mock.Job()
|
||||
job.Namespace = "foo"
|
||||
req := &structs.JobRegisterRequest{
|
||||
Job: job,
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
Job: job,
|
||||
WriteRequest: structs.WriteRequest{
|
||||
Region: "global",
|
||||
Namespace: job.Namespace,
|
||||
},
|
||||
}
|
||||
|
||||
// Try without a token, expect failure
|
||||
|
||||
Reference in New Issue
Block a user