forked from baron/baron-sso
백채널 로그아웃 URI 허용 범위 확장
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -2749,16 +2750,35 @@ func validateBackchannelLogoutURI(raw string) error {
|
||||
case "https":
|
||||
return nil
|
||||
case "http":
|
||||
host := strings.ToLower(parsed.Hostname())
|
||||
if host == "localhost" || host == "127.0.0.1" {
|
||||
if isAllowedLocalBackchannelLogoutHost(parsed.Hostname()) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("backchannelLogoutUri must use https outside localhost development")
|
||||
return fmt.Errorf("backchannelLogoutUri must use https outside local development")
|
||||
default:
|
||||
return fmt.Errorf("backchannelLogoutUri must use http or https")
|
||||
}
|
||||
}
|
||||
|
||||
func isAllowedLocalBackchannelLogoutHost(rawHost string) bool {
|
||||
host := strings.ToLower(strings.TrimSpace(rawHost))
|
||||
if host == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
switch host {
|
||||
case "localhost", "127.0.0.1", "::1", "host.docker.internal":
|
||||
return true
|
||||
}
|
||||
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
return ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()
|
||||
}
|
||||
|
||||
// Docker service names and other single-label local hostnames are
|
||||
// permitted only for local HTTP development workflows.
|
||||
return !strings.Contains(host, ".")
|
||||
}
|
||||
|
||||
func normalizeClientAutoLoginMetadata(metadata map[string]interface{}) (map[string]interface{}, error) {
|
||||
if metadata == nil {
|
||||
return metadata, nil
|
||||
|
||||
@@ -288,7 +288,26 @@ function isValidBackchannelLogoutUrl(value: string): boolean {
|
||||
if (url.protocol !== "http:") {
|
||||
return false;
|
||||
}
|
||||
return url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
||||
const host = url.hostname.toLowerCase();
|
||||
if (
|
||||
host === "localhost" ||
|
||||
host === "127.0.0.1" ||
|
||||
host === "::1" ||
|
||||
host === "host.docker.internal"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (/^\d+\.\d+\.\d+\.\d+$/.test(host)) {
|
||||
return (
|
||||
host.startsWith("10.") ||
|
||||
host.startsWith("192.168.") ||
|
||||
/^172\.(1[6-9]|2\d|3[0-1])\./.test(host) ||
|
||||
host.startsWith("169.254.")
|
||||
);
|
||||
}
|
||||
// Docker service names and other single-label local hosts are allowed
|
||||
// only for HTTP local development use.
|
||||
return !host.includes(".");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
@@ -949,7 +968,7 @@ function ClientGeneralPage() {
|
||||
throw new Error(
|
||||
t(
|
||||
"msg.dev.clients.general.backchannel_logout.invalid",
|
||||
"Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https, 로컬 개발 환경은 localhost/127.0.0.1의 http만 허용됩니다.",
|
||||
"Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https를 사용하고, 로컬 개발 환경은 localhost/127.0.0.1, host.docker.internal, Docker 서비스명, 사설 IP의 http만 허용됩니다.",
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1590,7 +1609,7 @@ function ClientGeneralPage() {
|
||||
<p className="text-xs text-destructive">
|
||||
{t(
|
||||
"msg.dev.clients.general.backchannel_logout.invalid",
|
||||
"Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https, 로컬 개발 환경은 localhost/127.0.0.1의 http만 허용됩니다.",
|
||||
"Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https를 사용하고, 로컬 개발 환경은 localhost/127.0.0.1, host.docker.internal, Docker 서비스명, 사설 IP의 http만 허용됩니다.",
|
||||
)}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -435,7 +435,7 @@ help = "Enter the redirect URIs. You can modify them in the Federation tab after
|
||||
|
||||
[msg.dev.clients.general.backchannel_logout]
|
||||
uri_help = "RP endpoint that receives Baron's session termination event via server-to-server POST."
|
||||
invalid = "The Back-Channel Logout URI format is invalid. Production requires https, and local development only allows http on localhost/127.0.0.1."
|
||||
invalid = "The Back-Channel Logout URI format is invalid. Production requires https, and local development only allows http on localhost/127.0.0.1, host.docker.internal, Docker service names, and private IPs."
|
||||
session_required_help = "Use this when the RP should process logout_token only if the sid claim is included."
|
||||
session_required_on = "On: process logout only when the logout_token contains a sid."
|
||||
session_required_off = "Off: process logout using sub even if sid is missing."
|
||||
|
||||
@@ -435,7 +435,7 @@ help = "인증 후 리다이렉트될 URI를 입력하세요. 생성 후 연동
|
||||
|
||||
[msg.dev.clients.general.backchannel_logout]
|
||||
uri_help = "Baron이 세션 종료 이벤트를 서버 간 POST로 전달할 RP endpoint입니다."
|
||||
invalid = "Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https, 로컬 개발 환경은 localhost/127.0.0.1의 http만 허용됩니다."
|
||||
invalid = "Back-Channel Logout URI 형식이 올바르지 않습니다. 운영 환경은 https를 사용하고, 로컬 개발 환경은 localhost/127.0.0.1, host.docker.internal, Docker 서비스명, 사설 IP의 http만 허용됩니다."
|
||||
session_required_help = "RP가 logout_token에 sid claim이 포함된 경우에만 처리하도록 요구할 때 사용합니다."
|
||||
session_required_on = "켜면: logout_token 안에 sid가 있을 때만 로그아웃 처리"
|
||||
session_required_off = "끄면: sid가 없어도 sub만으로 로그아웃 처리 가능"
|
||||
|
||||
Reference in New Issue
Block a user