Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package securityaudit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPromptAuditLogAllowlistAndErrorsDoNotLeakCanarySecrets(t *testing.T) {
|
||||
const canary = "PROMPT_AUDIT_CANARY_SECRET_DO_NOT_PERSIST"
|
||||
var output bytes.Buffer
|
||||
previous := slog.Default()
|
||||
slog.SetDefault(slog.New(slog.NewJSONHandler(&output, nil)))
|
||||
t.Cleanup(func() { slog.SetDefault(previous) })
|
||||
|
||||
LogWarn(EventConfigReloadDegraded, map[string]any{
|
||||
"status": "degraded",
|
||||
"error_code": "config_reload_failed",
|
||||
"error_kind": "Authorization: Bearer " + canary,
|
||||
"token": canary,
|
||||
"body": canary,
|
||||
"base_url": "https://guard.example.test/path?api_key=" + canary,
|
||||
"raw_prompt": "prompt " + canary,
|
||||
})
|
||||
require.NotContains(t, output.String(), canary)
|
||||
require.NotContains(t, output.String(), "api_key=")
|
||||
require.Contains(t, output.String(), EventConfigReloadDegraded)
|
||||
|
||||
beforeUnknown := output.Len()
|
||||
LogWarn("prompt_audit.typo_event", map[string]any{"status": "failed"})
|
||||
require.Equal(t, beforeUnknown, output.Len(), "events outside the stable dictionary must not be emitted")
|
||||
require.Len(t, knownLogEvents, 28)
|
||||
|
||||
_, err := NormalizeBaseURL("https://guard.example.test/path?token=" + canary)
|
||||
require.Error(t, err)
|
||||
require.NotContains(t, err.Error(), canary)
|
||||
}
|
||||
|
||||
func TestPromptGuardFailureLogUsesCompleteAllowlistedContextAndNoSideEffects(t *testing.T) {
|
||||
var output bytes.Buffer
|
||||
previous := slog.Default()
|
||||
slog.SetDefault(slog.New(slog.NewJSONHandler(&output, nil)))
|
||||
t.Cleanup(func() { slog.SetDefault(previous) })
|
||||
groupID := int64(9)
|
||||
snapshot := PromptSnapshot{
|
||||
RequestID: "req-1", UserID: 2, APIKeyID: 3, GroupID: &groupID,
|
||||
Provider: "openai", Protocol: "openai_chat", Endpoint: "/v1/chat/completions",
|
||||
Model: "gpt-test", Stage: "http",
|
||||
}
|
||||
logGuardFailure(snapshot, ActiveConfig{ConfigVersion: 7}, DecisionUnavailable, ErrorCodeUnavailable, "guard-1", 25*time.Millisecond)
|
||||
|
||||
var entry map[string]any
|
||||
require.NoError(t, json.Unmarshal(output.Bytes(), &entry))
|
||||
for key := range snapshotLogFields(snapshot) {
|
||||
require.Contains(t, entry, key)
|
||||
}
|
||||
require.EqualValues(t, 7, entry["config_version"])
|
||||
require.Equal(t, ErrorCodeUnavailable, entry["error_code"])
|
||||
require.Equal(t, false, entry["upstream_dispatched"])
|
||||
require.Equal(t, false, entry["billing_preconsumed"])
|
||||
require.EqualValues(t, 25, entry["latency_ms"])
|
||||
}
|
||||
Reference in New Issue
Block a user