дȫÏîĿÉó²éÎÊÌⲢ·¢²¼ v1.1.9
¸ÄÓñ¾»ú¶ÀÁ¢ CA£¬»ָ´ CLI TLS УÑ飬±£»¤ƾ¾ÝÓëÅäÖò¢·¢±£´档 д Cursor Êý¾ݡ¢»Ự·¾¶¡¢´úÀíÉúÃüÖÜÆڡ¢ģÐÍÇëÇóÓë Skills Îļþ²Ù×÷¡£ Ϊ¶ÀÁ¢ Tab ·þÎñÔö¼ӿͻ§¶˼øȨ£¬Éý¼¶ÒÀÀµÓ빤¾ßÁ´£¬ÍêÉƷ¢²¼ԪÐÅϢͬ²½¡£ Ñé֤£ºÁ½¸ö Go ģ¿éµIJâÊÔ/vet¡¢¹ؼüģ¿é race¡¢ǰ¶˲âÊÔ/Éú²ú¹¹½¨/Éó¼ơ¢ Go ¿ɴï©¶´ɨÃèÓë macOS/Linux ¿ÉÐÐģ¿齻²æ±àÒë¾ùͨ¹ý¡£ Windows ¸ôÀëÆô¶¯ͨ¹ý£»δÍê³ɵĵã»÷ðÑ̺ÍԭÉúƽ̨Ñé֤¼ûÉó²鱨¸档
This commit is contained in:
46
internal/localaccess/origin.go
Normal file
46
internal/localaccess/origin.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Package localaccess prevents unrelated browser pages from driving local RPCs.
|
||||
package localaccess
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func AllowedOrigin(raw string) bool {
|
||||
if raw == "" {
|
||||
return true
|
||||
} // Native Cursor/CLI requests do not send Origin.
|
||||
u, err := url.Parse(raw)
|
||||
if err != nil || u.User != nil || u.Hostname() == "" {
|
||||
return false
|
||||
}
|
||||
switch strings.ToLower(u.Scheme) {
|
||||
case "vscode-file", "vscode-webview", "wails":
|
||||
return true
|
||||
case "http", "https":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
host := strings.ToLower(u.Hostname())
|
||||
if host == "localhost" || host == "wails.localhost" || net.ParseIP(host).IsLoopback() {
|
||||
return true
|
||||
}
|
||||
for _, domain := range []string{"cursor.sh", "cursor.com"} {
|
||||
if host == domain || strings.HasSuffix(host, "."+domain) {
|
||||
return u.Scheme == "https"
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Wrap(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !AllowedOrigin(r.Header.Get("Origin")) {
|
||||
http.Error(w, "untrusted browser origin", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
26
internal/localaccess/origin_test.go
Normal file
26
internal/localaccess/origin_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package localaccess
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNativeAndCursorOriginsAllowedUnrelatedPagesRejected(t *testing.T) {
|
||||
for _, origin := range []string{"", "vscode-file://vscode-app", "vscode-webview://fixture", "wails://wails", "http://127.0.0.1:9245", "https://api2.cursor.sh", "https://www.cursor.com"} {
|
||||
if !AllowedOrigin(origin) {
|
||||
t.Errorf("rejected %q", origin)
|
||||
}
|
||||
}
|
||||
for _, origin := range []string{"null", "https://evil.invalid", "https://api2.cursor.sh.evil.invalid", "https://api2.cursor.sh@evil.invalid", "file:///tmp/evil.html"} {
|
||||
called := false
|
||||
handler := Wrap(http.HandlerFunc(func(http.ResponseWriter, *http.Request) { called = true }))
|
||||
r := httptest.NewRequest(http.MethodPost, "http://127.0.0.1/rpc", nil)
|
||||
r.Header.Set("Origin", origin)
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, r)
|
||||
if w.Code != 403 || called {
|
||||
t.Errorf("origin %q reached backend", origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user