fix: harden runtime deployment defaults
This commit is contained in:
+11
-14
@@ -64,11 +64,11 @@ async def exchange_code_for_user(code: str) -> Optional[dict]:
|
|||||||
"code": code,
|
"code": code,
|
||||||
}
|
}
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=15, verify=False) as client:
|
async with httpx.AsyncClient(timeout=15) as client:
|
||||||
try:
|
try:
|
||||||
resp = await client.post(token_url, data=data)
|
resp = await client.post(token_url, data=data)
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
logger.error(f"Casdoor token 换取失败: {resp.status_code} {resp.text}")
|
logger.error("Casdoor token 换取失败: status=%s", resp.status_code)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
token_data = resp.json()
|
token_data = resp.json()
|
||||||
@@ -77,19 +77,16 @@ async def exchange_code_for_user(code: str) -> Optional[dict]:
|
|||||||
logger.error("Casdoor 返回中没有 id_token")
|
logger.error("Casdoor 返回中没有 id_token")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 解码 id_token (JWT) payload,不验证签名(HTTPS 已保证传输安全)
|
|
||||||
# 生产环境建议验证 Casdoor 证书
|
|
||||||
cert = _load_casdoor_certificate()
|
cert = _load_casdoor_certificate()
|
||||||
try:
|
if not cert:
|
||||||
payload = jwt.decode(
|
logger.error("Casdoor token 验证证书未配置")
|
||||||
id_token,
|
return None
|
||||||
key=cert or None,
|
|
||||||
options={"verify_signature": bool(cert)},
|
payload = jwt.decode(
|
||||||
audience=settings.CASDOOR_CLIENT_ID,
|
id_token,
|
||||||
)
|
key=cert,
|
||||||
except JWTError:
|
audience=settings.CASDOOR_CLIENT_ID,
|
||||||
# 不验证签名的方式解码
|
)
|
||||||
payload = jwt.get_unverified_claims(id_token)
|
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_compose_does_not_embed_password_or_net_admin_capability():
|
||||||
|
compose = (ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
assert "POSTGRES_PASSWORD=pingwatch123" not in compose
|
||||||
|
assert "NET_ADMIN" not in compose
|
||||||
|
assert "127.0.0.1:8001:8000" in compose
|
||||||
|
|
||||||
|
|
||||||
|
def test_oauth_client_does_not_disable_tls_verification():
|
||||||
|
auth_source = (ROOT / "backend" / "app" / "core" / "auth.py").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
assert "verify=False" not in auth_source
|
||||||
+5
-7
@@ -6,10 +6,9 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- ./backend/.env
|
- ./backend/.env
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=postgresql+asyncpg://pingwatch:pingwatch123@db:5432/pingwatch
|
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
ports:
|
ports:
|
||||||
- "8001:8000"
|
- "127.0.0.1:8001:8000"
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -18,8 +17,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- pingwatch-net
|
- pingwatch-net
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_RAW # 允许 ICMP ping
|
- NET_RAW
|
||||||
- NET_ADMIN # 允许原始套接字
|
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
build: ./frontend
|
build: ./frontend
|
||||||
@@ -40,9 +38,9 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- POSTGRES_DB=pingwatch
|
- POSTGRES_DB=${POSTGRES_DB:-pingwatch}
|
||||||
- POSTGRES_USER=pingwatch
|
- POSTGRES_USER=${POSTGRES_USER:-pingwatch}
|
||||||
- POSTGRES_PASSWORD=pingwatch123
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in backend/.env}
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
Reference in New Issue
Block a user