Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
98 changes: 45 additions & 53 deletions rest-api/api/pkg/api/handler/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,29 +195,27 @@ func (cih CreateInstanceHandler) buildInstanceCreateRequestOsConfig(c echo.Conte

// Options below should all have been set by the
// earlier call to ValidateAndSetOperatingSystemData

if os.Type == cdbm.OperatingSystemTypeIPXE {
return &cwssaws.InstanceOperatingSystemConfig{
RunProvisioningInstructionsOnEveryBoot: *apiRequest.AlwaysBootWithCustomIpxe,
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{
IpxeScript: *apiRequest.IpxeScript,
},
},
UserData: apiRequest.UserData,
}, osID, nil
} else {
return &cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{
Value: os.ID.String(),
},
},
UserData: apiRequest.UserData,
}, osID, nil
result := cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
UserData: apiRequest.UserData,
}
switch os.Type {
case cdbm.OperatingSystemTypeIPXE:
result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{IpxeScript: *apiRequest.IpxeScript},
}
case cdbm.OperatingSystemTypeTemplatedIPXE:
result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OperatingSystemId{
OperatingSystemId: &cwssaws.OperatingSystemId{Value: os.ID.String()},
}
Comment on lines +208 to +212

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate TemplatedIPXE scope/site access before sending the OS ID to Core. Both create and update now dispatch TemplatedIPXE via OperatingSystemId, but the visible site-association check remains Image-only, so a site-scoped templated OS can be selected outside its allowed site.

  • rest-api/api/pkg/api/handler/instance.go#L208-L212: add the TemplatedIPXE scope/site-association guard before constructing InstanceOperatingSystemConfig_OperatingSystemId.
  • rest-api/api/pkg/api/handler/instance.go#L2077-L2081: reuse the same guard before allowing an instance update to switch to that TemplatedIPXE OS.

As per coding guidelines, REST API server changes must be reviewed for validation, authorization, tenant/resource ownership checks.

📍 Affects 1 file
  • rest-api/api/pkg/api/handler/instance.go#L208-L212 (this comment)
  • rest-api/api/pkg/api/handler/instance.go#L2077-L2081
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rest-api/api/pkg/api/handler/instance.go` around lines 208 - 212, The
TemplatedIPXE operating system selection is not validating
scope/site-association before sending the OS ID to Core, creating a security
issue where site-scoped templated OS can be selected outside their allowed site.
In rest-api/api/pkg/api/handler/instance.go at lines 208-212 (the anchor case
statement for cdbm.OperatingSystemTypeTemplatedIPXE), add a
scope/site-association guard before constructing the
InstanceOperatingSystemConfig_OperatingSystemId, reusing the same validation
logic already applied to Image types. Apply the identical guard at lines
2077-2081 (the sibling location in the instance update path) before allowing the
instance to switch to that TemplatedIPXE OS. This ensures that Operating System
accessibility is validated at both the create and update paths consistent with
the existing Image-type validation.

Source: Coding guidelines

case cdbm.OperatingSystemTypeImage:
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{Value: os.ID.String()},
}
}
return &result, osID, nil
}

// Handle godoc
Expand Down Expand Up @@ -2065,41 +2063,35 @@ func (uih UpdateInstanceHandler) buildInstanceUpdateRequestOsConfig(c echo.Conte
phoneHomeEnabled = *apiRequest.PhoneHomeEnabled
}

result := cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: phoneHomeEnabled,
UserData: userData,
}
if os != nil {
if os.Type == cdbm.OperatingSystemTypeIPXE {
return &cwssaws.InstanceOperatingSystemConfig{
RunProvisioningInstructionsOnEveryBoot: alwaysBootWithCustomIpxe,
PhoneHomeEnabled: phoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{
IpxeScript: *ipxeScript,
},
},
UserData: userData,
}, osID, nil
} else if os.Type == cdbm.OperatingSystemTypeImage {
return &cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: phoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{
Value: os.ID.String(),
},
},
UserData: userData,
}, osID, nil
switch os.Type {
case cdbm.OperatingSystemTypeIPXE:
result.RunProvisioningInstructionsOnEveryBoot = alwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{IpxeScript: *ipxeScript},
}
case cdbm.OperatingSystemTypeTemplatedIPXE:
result.RunProvisioningInstructionsOnEveryBoot = alwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OperatingSystemId{
OperatingSystemId: &cwssaws.OperatingSystemId{Value: os.ID.String()},
}
case cdbm.OperatingSystemTypeImage:
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{Value: os.ID.String()},
}
}
} else {
result.RunProvisioningInstructionsOnEveryBoot = alwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{IpxeScript: *ipxeScript},
}
}

return &cwssaws.InstanceOperatingSystemConfig{
RunProvisioningInstructionsOnEveryBoot: alwaysBootWithCustomIpxe,
PhoneHomeEnabled: phoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{
IpxeScript: *ipxeScript,
},
},
UserData: userData,
}, osID, nil
return &result, osID, nil
}

// Handle godoc
Expand Down
41 changes: 20 additions & 21 deletions rest-api/api/pkg/api/handler/instancebatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,28 +175,27 @@ func (bcih BatchCreateInstanceHandler) buildBatchInstanceCreateRequestOsConfig(c
// Options below should all have been set by the
// earlier call to ValidateAndSetOperatingSystemData

if os.Type == cdbm.OperatingSystemTypeIPXE {
return &cwssaws.InstanceOperatingSystemConfig{
RunProvisioningInstructionsOnEveryBoot: *apiRequest.AlwaysBootWithCustomIpxe,
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{
IpxeScript: *apiRequest.IpxeScript,
},
},
UserData: apiRequest.UserData,
}, osID, nil
} else {
return &cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
Variant: &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{
Value: os.ID.String(),
},
},
UserData: apiRequest.UserData,
}, osID, nil
result := cwssaws.InstanceOperatingSystemConfig{
PhoneHomeEnabled: *apiRequest.PhoneHomeEnabled,
UserData: apiRequest.UserData,
}
switch os.Type {
case cdbm.OperatingSystemTypeIPXE:
result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_Ipxe{
Ipxe: &cwssaws.InlineIpxe{IpxeScript: *apiRequest.IpxeScript},
}
case cdbm.OperatingSystemTypeTemplatedIPXE:
result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OperatingSystemId{
OperatingSystemId: &cwssaws.OperatingSystemId{Value: os.ID.String()},
}
case cdbm.OperatingSystemTypeImage:
result.Variant = &cwssaws.InstanceOperatingSystemConfig_OsImageId{
OsImageId: &cwssaws.UUID{Value: os.ID.String()},
}
}
return &result, osID, nil
Comment on lines +182 to +198

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add an explicit unsupported OS-type path in the switch.

At Line 182, the switch has no default, so an unknown os.Type returns success with Variant == nil. That produces an invalid InstanceOperatingSystemConfig and defers failure to the workflow layer.

Suggested fix
 	switch os.Type {
 	case cdbm.OperatingSystemTypeIPXE:
 		result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
 		result.Variant = &cwssaws.InstanceOperatingSystemConfig_Ipxe{
 			Ipxe: &cwssaws.InlineIpxe{IpxeScript: *apiRequest.IpxeScript},
 		}
 	case cdbm.OperatingSystemTypeTemplatedIPXE:
 		result.RunProvisioningInstructionsOnEveryBoot = *apiRequest.AlwaysBootWithCustomIpxe
 		result.Variant = &cwssaws.InstanceOperatingSystemConfig_OperatingSystemId{
 			OperatingSystemId: &cwssaws.OperatingSystemId{Value: os.ID.String()},
 		}
 	case cdbm.OperatingSystemTypeImage:
 		result.Variant = &cwssaws.InstanceOperatingSystemConfig_OsImageId{
 			OsImageId: &cwssaws.UUID{Value: os.ID.String()},
 		}
+	default:
+		logger.Error().Str("osType", os.Type).Msg("unsupported OperatingSystem type for batch create")
+		return nil, nil, cutil.NewAPIError(
+			http.StatusBadRequest,
+			"Unsupported OperatingSystem type specified in request data",
+			nil,
+		)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rest-api/api/pkg/api/handler/instancebatch.go` around lines 182 - 198, The
switch statement handling os.Type cases (OperatingSystemTypeIPXE,
OperatingSystemTypeTemplatedIPXE, OperatingSystemTypeImage) is missing a default
case, allowing unknown OS types to return success with a nil Variant field,
creating an invalid InstanceOperatingSystemConfig. Add a default case to the
switch statement that returns an error for any unsupported or unknown os.Type
values, preventing the function from silently returning an incomplete
configuration that would defer failure to the workflow layer.

}

// Handle godoc
Expand Down
Loading
Loading