mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-04 05:02:06 +03:00
ede275e4dc
The remote certificate fetch now dials through the same netsafe guard as the REALITY target scan. A private or loopback endpoint is refused unless the request carries allowPrivate; the inbound form asks the operator to confirm and retries with the opt-in.
39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
package service
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/mhsanaei/3x-ui/v3/internal/util/netsafe"
|
|
)
|
|
|
|
func TestGetRemoteCertHashGuardsPrivateTargets(t *testing.T) {
|
|
srv := httptest.NewTLSServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
|
|
defer srv.Close()
|
|
target := strings.TrimPrefix(srv.URL, "https://")
|
|
sum := sha256.Sum256(srv.Certificate().Raw)
|
|
want := hex.EncodeToString(sum[:])
|
|
|
|
t.Run("loopback refused without opt-in", func(t *testing.T) {
|
|
hashes, err := (&ServerService{}).GetRemoteCertHash(target, false)
|
|
if !errors.Is(err, netsafe.ErrPrivateAddressBlocked) {
|
|
t.Fatalf("GetRemoteCertHash(%s) = %v, %v; want ErrPrivateAddressBlocked", target, hashes, err)
|
|
}
|
|
})
|
|
|
|
t.Run("loopback read with opt-in", func(t *testing.T) {
|
|
hashes, err := (&ServerService{}).GetRemoteCertHash(target, true)
|
|
if err != nil {
|
|
t.Fatalf("GetRemoteCertHash(%s, allowPrivate): %v", target, err)
|
|
}
|
|
if len(hashes) != 1 || hashes[0] != want {
|
|
t.Fatalf("hashes = %v, want [%s]", hashes, want)
|
|
}
|
|
})
|
|
}
|