fix: harden lease registration, remove InsecureSkipVerify

Kim committed Mar 3, 2026 at 10:41 UTC fa6ccb4a4dfcf87e1d26659d7c76327676e9bf68
2 files changed +39 -5
cmd/relay-server/registry.go
+37 -2
@@ -64,6 +64,33 @@ func (r *SDKRegistry) handleRegister(w http.ResponseWriter, req *http.Request, s
64 return
65 }
66
67 + if registerReq.LeaseID == "" {
68 + writeJSON(w, sdk.RegisterResponse{
69 + Success: false,
70 + Message: "lease_id is required",
71 + })
72 + return
73 + }
74 +
75 + if registerReq.ReverseToken == "" {
76 + writeJSON(w, sdk.RegisterResponse{
77 + Success: false,
78 + Message: "reverse_token is required",
79 + })
80 + return
81 + }
82 +
83 + // Ownership semantics: re-registration of an existing lease ID requires the same reverse token.
84 + if entry, ok := serv.GetLeaseManager().GetLeaseByID(registerReq.LeaseID); ok && entry != nil && entry.Lease != nil {
85 + if subtle.ConstantTimeCompare([]byte(strings.TrimSpace(entry.Lease.ReverseToken)), []byte(registerReq.ReverseToken)) != 1 {
86 + writeJSON(w, sdk.RegisterResponse{
87 + Success: false,
88 + Message: "unauthorized lease registration",
89 + })
90 + return
91 + }
92 + }
93 +
94 // Create lease
95 lease := &portal.Lease{
96 ID: registerReq.LeaseID,
@@ -71,7 +98,7 @@ func (r *SDKRegistry) handleRegister(w http.ResponseWriter, req *http.Request, s
98 Metadata: registerReq.Metadata,
99 Expires: time.Now().Add(30 * time.Second),
100 TLSMode: string(registerReq.TLSMode),
74 - ReverseToken: strings.TrimSpace(registerReq.ReverseToken),
101 + ReverseToken: registerReq.ReverseToken,
102 }
103
104 // Register with lease manager
@@ -166,6 +193,14 @@ func (r *SDKRegistry) handleRenew(w http.ResponseWriter, req *http.Request, serv
193 return
194 }
195
196 + if renewReq.ReverseToken == "" {
197 + writeJSON(w, sdk.RegisterResponse{
198 + Success: false,
199 + Message: "reverse_token is required",
200 + })
201 + return
202 + }
203 +
204 // Get existing lease
205 entry, ok := serv.GetLeaseManager().GetLeaseByID(renewReq.LeaseID)
206 if !ok {
@@ -175,7 +210,7 @@ func (r *SDKRegistry) handleRenew(w http.ResponseWriter, req *http.Request, serv
210 })
211 return
212 }
178 - if subtle.ConstantTimeCompare([]byte(strings.TrimSpace(entry.Lease.ReverseToken)), []byte(strings.TrimSpace(renewReq.ReverseToken))) != 1 {
213 + if subtle.ConstantTimeCompare([]byte(strings.TrimSpace(entry.Lease.ReverseToken)), []byte(renewReq.ReverseToken)) != 1 {
214 writeJSON(w, sdk.APIResponse{
215 Success: false,
216 Message: "unauthorized lease renewal",
portal/keyless/bootstrap.go
+2 -3
@@ -131,9 +131,8 @@ func FetchEndpointCertificateChain(ctx context.Context, endpoint string, serverN
131 }
132
133 tlsConn := tls.Client(rawConn, &tls.Config{
134 - MinVersion: tls.VersionTLS12,
135 - ServerName: serverName,
136 - InsecureSkipVerify: true,
134 + MinVersion: tls.VersionTLS12,
135 + ServerName: serverName,
136 })
137 defer tlsConn.Close()
138 if err := tlsConn.HandshakeContext(ctx); err != nil {