Compare commits

...

2 Commits

Author SHA1 Message Date
alt-glitch
9aed1b2fe7 fix: restore accidentally deleted websocket close code assertion 2026-04-25 10:06:46 +05:30
alt-glitch
f87dbdf0a8 fix(web): reject empty values in PUT /api/env
The endpoint accepted empty strings, allowing any .env key to be
silently blanked out from the web UI. Add Pydantic validators to
reject empty keys and values.
2026-04-25 09:59:11 +05:30
2 changed files with 46 additions and 1 deletions

View File

@@ -53,7 +53,7 @@ try:
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from pydantic import BaseModel, field_validator
except ImportError:
raise SystemExit(
"Web UI requires fastapi and uvicorn.\n"
@@ -425,6 +425,20 @@ class EnvVarUpdate(BaseModel):
key: str
value: str
@field_validator("key")
@classmethod
def key_must_be_nonempty(cls, v: str) -> str:
if not v.strip():
raise ValueError("key must not be empty")
return v
@field_validator("value")
@classmethod
def value_must_be_nonempty(cls, v: str) -> str:
if not v.strip():
raise ValueError("value must not be empty; use DELETE /api/env to remove a key")
return v
class EnvVarDelete(BaseModel):
key: str

View File

@@ -1925,3 +1925,34 @@ class TestPtyWebSocket:
):
pass
assert exc.value.code == 4400
class TestEnvVarUpdateValidation:
"""PUT /api/env must reject empty values to prevent .env key destruction."""
def test_rejects_empty_value(self):
from hermes_cli.web_server import EnvVarUpdate
import pydantic
with pytest.raises(pydantic.ValidationError):
EnvVarUpdate(key="SOME_KEY", value="")
def test_rejects_whitespace_only_value(self):
from hermes_cli.web_server import EnvVarUpdate
import pydantic
with pytest.raises(pydantic.ValidationError):
EnvVarUpdate(key="SOME_KEY", value=" ")
def test_accepts_nonempty_value(self):
from hermes_cli.web_server import EnvVarUpdate
update = EnvVarUpdate(key="SOME_KEY", value="sk-abc123")
assert update.value == "sk-abc123"
def test_rejects_empty_key(self):
from hermes_cli.web_server import EnvVarUpdate
import pydantic
with pytest.raises(pydantic.ValidationError):
EnvVarUpdate(key="", value="some-value")