Files
Andrew ef8fbd530b
Some checks failed
Endpoint Sync Check / check-drift (push) Successful in 50s
CI / build (push) Failing after 1m26s
Fix path injection, sensitive attribute exposure, and error body truncation
Security fixes from audit:

- Escape user-supplied strings (ext_relation_id, interface_name) with
  url.PathEscape before interpolating into API URL paths, preventing
  path traversal via crafted values like "../admin" or "foo/bar"
- Mark auth token URL attributes as Sensitive in both
  virtfusion_user_auth_token and virtfusion_user_server_auth_token
  resources, since the URL embeds the signed token
- Truncate raw API error response bodies to 500 bytes in error messages
  to prevent leaking sensitive data from verbose Laravel error responses

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 02:07:34 -04:00

44 lines
1.2 KiB
Go

// Copyright (c) EZSCALE.
// SPDX-License-Identifier: MPL-2.0
package client
import "fmt"
// APIError represents an error returned by the VirtFusion API.
type APIError struct {
StatusCode int
Status string
Body string
Errors map[string][]string
}
// maxErrorBodyLen is the maximum number of bytes from the API response body
// to include in error messages, to avoid leaking sensitive data from verbose
// error responses.
const maxErrorBodyLen = 500
func (e *APIError) Error() string {
if len(e.Errors) > 0 {
return fmt.Sprintf("VirtFusion API error %d (%s): %v", e.StatusCode, e.Status, e.Errors)
}
if e.Body != "" {
body := e.Body
if len(body) > maxErrorBodyLen {
body = body[:maxErrorBodyLen] + "... (truncated)"
}
return fmt.Sprintf("VirtFusion API error %d (%s): %s", e.StatusCode, e.Status, body)
}
return fmt.Sprintf("VirtFusion API error %d (%s)", e.StatusCode, e.Status)
}
// IsNotFound returns true if the error is a 404 Not Found response.
func (e *APIError) IsNotFound() bool {
return e.StatusCode == 404
}
// IsValidationError returns true if the error is a 422 Unprocessable Entity response.
func (e *APIError) IsValidationError() bool {
return e.StatusCode == 422
}