mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-11-19 22:53:41 +08:00
fix: 修复CodeReview发现的安全问题和代码质量问题 | fix security and code quality issues identified by CodeReview
- 修复JSON注入漏洞:使用json.Marshal()安全转义字符串内容 - 定义常量CHARS_PER_TOKEN替换硬编码的token估算数字4 - 处理UnmarshalJSON错误,避免静默失败并记录错误日志 - 定义常量替换硬编码的API端点路径,提高可维护性 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,13 @@ import (
|
|||||||
"github.com/songquanpeng/one-api/relay/relaymode"
|
"github.com/songquanpeng/one-api/relay/relaymode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NativeAnthropicEndpoint is the endpoint for native Anthropic API
|
||||||
|
NativeAnthropicEndpoint = "/v1/messages"
|
||||||
|
// ThirdPartyAnthropicEndpoint is the endpoint for third-party providers supporting Anthropic protocol
|
||||||
|
ThirdPartyAnthropicEndpoint = "/anthropic/v1/messages"
|
||||||
|
)
|
||||||
|
|
||||||
type Adaptor struct {
|
type Adaptor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +31,13 @@ func (a *Adaptor) Init(meta *meta.Meta) {
|
|||||||
func (a *Adaptor) GetRequestURL(meta *meta.Meta) (string, error) {
|
func (a *Adaptor) GetRequestURL(meta *meta.Meta) (string, error) {
|
||||||
// For native Anthropic API
|
// For native Anthropic API
|
||||||
if strings.Contains(meta.BaseURL, "api.anthropic.com") {
|
if strings.Contains(meta.BaseURL, "api.anthropic.com") {
|
||||||
return fmt.Sprintf("%s/v1/messages", meta.BaseURL), nil
|
return fmt.Sprintf("%s%s", meta.BaseURL, NativeAnthropicEndpoint), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// For third-party providers supporting Anthropic protocol (like DeepSeek)
|
// For third-party providers supporting Anthropic protocol (like DeepSeek)
|
||||||
// They typically expose the endpoint at /anthropic/v1/messages
|
// They typically expose the endpoint at /anthropic/v1/messages
|
||||||
baseURL := strings.TrimSuffix(meta.BaseURL, "/")
|
baseURL := strings.TrimSuffix(meta.BaseURL, "/")
|
||||||
return fmt.Sprintf("%s/anthropic/v1/messages", baseURL), nil
|
return fmt.Sprintf("%s%s", baseURL, ThirdPartyAnthropicEndpoint), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Request, meta *meta.Meta) error {
|
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Request, meta *meta.Meta) error {
|
||||||
|
|||||||
@@ -93,9 +93,15 @@ func ConvertRequest(textRequest model.GeneralOpenAIRequest) *Request {
|
|||||||
if message.Role == "system" && claudeRequest.System.IsEmpty() {
|
if message.Role == "system" && claudeRequest.System.IsEmpty() {
|
||||||
// Create a SystemPrompt from the string content
|
// Create a SystemPrompt from the string content
|
||||||
systemPrompt := SystemPrompt{}
|
systemPrompt := SystemPrompt{}
|
||||||
systemData := []byte(`"` + message.StringContent() + `"`) // Wrap in JSON string quotes
|
systemData, err := json.Marshal(message.StringContent()) // Safely escape string for JSON
|
||||||
_ = systemPrompt.UnmarshalJSON(systemData)
|
if err != nil {
|
||||||
claudeRequest.System = systemPrompt
|
logger.SysError(fmt.Sprintf("Failed to marshal system prompt: %v", err))
|
||||||
|
} else {
|
||||||
|
if err := systemPrompt.UnmarshalJSON(systemData); err != nil {
|
||||||
|
logger.SysError(fmt.Sprintf("Failed to unmarshal system prompt: %v", err))
|
||||||
|
}
|
||||||
|
claudeRequest.System = systemPrompt
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
claudeMessage := Message{
|
claudeMessage := Message{
|
||||||
|
|||||||
@@ -142,6 +142,12 @@ func getAnthropicRequestBody(c *gin.Context, anthropicRequest *anthropic.Request
|
|||||||
return bytes.NewBuffer(jsonData), nil
|
return bytes.NewBuffer(jsonData), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CHARS_PER_TOKEN represents the rough character-to-token ratio for Anthropic models
|
||||||
|
// This is a conservative estimate: approximately 1 token per 4 characters
|
||||||
|
CHARS_PER_TOKEN = 4
|
||||||
|
)
|
||||||
|
|
||||||
func estimateAnthropicTokens(request *anthropic.Request) int {
|
func estimateAnthropicTokens(request *anthropic.Request) int {
|
||||||
// Simple token estimation for Anthropic requests
|
// Simple token estimation for Anthropic requests
|
||||||
// This is a rough estimation, actual implementation might need more sophisticated logic
|
// This is a rough estimation, actual implementation might need more sophisticated logic
|
||||||
@@ -150,14 +156,14 @@ func estimateAnthropicTokens(request *anthropic.Request) int {
|
|||||||
// Count tokens in system prompt
|
// Count tokens in system prompt
|
||||||
if !request.System.IsEmpty() {
|
if !request.System.IsEmpty() {
|
||||||
systemText := request.System.String()
|
systemText := request.System.String()
|
||||||
totalTokens += len(systemText) / 4 // rough estimate: 1 token per 4 characters
|
totalTokens += len(systemText) / CHARS_PER_TOKEN // rough estimate: 1 token per 4 characters
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count tokens in messages
|
// Count tokens in messages
|
||||||
for _, message := range request.Messages {
|
for _, message := range request.Messages {
|
||||||
for _, content := range message.Content {
|
for _, content := range message.Content {
|
||||||
if content.Type == "text" {
|
if content.Type == "text" {
|
||||||
totalTokens += len(content.Text) / 4
|
totalTokens += len(content.Text) / CHARS_PER_TOKEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user