Harden auth recovery flow and disable perpetual admin tokens by default#6
Conversation
Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com>
Reviewer's GuideTightens security around password recovery and admin token issuance by introducing randomized verification codes, scope normalization/validation, session purging and abuse controls for recovery flows, and making non-expiring admin tokens opt-in via environment configuration, backed by focused tests. Sequence diagram for hardened password recovery flowsequenceDiagram
actor User
participant AuthRouter
participant PasswordRecoveryStore
User->>AuthRouter: POST /recovery/start (user_hint, scope)
AuthRouter->>AuthRouter: _purge_expired_password_recovery_sessions
AuthRouter->>AuthRouter: _normalize_password_recovery_scope
AuthRouter->>PasswordRecoveryStore: Create recovery_session
Note over PasswordRecoveryStore: Store user_id, scope, verified=false,
Note over PasswordRecoveryStore: verification_code=random_6_digits,
Note over PasswordRecoveryStore: verification_attempts=0, expires_at
User->>AuthRouter: POST /recovery/verify-identity
AuthRouter->>AuthRouter: _purge_expired_password_recovery_sessions
AuthRouter->>PasswordRecoveryStore: Load recovery_session
AuthRouter->>AuthRouter: Check expires_at
alt session_expired_or_missing
AuthRouter-->>User: 404 or 410 error
else session_ok
AuthRouter->>AuthRouter: compare_digest(input_code, expected_code)
alt code_mismatch
AuthRouter->>PasswordRecoveryStore: Increment verification_attempts
alt attempts_exceeded
AuthRouter->>PasswordRecoveryStore: Delete recovery_session
AuthRouter-->>User: 429 too many attempts
else attempts_remaining
AuthRouter-->>User: 401 invalid code
end
else code_match
AuthRouter->>AuthRouter: _issue_recovery_token for reset
AuthRouter->>PasswordRecoveryStore: Set verified=true
AuthRouter->>PasswordRecoveryStore: Store identity_session_token
AuthRouter->>PasswordRecoveryStore: Store reset_token, reset_expires_at
AuthRouter->>PasswordRecoveryStore: Reset verification_attempts=0
AuthRouter-->>User: recovery_session_token, reset_token
end
end
User->>AuthRouter: POST /recovery/reset-password
AuthRouter->>AuthRouter: _purge_expired_password_recovery_sessions
AuthRouter->>AuthRouter: Validate new_password length
AuthRouter->>AuthRouter: _normalize_password_recovery_scope
AuthRouter->>PasswordRecoveryStore: Find session by scope and compare_digest(reset_token)
alt no_matching_session
AuthRouter-->>User: 404 reset token not found
else session_found
AuthRouter->>AuthRouter: Check verified and identity_session_token
alt not_verified_or_missing_identity
AuthRouter-->>User: 403 identity verification incomplete
else verified
AuthRouter->>AuthRouter: Check reset_expires_at
alt reset_token_expired
AuthRouter->>PasswordRecoveryStore: Delete recovery_session
AuthRouter-->>User: 410 reset token expired
else reset_token_valid
AuthRouter->>AuthRouter: Update user password
AuthRouter->>PasswordRecoveryStore: Delete recovery_session
AuthRouter-->>User: 200 password reset success
end
end
end
Flow diagram for password recovery session lifecycle and abuse controlsflowchart TD
A["Start password recovery request"] --> B["_purge_expired_password_recovery_sessions"]
B --> C["Normalize and validate scope (admin or user)"]
C --> D["Lookup user by email or username"]
D -->|not found| E["404 no matching account"]
D -->|found| F{"Scope admin and user not admin/superuser?"}
F -->|yes| G["403 admin-only recovery path"]
F -->|no| H["Create recovery session in store\nverification_code=random 6 digits\nverification_attempts=0\nverified=false"]
H --> I["Send verification code to user"]
subgraph Identity verification
I --> J["User submits verification code"]
J --> K["_purge_expired_password_recovery_sessions"]
K --> L{"Recovery session exists and not expired?"}
L -->|no| M["404 or 410 session error"]
L -->|yes| N{"compare_digest(input_code, stored_code)"}
N -->|mismatch| O["Increment verification_attempts"]
O --> P{"attempts >= PASSWORD_RECOVERY_MAX_VERIFY_ATTEMPTS?"}
P -->|yes| Q["Delete session and return 429 too many attempts"]
P -->|no| R["Return 401 invalid code"]
N -->|match| S["Mark verified=true, reset verification_attempts=0\nissue reset_token and reset_expires_at\nstore identity_session_token"]
end
S --> T["User submits reset password request"]
subgraph Password reset
T --> U["_purge_expired_password_recovery_sessions"]
U --> V["Validate new_password length >= 8"]
V -->|invalid| W["400 weak password"]
V -->|valid| X["Normalize and validate scope"]
X --> Y["Find session with matching scope\nand compare_digest(reset_token)"]
Y -->|not found| Z["404 reset token not found"]
Y -->|found| AA{"verified is true and identity_session_token present?"}
AA -->|no| AB["403 identity verification incomplete"]
AA -->|yes| AC{"reset_expires_at > now?"}
AC -->|no| AD["Delete session and return 410 reset token expired"]
AC -->|yes| AE["Update user password"]
AE --> AF["Delete recovery session from store"]
AF --> AG["Return 200 password reset success"]
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
수고했습니다, 부조종사님 |
There was a problem hiding this comment.
Hey - I've found 8 issues, and left some high level feedback:
- The
_should_issue_non_expiring_admin_tokenhelper re-parses theALLOW_NON_EXPIRING_ADMIN_TOKENSenvironment variable on every call; consider reading this once into a config or module-level flag to avoid repeated env/string work on hot paths. - Both
_purge_expired_password_recovery_sessionsandreset_password_via_recoveryiterate linearly over_password_recovery_store; if this store can grow, consider indexing sessions by reset token (and/or expiry) to avoid O(n) scans on every recovery-related request.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `_should_issue_non_expiring_admin_token` helper re-parses the `ALLOW_NON_EXPIRING_ADMIN_TOKENS` environment variable on every call; consider reading this once into a config or module-level flag to avoid repeated env/string work on hot paths.
- Both `_purge_expired_password_recovery_sessions` and `reset_password_via_recovery` iterate linearly over `_password_recovery_store`; if this store can grow, consider indexing sessions by reset token (and/or expiry) to avoid O(n) scans on every recovery-related request.
## Individual Comments
### Comment 1
<location path="backend/auth_router.py" line_range="265-266" />
<code_context>
+ return f"{randbelow(1_000_000):06d}"
+
+
+def _normalize_password_recovery_scope(scope: str) -> str:
+ normalized = str(scope or "admin").strip().lower()
+ if normalized not in _PASSWORD_RECOVERY_ALLOWED_SCOPES:
+ raise HTTPException(
</code_context>
<issue_to_address>
**🚨 issue (security):** Defaulting a falsy scope to 'admin' is risky and may accidentally elevate recovery privileges.
`scope or "admin"` makes any falsy or empty scope (e.g. missing field, empty string) behave as an admin recovery request, so validation failures can silently become admin flows. Consider either defaulting to a non-privileged scope like `"user"` or requiring a non-empty scope and raising if it’s falsy.
</issue_to_address>
### Comment 2
<location path="backend/auth_router.py" line_range="626-628" />
<code_context>
matched_session = None
for session_token, session_state in _password_recovery_store.items():
- if session_state.get("reset_token") == payload.reset_token and session_state.get("scope") == payload.scope:
+ if (
+ session_state.get("scope") == scope
+ and compare_digest(str(session_state.get("reset_token") or ""), payload.reset_token)
+ ):
matched_session = (session_token, session_state)
</code_context>
<issue_to_address>
**suggestion:** Consider normalizing the incoming reset token before constant-time comparison to reduce UX friction.
`payload.reset_token` is compared verbatim to a normalized session token. If the client sends the correct token with extra whitespace (e.g. from copy‑paste), `compare_digest` will fail. Trimming or otherwise normalizing `payload.reset_token` (for example, `payload.reset_token.strip()`) before comparison would handle these cases without affecting security.
Suggested implementation:
```python
scope = _normalize_password_recovery_scope(payload.scope)
normalized_reset_token = (payload.reset_token or "").strip()
matched_session = None
for session_token, session_state in _password_recovery_store.items():
```
```python
if (
session_state.get("scope") == scope
and compare_digest(str(session_state.get("reset_token") or ""), normalized_reset_token)
):
```
</issue_to_address>
### Comment 3
<location path="tests/test_auth_router_security.py" line_range="58-67" />
<code_context>
+ return importlib.import_module("backend.auth_router")
+
+
+def test_admin_tokens_expire_by_default(monkeypatch):
+ monkeypatch.delenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", raising=False)
+ auth_router = _load_auth_router(monkeypatch)
+ admin_user = SimpleNamespace(is_admin=True, is_superuser=False)
+
+ assert auth_router._should_issue_non_expiring_admin_token(admin_user) is False
+
+ monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", "true")
+ auth_router = _load_auth_router(monkeypatch)
+ assert auth_router._should_issue_non_expiring_admin_token(admin_user) is True
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add parametrized tests for all supported ALLOW_NON_EXPIRING_ADMIN_TOKENS values and non-admin users
This test only covers the default and a single truthy value. Since `_should_issue_non_expiring_admin_token` accepts multiple truthy strings and depends on admin/superuser flags, please parameterize it to cover:
- All accepted truthy values (e.g. `"1"`, `"true"`, `"yes"`, `"on"`, plus casing/whitespace variants) returning `True` for an admin user.
- A non-admin user returning `False` even when the env var is a truthy value.
- Falsy/invalid values (e.g. `"false"`, `"0"`, `"random"`) returning `False` for an admin user.
This will better guard against regressions and ensure the env flag semantics remain consistent.
Suggested implementation:
```python
import pytest
from fastapi import HTTPException
from types import SimpleNamespace
```
```python
@pytest.mark.parametrize(
"env_value",
[
"1",
"true",
"yes",
"on",
"TRUE",
"Yes",
"On",
" true ",
],
)
def test_should_issue_non_expiring_admin_token_for_truthy_values(monkeypatch, env_value):
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
admin_user = SimpleNamespace(is_admin=True, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(admin_user) is True
@pytest.mark.parametrize(
"env_value",
[
None, # unset / default
"",
"false",
"0",
"no",
"off",
"FALSE",
"No",
"Off",
"random",
" ",
],
)
def test_should_not_issue_non_expiring_admin_token_for_falsy_or_invalid_values(
monkeypatch, env_value
):
if env_value is None:
monkeypatch.delenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", raising=False)
else:
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
admin_user = SimpleNamespace(is_admin=True, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(admin_user) is False
@pytest.mark.parametrize(
"env_value",
[
"1",
"true",
"yes",
"on",
"TRUE",
"Yes",
"On",
" true ",
],
)
def test_should_not_issue_non_expiring_token_for_non_admin_users(monkeypatch, env_value):
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
non_admin_user = SimpleNamespace(is_admin=False, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(non_admin_user) is False
```
</issue_to_address>
### Comment 4
<location path="tests/test_auth_router_security.py" line_range="70-86" />
<code_context>
+ assert auth_router._should_issue_non_expiring_admin_token(admin_user) is True
+
+
+def test_start_password_recovery_uses_random_verification_code(monkeypatch):
+ auth_router = _load_auth_router(monkeypatch)
+ auth_router._password_recovery_store.clear()
+ monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 123456)
+ db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False))
+
+ response = auth_router.start_password_recovery(
+ auth_router.PasswordRecoveryStartRequest(
+ scope="admin",
+ user_hint="admin@example.com",
+ ),
+ db,
+ )
+
+ session_state = auth_router._password_recovery_store[response["recovery_session_token"]]
+ assert session_state["verification_code"] == "123456"
+ assert session_state["verification_code"] != "000000"
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Cover zero-padding and multi-session behavior of the recovery verification code
To strengthen this test, consider adding:
- Zero-padding: monkeypatch `randbelow` to return a small value (e.g. `42`) and assert `verification_code == "000042"` to cover the formatting logic.
- Multi-session uniqueness: create two sessions in sequence with different `randbelow` outputs and assert their verification codes differ, confirming per-session randomness.
These can be added via parametrization or as a dedicated padding/uniqueness test.
```suggestion
def test_start_password_recovery_uses_random_verification_code(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 123456)
db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False))
response = auth_router.start_password_recovery(
auth_router.PasswordRecoveryStartRequest(
scope="admin",
user_hint="admin@example.com",
),
db,
)
session_state = auth_router._password_recovery_store[response["recovery_session_token"]]
assert session_state["verification_code"] == "123456"
assert session_state["verification_code"] != "000000"
def test_start_password_recovery_zero_pads_verification_code(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
# Force a small random value to exercise zero-padding logic
monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 42)
db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False))
response = auth_router.start_password_recovery(
auth_router.PasswordRecoveryStartRequest(
scope="admin",
user_hint="admin@example.com",
),
db,
)
session_state = auth_router._password_recovery_store[response["recovery_session_token"]]
assert session_state["verification_code"] == "000042"
def test_start_password_recovery_generates_unique_codes_per_session(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
# Simulate different random outputs for consecutive sessions
random_values = iter([123456, 654321])
def _fake_randbelow(upper_bound):
return next(random_values)
monkeypatch.setattr(auth_router, "randbelow", _fake_randbelow)
db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False))
response1 = auth_router.start_password_recovery(
auth_router.PasswordRecoveryStartRequest(
scope="admin",
user_hint="admin1@example.com",
),
db,
)
response2 = auth_router.start_password_recovery(
auth_router.PasswordRecoveryStartRequest(
scope="admin",
user_hint="admin2@example.com",
),
db,
)
session_state1 = auth_router._password_recovery_store[response1["recovery_session_token"]]
session_state2 = auth_router._password_recovery_store[response2["recovery_session_token"]]
assert session_state1["verification_code"] == "123456"
assert session_state2["verification_code"] == "654321"
assert session_state1["verification_code"] != session_state2["verification_code"]
```
</issue_to_address>
### Comment 5
<location path="tests/test_auth_router_security.py" line_range="89-98" />
<code_context>
+def test_password_recovery_verify_identity_limits_failed_attempts(monkeypatch):
</code_context>
<issue_to_address>
**suggestion (testing):** Add a positive-path test for identity verification, including reset of attempt counter and reset-token issuance
This test covers the failure path and 401/429 behavior well. To fully cover `verify_password_recovery_identity`, please also add a positive-path test that:
- Begins with a session where `verification_attempts` > 0,
- Submits a correct `verification_code`,
- Asserts that:
- `session_state["verified"]` becomes `True`,
- `session_state["verification_attempts"]` is reset to `0`,
- `identity_session_token`, `reset_token`, and `reset_expires_at` are correctly set,
- The response exposes a usable `reset_token`.
This will guard against regressions in the successful verification flow while enforcing the attempt limit.
Suggested implementation:
```python
def test_password_recovery_verify_identity_limits_failed_attempts(monkeypatch):
def test_password_recovery_verify_identity_success_resets_attempts_and_issues_reset_token(monkeypatch, db):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
recovery_session_token = "recovery_test_success"
auth_router._password_recovery_store[recovery_session_token] = {
"user_id": 1,
"scope": "admin",
"verified": False,
"verification_code": "654321",
"verification_attempts": 2,
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
response = auth_router.verify_password_recovery_identity(
recovery_session_token=recovery_session_token,
verification_code="654321",
db=db,
)
session_state = auth_router._password_recovery_store[recovery_session_token]
# verification flag should be set
assert session_state["verified"] is True
# attempts counter should be reset
assert session_state["verification_attempts"] == 0
# reset / identity session fields should be issued
assert "identity_session_token" in session_state
assert "reset_token" in session_state
assert "reset_expires_at" in session_state
# response should expose usable reset_token
assert response["reset_token"] == session_state["reset_token"]
```
To wire this in cleanly you may need to:
1. Confirm the verification entry point and adapt the call accordingly:
- If the API is different (e.g. `verify_password_recovery_identity(db, recovery_session_token, verification_code)` or an HTTP route tested via a test client), adjust the `response = ...` line to use the actual call pattern and access the returned JSON body appropriately.
2. Ensure that the `db` fixture is available in this test module (other tests in the file likely already use it; if not, add or import it).
3. Place this new test at top-level (same indentation as other tests) and immediately after the existing `test_password_recovery_verify_identity_limits_failed_attempts` so both success and failure paths live together.
4. If your implementation uses different session-state keys (e.g. `"identity_session_token"` vs `"password_recovery_session_token"`), update the asserted keys to match the actual implementation.
</issue_to_address>
### Comment 6
<location path="tests/test_auth_router_security.py" line_range="118-127" />
<code_context>
+def test_reset_password_requires_verified_identity(monkeypatch):
</code_context>
<issue_to_address>
**suggestion (testing):** Distinguish between unverified and missing identity session token in reset-password tests
This test covers the `verified=False` → 403 behavior. The implementation also requires a non-empty `identity_session_token`. Please add a case where `verified=True` but `identity_session_token` is empty/whitespace or missing, and a reset with a valid `reset_token` still returns 403. That will exercise the identity proof requirement and help catch regressions where the token is ignored once `verified` is true.
Suggested implementation:
```python
def test_reset_password_requires_verified_identity(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
# Case 1: identity not verified → reset must be forbidden even with a valid reset token
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": False,
"reset_token": "reset_token",
"reset_expires_at": datetime.utcnow() + timedelta(minutes=5),
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
with pytest.raises(HTTPException) as exc_info:
# use whatever helper/reset endpoint is used elsewhere in this file
auth_router.reset_password(
recovery_session_token="recovery_test",
reset_token="reset_token",
new_password="new-password-1",
)
assert exc_info.value.status_code == 403
# Case 2: identity marked verified but missing/blank identity_session_token → still forbidden
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
# intentionally omit or blank out identity_session_token to simulate missing proof
"identity_session_token": " ",
"reset_token": "reset_token",
"reset_expires_at": datetime.utcnow() + timedelta(minutes=5),
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
with pytest.raises(HTTPException) as exc_info:
auth_router.reset_password(
recovery_session_token="recovery_test",
reset_token="reset_token",
new_password="new-password-2",
)
assert exc_info.value.status_code == 403
```
1. Replace `auth_router.reset_password(...)` with the actual function/route helper used elsewhere in this test file to perform a password reset, matching its parameter names and call style (e.g. using `client.post("/reset-password", json=...)` or similar).
2. Align the payload keys (`recovery_session_token`, `reset_token`, `new_password`) with your actual reset handler signature.
3. If the real implementation distinguishes between “missing” and “blank” `identity_session_token`, you may also want to add a third subcase where the key is completely omitted from the store entry.
</issue_to_address>
### Comment 7
<location path="tests/test_auth_router_security.py" line_range="143-152" />
<code_context>
+def test_reset_password_updates_hash_and_clears_session(monkeypatch):
</code_context>
<issue_to_address>
**suggestion (testing):** Add tests for scope normalization and invalid scopes in the recovery flow
The current test only covers the happy path for an `admin` scope, but the implementation now normalizes and validates scopes in both `start_password_recovery` and `reset_password_via_recovery`. Please add tests that:
- Use mixed-case and whitespace scopes (e.g. `" Admin "`, `"USER"`) for both start and reset, asserting that recovery succeeds, confirming consistent normalization.
- Use invalid scopes (e.g. `"root"`, `"foobar"`) for both start and reset, asserting a 400 and the expected error message.
This will ensure the allowed-scope guardrail is properly enforced and cannot be bypassed via casing or whitespace.
Suggested implementation:
```python
def test_reset_password_updates_hash_and_clears_session(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry for the user
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
# Perform the reset
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope="admin",
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
# Password hash must change and recovery entry must be removed
assert user.hashed_password != "old"
assert "recovery_test" not in auth_router._password_recovery_store
def test_start_password_recovery_normalizes_scope(monkeypatch):
"""start_password_recovery should accept mixed-case/whitespace scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, email="user@example.com", hashed_password="old")
db = _FakeDB(user)
# Use mixed-case and whitespace for scope
request = SimpleNamespace(
email="user@example.com",
scope=" Admin ",
)
auth_router.start_password_recovery(request, db)
# Recovery entry should exist and have normalized scope (e.g. 'admin')
assert len(auth_router._password_recovery_store) == 1
recovery = next(iter(auth_router._password_recovery_store.values()))
assert recovery["user_id"] == user.id
assert recovery["scope"] == "admin"
def test_start_password_recovery_rejects_invalid_scope(monkeypatch):
"""start_password_recovery should reject invalid scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, email="user@example.com", hashed_password="old")
db = _FakeDB(user)
for invalid_scope in ["root", "foobar"]:
request = SimpleNamespace(
email="user@example.com",
scope=invalid_scope,
)
with pytest.raises(HTTPException) as exc_info:
auth_router.start_password_recovery(request, db)
assert exc_info.value.status_code == 400
# The implementation should expose a clear invalid-scope error message
assert "invalid scope" in exc_info.value.detail.lower()
def test_reset_password_via_recovery_normalizes_scope(monkeypatch):
"""reset_password_via_recovery should accept mixed-case/whitespace scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry with normalized scope
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
# Call reset with mixed-case and extra whitespace in scope
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope=" Admin ",
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
# Ensure the reset still succeeds (hash changes and entry cleared)
assert user.hashed_password != "old"
assert "recovery_test" not in auth_router._password_recovery_store
def test_reset_password_via_recovery_rejects_invalid_scope(monkeypatch):
"""reset_password_via_recovery should reject invalid scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry with an allowed scope
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
for invalid_scope in ["root", "foobar"]:
with pytest.raises(HTTPException) as exc_info:
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope=invalid_scope,
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
assert exc_info.value.status_code == 400
assert "invalid scope" in exc_info.value.detail.lower()
```
The above tests assume the following, based on typical patterns in this file:
1. `start_password_recovery(request, db)` accepts a `request` object with `email` and `scope` attributes and raises `HTTPException` on invalid scope, with a message that includes "invalid scope".
2. `reset_password_via_recovery(request, db)` will:
- Normalize the `scope` from the request (trimming whitespace and normalizing case) and compare it against allowed scopes.
- Raise `HTTPException(status_code=400, detail="...invalid scope...")` when the scope is invalid.
3. `auth_router._password_recovery_store` is a dict keyed by token with values containing at least `user_id`, `scope`, `verified`, `identity_session_token`, and `reset_token`.
If your actual request/DB interfaces or error messages differ, adjust:
- The `SimpleNamespace` fields used to construct the `request` objects.
- The error-message substring checks (`"invalid scope"`).
- Any additional assertions you want (e.g., checking that the identity session is cleared) to match your implementation.
</issue_to_address>
### Comment 8
<location path="tests/test_auth_router_security.py" line_range="38-47" />
<code_context>
+ self.committed = True
+
+
+def _load_auth_router(monkeypatch):
+ sys.modules.pop("backend.auth_router", None)
+
+ fake_database = types.ModuleType("backend.database")
+ fake_database.get_db = lambda: None
+
+ fake_models = types.ModuleType("backend.models")
+
+ class _StubUser:
+ id = "id"
+ email = "email"
+ username = "username"
+
+ fake_models.User = _StubUser
+
+ monkeypatch.setitem(sys.modules, "backend.database", fake_database)
+ monkeypatch.setitem(sys.modules, "backend.models", fake_models)
+ return importlib.import_module("backend.auth_router")
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add coverage for purging expired password recovery sessions before start/verify/reset
Since `_purge_expired_password_recovery_sessions` is now invoked by all three recovery endpoints, it’d be helpful to add tests that:
- Populate `_password_recovery_store` with both an expired and a valid session.
- Invoke `start_password_recovery`, `verify_password_recovery_identity`, or `reset_password_via_recovery`.
- Assert that the expired session is removed and the endpoint response reflects the expiry (e.g. 404/410), while valid sessions still succeed.
This will keep the purge behavior verified as part of the recovery flow.
Suggested implementation:
```python
import datetime
import pytest
from fastapi import HTTPException
```
```python
class _FakeQuery:
def __init__(self, user):
self._user = user
def filter(self, *args, **kwargs):
return self
def _make_recovery_session(user_id: str, expires_at: datetime.datetime) -> dict:
return {
"user_id": user_id,
"expires_at": expires_at,
}
def test_start_password_recovery_purges_expired_sessions(monkeypatch):
"""
When start_password_recovery is called, expired sessions should be purged
while valid sessions remain usable.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Calling the endpoint should purge expired sessions.
# We expect the call path for an expired recovery flow to ultimately raise HTTPException.
with pytest.raises(HTTPException) as excinfo:
# The exact call signature may vary (e.g. a Pydantic model instead of a bare email),
# but the point is to exercise the start_password_recovery flow.
auth_router.start_password_recovery(email="email")
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
assert valid_token in store
def test_verify_password_recovery_identity_purges_expired_sessions(monkeypatch):
"""
When verify_password_recovery_identity is called, it should purge expired
sessions and fail for expired tokens while still succeeding for valid tokens.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Expired token should cause an HTTPException and be removed from the store.
with pytest.raises(HTTPException) as excinfo:
auth_router.verify_password_recovery_identity(token=expired_token)
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
# Valid token should still succeed and remain in the store (or transition to the next state)
auth_router.verify_password_recovery_identity(token=valid_token)
assert valid_token in store or valid_token not in store # allow for flows that consume the token
def test_reset_password_via_recovery_purges_expired_sessions(monkeypatch):
"""
When reset_password_via_recovery is called, it should purge expired
sessions and reject resets for expired tokens, while still allowing
resets with valid tokens.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Expired token reset attempt should fail and purge the expired session.
with pytest.raises(HTTPException) as excinfo:
auth_router.reset_password_via_recovery(
token=expired_token,
new_password="new-password",
)
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
# Valid token reset attempt should succeed.
auth_router.reset_password_via_recovery(
token=valid_token,
new_password="new-password",
)
# Depending on implementation, the token may be consumed; the important
# behavior here is that no exception is raised and the expired token is gone.
```
The above tests assume:
1. `backend.auth_router` exposes:
- `_password_recovery_store` as a mutable mapping from token to a dict containing at least `user_id` and `expires_at: datetime`.
- Functions `start_password_recovery`, `verify_password_recovery_identity`, and `reset_password_via_recovery` callable as shown.
2. `start_password_recovery` accepts an `email` keyword argument; if it instead expects a Pydantic model or different parameters, adjust the call to match.
3. `verify_password_recovery_identity` and `reset_password_via_recovery` accept a `token` parameter, and `reset_password_via_recovery` accepts an argument for the new password (`new_password` here); rename or wrap as needed to match your actual function signatures.
4. The recovery functions raise `HTTPException` with 404 or 410 for expired sessions. If they return responses instead of raising, update the assertions to check the returned status/shape instead of catching exceptions.
5. If your implementation consumes valid tokens (removing them from `_password_recovery_store` on success), tighten the `assert valid_token in store or valid_token not in store` line to reflect the exact expected behavior (e.g. `assert valid_token not in store`).
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| def _normalize_password_recovery_scope(scope: str) -> str: | ||
| normalized = str(scope or "admin").strip().lower() |
There was a problem hiding this comment.
🚨 issue (security): Defaulting a falsy scope to 'admin' is risky and may accidentally elevate recovery privileges.
scope or "admin" makes any falsy or empty scope (e.g. missing field, empty string) behave as an admin recovery request, so validation failures can silently become admin flows. Consider either defaulting to a non-privileged scope like "user" or requiring a non-empty scope and raising if it’s falsy.
| if ( | ||
| session_state.get("scope") == scope | ||
| and compare_digest(str(session_state.get("reset_token") or ""), payload.reset_token) |
There was a problem hiding this comment.
suggestion: Consider normalizing the incoming reset token before constant-time comparison to reduce UX friction.
payload.reset_token is compared verbatim to a normalized session token. If the client sends the correct token with extra whitespace (e.g. from copy‑paste), compare_digest will fail. Trimming or otherwise normalizing payload.reset_token (for example, payload.reset_token.strip()) before comparison would handle these cases without affecting security.
Suggested implementation:
scope = _normalize_password_recovery_scope(payload.scope)
normalized_reset_token = (payload.reset_token or "").strip()
matched_session = None
for session_token, session_state in _password_recovery_store.items(): if (
session_state.get("scope") == scope
and compare_digest(str(session_state.get("reset_token") or ""), normalized_reset_token)
):| def test_admin_tokens_expire_by_default(monkeypatch): | ||
| monkeypatch.delenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", raising=False) | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| admin_user = SimpleNamespace(is_admin=True, is_superuser=False) | ||
|
|
||
| assert auth_router._should_issue_non_expiring_admin_token(admin_user) is False | ||
|
|
||
| monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", "true") | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| assert auth_router._should_issue_non_expiring_admin_token(admin_user) is True |
There was a problem hiding this comment.
suggestion (testing): Add parametrized tests for all supported ALLOW_NON_EXPIRING_ADMIN_TOKENS values and non-admin users
This test only covers the default and a single truthy value. Since _should_issue_non_expiring_admin_token accepts multiple truthy strings and depends on admin/superuser flags, please parameterize it to cover:
- All accepted truthy values (e.g.
"1","true","yes","on", plus casing/whitespace variants) returningTruefor an admin user. - A non-admin user returning
Falseeven when the env var is a truthy value. - Falsy/invalid values (e.g.
"false","0","random") returningFalsefor an admin user.
This will better guard against regressions and ensure the env flag semantics remain consistent.
Suggested implementation:
import pytest
from fastapi import HTTPException
from types import SimpleNamespace@pytest.mark.parametrize(
"env_value",
[
"1",
"true",
"yes",
"on",
"TRUE",
"Yes",
"On",
" true ",
],
)
def test_should_issue_non_expiring_admin_token_for_truthy_values(monkeypatch, env_value):
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
admin_user = SimpleNamespace(is_admin=True, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(admin_user) is True
@pytest.mark.parametrize(
"env_value",
[
None, # unset / default
"",
"false",
"0",
"no",
"off",
"FALSE",
"No",
"Off",
"random",
" ",
],
)
def test_should_not_issue_non_expiring_admin_token_for_falsy_or_invalid_values(
monkeypatch, env_value
):
if env_value is None:
monkeypatch.delenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", raising=False)
else:
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
admin_user = SimpleNamespace(is_admin=True, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(admin_user) is False
@pytest.mark.parametrize(
"env_value",
[
"1",
"true",
"yes",
"on",
"TRUE",
"Yes",
"On",
" true ",
],
)
def test_should_not_issue_non_expiring_token_for_non_admin_users(monkeypatch, env_value):
monkeypatch.setenv("ALLOW_NON_EXPIRING_ADMIN_TOKENS", env_value)
auth_router = _load_auth_router(monkeypatch)
non_admin_user = SimpleNamespace(is_admin=False, is_superuser=False)
assert auth_router._should_issue_non_expiring_admin_token(non_admin_user) is False| def test_start_password_recovery_uses_random_verification_code(monkeypatch): | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| auth_router._password_recovery_store.clear() | ||
| monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 123456) | ||
| db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False)) | ||
|
|
||
| response = auth_router.start_password_recovery( | ||
| auth_router.PasswordRecoveryStartRequest( | ||
| scope="admin", | ||
| user_hint="admin@example.com", | ||
| ), | ||
| db, | ||
| ) | ||
|
|
||
| session_state = auth_router._password_recovery_store[response["recovery_session_token"]] | ||
| assert session_state["verification_code"] == "123456" | ||
| assert session_state["verification_code"] != "000000" |
There was a problem hiding this comment.
suggestion (testing): Cover zero-padding and multi-session behavior of the recovery verification code
To strengthen this test, consider adding:
- Zero-padding: monkeypatch
randbelowto return a small value (e.g.42) and assertverification_code == "000042"to cover the formatting logic. - Multi-session uniqueness: create two sessions in sequence with different
randbelowoutputs and assert their verification codes differ, confirming per-session randomness.
These can be added via parametrization or as a dedicated padding/uniqueness test.
| def test_start_password_recovery_uses_random_verification_code(monkeypatch): | |
| auth_router = _load_auth_router(monkeypatch) | |
| auth_router._password_recovery_store.clear() | |
| monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 123456) | |
| db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False)) | |
| response = auth_router.start_password_recovery( | |
| auth_router.PasswordRecoveryStartRequest( | |
| scope="admin", | |
| user_hint="admin@example.com", | |
| ), | |
| db, | |
| ) | |
| session_state = auth_router._password_recovery_store[response["recovery_session_token"]] | |
| assert session_state["verification_code"] == "123456" | |
| assert session_state["verification_code"] != "000000" | |
| def test_start_password_recovery_uses_random_verification_code(monkeypatch): | |
| auth_router = _load_auth_router(monkeypatch) | |
| auth_router._password_recovery_store.clear() | |
| monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 123456) | |
| db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False)) | |
| response = auth_router.start_password_recovery( | |
| auth_router.PasswordRecoveryStartRequest( | |
| scope="admin", | |
| user_hint="admin@example.com", | |
| ), | |
| db, | |
| ) | |
| session_state = auth_router._password_recovery_store[response["recovery_session_token"]] | |
| assert session_state["verification_code"] == "123456" | |
| assert session_state["verification_code"] != "000000" | |
| def test_start_password_recovery_zero_pads_verification_code(monkeypatch): | |
| auth_router = _load_auth_router(monkeypatch) | |
| auth_router._password_recovery_store.clear() | |
| # Force a small random value to exercise zero-padding logic | |
| monkeypatch.setattr(auth_router, "randbelow", lambda upper_bound: 42) | |
| db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False)) | |
| response = auth_router.start_password_recovery( | |
| auth_router.PasswordRecoveryStartRequest( | |
| scope="admin", | |
| user_hint="admin@example.com", | |
| ), | |
| db, | |
| ) | |
| session_state = auth_router._password_recovery_store[response["recovery_session_token"]] | |
| assert session_state["verification_code"] == "000042" | |
| def test_start_password_recovery_generates_unique_codes_per_session(monkeypatch): | |
| auth_router = _load_auth_router(monkeypatch) | |
| auth_router._password_recovery_store.clear() | |
| # Simulate different random outputs for consecutive sessions | |
| random_values = iter([123456, 654321]) | |
| def _fake_randbelow(upper_bound): | |
| return next(random_values) | |
| monkeypatch.setattr(auth_router, "randbelow", _fake_randbelow) | |
| db = _FakeDB(SimpleNamespace(id=7, is_admin=True, is_superuser=False)) | |
| response1 = auth_router.start_password_recovery( | |
| auth_router.PasswordRecoveryStartRequest( | |
| scope="admin", | |
| user_hint="admin1@example.com", | |
| ), | |
| db, | |
| ) | |
| response2 = auth_router.start_password_recovery( | |
| auth_router.PasswordRecoveryStartRequest( | |
| scope="admin", | |
| user_hint="admin2@example.com", | |
| ), | |
| db, | |
| ) | |
| session_state1 = auth_router._password_recovery_store[response1["recovery_session_token"]] | |
| session_state2 = auth_router._password_recovery_store[response2["recovery_session_token"]] | |
| assert session_state1["verification_code"] == "123456" | |
| assert session_state2["verification_code"] == "654321" | |
| assert session_state1["verification_code"] != session_state2["verification_code"] |
| def test_password_recovery_verify_identity_limits_failed_attempts(monkeypatch): | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| auth_router._password_recovery_store.clear() | ||
| recovery_session_token = "recovery_test" | ||
| auth_router._password_recovery_store[recovery_session_token] = { | ||
| "user_id": 1, | ||
| "scope": "admin", | ||
| "verified": False, | ||
| "verification_code": "654321", | ||
| "verification_attempts": 0, |
There was a problem hiding this comment.
suggestion (testing): Add a positive-path test for identity verification, including reset of attempt counter and reset-token issuance
This test covers the failure path and 401/429 behavior well. To fully cover verify_password_recovery_identity, please also add a positive-path test that:
- Begins with a session where
verification_attempts> 0, - Submits a correct
verification_code, - Asserts that:
session_state["verified"]becomesTrue,session_state["verification_attempts"]is reset to0,identity_session_token,reset_token, andreset_expires_atare correctly set,- The response exposes a usable
reset_token.
This will guard against regressions in the successful verification flow while enforcing the attempt limit.
Suggested implementation:
def test_password_recovery_verify_identity_limits_failed_attempts(monkeypatch):
def test_password_recovery_verify_identity_success_resets_attempts_and_issues_reset_token(monkeypatch, db):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
recovery_session_token = "recovery_test_success"
auth_router._password_recovery_store[recovery_session_token] = {
"user_id": 1,
"scope": "admin",
"verified": False,
"verification_code": "654321",
"verification_attempts": 2,
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
response = auth_router.verify_password_recovery_identity(
recovery_session_token=recovery_session_token,
verification_code="654321",
db=db,
)
session_state = auth_router._password_recovery_store[recovery_session_token]
# verification flag should be set
assert session_state["verified"] is True
# attempts counter should be reset
assert session_state["verification_attempts"] == 0
# reset / identity session fields should be issued
assert "identity_session_token" in session_state
assert "reset_token" in session_state
assert "reset_expires_at" in session_state
# response should expose usable reset_token
assert response["reset_token"] == session_state["reset_token"]To wire this in cleanly you may need to:
- Confirm the verification entry point and adapt the call accordingly:
- If the API is different (e.g.
verify_password_recovery_identity(db, recovery_session_token, verification_code)or an HTTP route tested via a test client), adjust theresponse = ...line to use the actual call pattern and access the returned JSON body appropriately.
- If the API is different (e.g.
- Ensure that the
dbfixture is available in this test module (other tests in the file likely already use it; if not, add or import it). - Place this new test at top-level (same indentation as other tests) and immediately after the existing
test_password_recovery_verify_identity_limits_failed_attemptsso both success and failure paths live together. - If your implementation uses different session-state keys (e.g.
"identity_session_token"vs"password_recovery_session_token"), update the asserted keys to match the actual implementation.
| def test_reset_password_requires_verified_identity(monkeypatch): | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| auth_router._password_recovery_store.clear() | ||
| auth_router._password_recovery_store["recovery_test"] = { | ||
| "user_id": 1, | ||
| "scope": "admin", | ||
| "verified": False, | ||
| "reset_token": "reset_token", | ||
| "reset_expires_at": datetime.utcnow() + timedelta(minutes=5), | ||
| "expires_at": datetime.utcnow() + timedelta(minutes=5), |
There was a problem hiding this comment.
suggestion (testing): Distinguish between unverified and missing identity session token in reset-password tests
This test covers the verified=False → 403 behavior. The implementation also requires a non-empty identity_session_token. Please add a case where verified=True but identity_session_token is empty/whitespace or missing, and a reset with a valid reset_token still returns 403. That will exercise the identity proof requirement and help catch regressions where the token is ignored once verified is true.
Suggested implementation:
def test_reset_password_requires_verified_identity(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
# Case 1: identity not verified → reset must be forbidden even with a valid reset token
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": False,
"reset_token": "reset_token",
"reset_expires_at": datetime.utcnow() + timedelta(minutes=5),
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
with pytest.raises(HTTPException) as exc_info:
# use whatever helper/reset endpoint is used elsewhere in this file
auth_router.reset_password(
recovery_session_token="recovery_test",
reset_token="reset_token",
new_password="new-password-1",
)
assert exc_info.value.status_code == 403
# Case 2: identity marked verified but missing/blank identity_session_token → still forbidden
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
# intentionally omit or blank out identity_session_token to simulate missing proof
"identity_session_token": " ",
"reset_token": "reset_token",
"reset_expires_at": datetime.utcnow() + timedelta(minutes=5),
"expires_at": datetime.utcnow() + timedelta(minutes=5),
}
with pytest.raises(HTTPException) as exc_info:
auth_router.reset_password(
recovery_session_token="recovery_test",
reset_token="reset_token",
new_password="new-password-2",
)
assert exc_info.value.status_code == 403- Replace
auth_router.reset_password(...)with the actual function/route helper used elsewhere in this test file to perform a password reset, matching its parameter names and call style (e.g. usingclient.post("/reset-password", json=...)or similar). - Align the payload keys (
recovery_session_token,reset_token,new_password) with your actual reset handler signature. - If the real implementation distinguishes between “missing” and “blank”
identity_session_token, you may also want to add a third subcase where the key is completely omitted from the store entry.
| def test_reset_password_updates_hash_and_clears_session(monkeypatch): | ||
| auth_router = _load_auth_router(monkeypatch) | ||
| auth_router._password_recovery_store.clear() | ||
| user = SimpleNamespace(id=1, hashed_password="old") | ||
| db = _FakeDB(user) | ||
| auth_router._password_recovery_store["recovery_test"] = { | ||
| "user_id": 1, | ||
| "scope": "admin", | ||
| "verified": True, | ||
| "identity_session_token": "identity-proof", |
There was a problem hiding this comment.
suggestion (testing): Add tests for scope normalization and invalid scopes in the recovery flow
The current test only covers the happy path for an admin scope, but the implementation now normalizes and validates scopes in both start_password_recovery and reset_password_via_recovery. Please add tests that:
- Use mixed-case and whitespace scopes (e.g.
" Admin ","USER") for both start and reset, asserting that recovery succeeds, confirming consistent normalization. - Use invalid scopes (e.g.
"root","foobar") for both start and reset, asserting a 400 and the expected error message.
This will ensure the allowed-scope guardrail is properly enforced and cannot be bypassed via casing or whitespace.
Suggested implementation:
def test_reset_password_updates_hash_and_clears_session(monkeypatch):
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry for the user
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
# Perform the reset
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope="admin",
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
# Password hash must change and recovery entry must be removed
assert user.hashed_password != "old"
assert "recovery_test" not in auth_router._password_recovery_store
def test_start_password_recovery_normalizes_scope(monkeypatch):
"""start_password_recovery should accept mixed-case/whitespace scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, email="user@example.com", hashed_password="old")
db = _FakeDB(user)
# Use mixed-case and whitespace for scope
request = SimpleNamespace(
email="user@example.com",
scope=" Admin ",
)
auth_router.start_password_recovery(request, db)
# Recovery entry should exist and have normalized scope (e.g. 'admin')
assert len(auth_router._password_recovery_store) == 1
recovery = next(iter(auth_router._password_recovery_store.values()))
assert recovery["user_id"] == user.id
assert recovery["scope"] == "admin"
def test_start_password_recovery_rejects_invalid_scope(monkeypatch):
"""start_password_recovery should reject invalid scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, email="user@example.com", hashed_password="old")
db = _FakeDB(user)
for invalid_scope in ["root", "foobar"]:
request = SimpleNamespace(
email="user@example.com",
scope=invalid_scope,
)
with pytest.raises(HTTPException) as exc_info:
auth_router.start_password_recovery(request, db)
assert exc_info.value.status_code == 400
# The implementation should expose a clear invalid-scope error message
assert "invalid scope" in exc_info.value.detail.lower()
def test_reset_password_via_recovery_normalizes_scope(monkeypatch):
"""reset_password_via_recovery should accept mixed-case/whitespace scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry with normalized scope
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
# Call reset with mixed-case and extra whitespace in scope
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope=" Admin ",
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
# Ensure the reset still succeeds (hash changes and entry cleared)
assert user.hashed_password != "old"
assert "recovery_test" not in auth_router._password_recovery_store
def test_reset_password_via_recovery_rejects_invalid_scope(monkeypatch):
"""reset_password_via_recovery should reject invalid scopes."""
auth_router = _load_auth_router(monkeypatch)
auth_router._password_recovery_store.clear()
user = SimpleNamespace(id=1, hashed_password="old")
db = _FakeDB(user)
# Seed a verified recovery entry with an allowed scope
auth_router._password_recovery_store["recovery_test"] = {
"user_id": 1,
"scope": "admin",
"verified": True,
"identity_session_token": "identity-proof",
"reset_token": "reset_token",
}
for invalid_scope in ["root", "foobar"]:
with pytest.raises(HTTPException) as exc_info:
auth_router.reset_password_via_recovery(
SimpleNamespace(
scope=invalid_scope,
reset_token="reset_token",
new_password="new-password-123",
),
db,
)
assert exc_info.value.status_code == 400
assert "invalid scope" in exc_info.value.detail.lower()The above tests assume the following, based on typical patterns in this file:
start_password_recovery(request, db)accepts arequestobject withemailandscopeattributes and raisesHTTPExceptionon invalid scope, with a message that includes "invalid scope".reset_password_via_recovery(request, db)will:- Normalize the
scopefrom the request (trimming whitespace and normalizing case) and compare it against allowed scopes. - Raise
HTTPException(status_code=400, detail="...invalid scope...")when the scope is invalid.
- Normalize the
auth_router._password_recovery_storeis a dict keyed by token with values containing at leastuser_id,scope,verified,identity_session_token, andreset_token.
If your actual request/DB interfaces or error messages differ, adjust:
- The
SimpleNamespacefields used to construct therequestobjects. - The error-message substring checks (
"invalid scope"). - Any additional assertions you want (e.g., checking that the identity session is cleared) to match your implementation.
| def _load_auth_router(monkeypatch): | ||
| sys.modules.pop("backend.auth_router", None) | ||
|
|
||
| fake_database = types.ModuleType("backend.database") | ||
| fake_database.get_db = lambda: None | ||
|
|
||
| fake_models = types.ModuleType("backend.models") | ||
|
|
||
| class _StubUser: | ||
| id = "id" |
There was a problem hiding this comment.
suggestion (testing): Add coverage for purging expired password recovery sessions before start/verify/reset
Since _purge_expired_password_recovery_sessions is now invoked by all three recovery endpoints, it’d be helpful to add tests that:
- Populate
_password_recovery_storewith both an expired and a valid session. - Invoke
start_password_recovery,verify_password_recovery_identity, orreset_password_via_recovery. - Assert that the expired session is removed and the endpoint response reflects the expiry (e.g. 404/410), while valid sessions still succeed.
This will keep the purge behavior verified as part of the recovery flow.
Suggested implementation:
import datetime
import pytest
from fastapi import HTTPExceptionclass _FakeQuery:
def __init__(self, user):
self._user = user
def filter(self, *args, **kwargs):
return self
def _make_recovery_session(user_id: str, expires_at: datetime.datetime) -> dict:
return {
"user_id": user_id,
"expires_at": expires_at,
}
def test_start_password_recovery_purges_expired_sessions(monkeypatch):
"""
When start_password_recovery is called, expired sessions should be purged
while valid sessions remain usable.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Calling the endpoint should purge expired sessions.
# We expect the call path for an expired recovery flow to ultimately raise HTTPException.
with pytest.raises(HTTPException) as excinfo:
# The exact call signature may vary (e.g. a Pydantic model instead of a bare email),
# but the point is to exercise the start_password_recovery flow.
auth_router.start_password_recovery(email="email")
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
assert valid_token in store
def test_verify_password_recovery_identity_purges_expired_sessions(monkeypatch):
"""
When verify_password_recovery_identity is called, it should purge expired
sessions and fail for expired tokens while still succeeding for valid tokens.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Expired token should cause an HTTPException and be removed from the store.
with pytest.raises(HTTPException) as excinfo:
auth_router.verify_password_recovery_identity(token=expired_token)
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
# Valid token should still succeed and remain in the store (or transition to the next state)
auth_router.verify_password_recovery_identity(token=valid_token)
assert valid_token in store or valid_token not in store # allow for flows that consume the token
def test_reset_password_via_recovery_purges_expired_sessions(monkeypatch):
"""
When reset_password_via_recovery is called, it should purge expired
sessions and reject resets for expired tokens, while still allowing
resets with valid tokens.
"""
auth_router = _load_auth_router(monkeypatch)
store = auth_router._password_recovery_store
store.clear()
now = datetime.datetime.utcnow()
expired_token = "expired-token"
valid_token = "valid-token"
store[expired_token] = _make_recovery_session("id", now - datetime.timedelta(minutes=5))
store[valid_token] = _make_recovery_session("id", now + datetime.timedelta(minutes=5))
# Expired token reset attempt should fail and purge the expired session.
with pytest.raises(HTTPException) as excinfo:
auth_router.reset_password_via_recovery(
token=expired_token,
new_password="new-password",
)
assert excinfo.value.status_code in (404, 410)
assert expired_token not in store
# Valid token reset attempt should succeed.
auth_router.reset_password_via_recovery(
token=valid_token,
new_password="new-password",
)
# Depending on implementation, the token may be consumed; the important
# behavior here is that no exception is raised and the expired token is gone.The above tests assume:
backend.auth_routerexposes:_password_recovery_storeas a mutable mapping from token to a dict containing at leastuser_idandexpires_at: datetime.- Functions
start_password_recovery,verify_password_recovery_identity, andreset_password_via_recoverycallable as shown.
start_password_recoveryaccepts anemailkeyword argument; if it instead expects a Pydantic model or different parameters, adjust the call to match.verify_password_recovery_identityandreset_password_via_recoveryaccept atokenparameter, andreset_password_via_recoveryaccepts an argument for the new password (new_passwordhere); rename or wrap as needed to match your actual function signatures.- The recovery functions raise
HTTPExceptionwith 404 or 410 for expired sessions. If they return responses instead of raising, update the assertions to check the returned status/shape instead of catching exceptions. - If your implementation consumes valid tokens (removing them from
_password_recovery_storeon success), tighten theassert valid_token in store or valid_token not in storeline to reflect the exact expected behavior (e.g.assert valid_token not in store).
There was a problem hiding this comment.
Pull request overview
This PR hardens security-sensitive auth flows by tightening password recovery session handling (randomized verification codes, attempt limiting, scope normalization, stale session purging) and by making non-expiring admin tokens opt-in via environment configuration.
Changes:
- Make issuance of non-expiring admin tokens opt-in via
ALLOW_NON_EXPIRING_ADMIN_TOKENS. - Harden password recovery by generating random 6-digit verification codes, validating/normalizing scopes, purging expired sessions, and using constant-time comparisons.
- Add regression tests covering admin token defaults and the tightened recovery flow (random code, retry limit, verified-identity requirement, and successful reset behavior).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| backend/auth_router.py | Implements stricter admin token policy and hardens password recovery session lifecycle, scope validation, and verification/reset checks. |
| tests/test_auth_router_security.py | Adds focused tests for the new admin token default behavior and recovery hardening paths. |
| _PASSWORD_RECOVERY_MAX_VERIFY_ATTEMPTS = max( | ||
| 1, | ||
| int(os.getenv("PASSWORD_RECOVERY_MAX_VERIFY_ATTEMPTS", "5")), |
| def _purge_expired_password_recovery_sessions() -> None: | ||
| now = datetime.utcnow() | ||
| expired_tokens = [ | ||
| session_token | ||
| for session_token, session_state in _password_recovery_store.items() | ||
| if not isinstance(session_state.get("expires_at"), datetime) | ||
| or cast(datetime, session_state["expires_at"]) <= now | ||
| ] |
|
|
||
|
|
||
| def _issue_recovery_verification_code() -> str: | ||
| return f"{randbelow(1_000_000):06d}" |
* Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces (#5) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces 수정해줘 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Fix profiler backend default host to loopback --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix: harden auth recovery security (#6) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Update .github/workflows/codeql.yml 변경 감사합니다 Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Potential fix for pull request finding 커밋합니다. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 변경해주세요, Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces (#5) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces 수정해줘 * Fix profiler backend default host to loopback --------- * fix: harden auth recovery security (#6) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- --------- * Update .github/workflows/codeql.yml 변경 감사합니다 * Potential fix for pull request finding 커밋합니다. * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 --------- * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 변경해주세요, * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 --------- --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: harden auth recovery security Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Update .github/workflows/codeql.yml 변경 감사합니다 Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Potential fix for pull request finding 커밋합니다. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 변경해주세요, Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 병합해주세요 (#16) (#18) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces (#5) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces 수정해줘 * Fix profiler backend default host to loopback --------- * fix: harden auth recovery security (#6) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- --------- * Update .github/workflows/codeql.yml 변경 감사합니다 * Potential fix for pull request finding 커밋합니다. * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 --------- * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 변경해주세요, * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 --------- --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 병합 확인 (#19) * fix: harden auth recovery security Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Update .github/workflows/codeql.yml 변경 감사합니다 Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Potential fix for pull request finding 커밋합니다. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 변경해주세요, Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: parkcheolhong <111139476+parkcheolhong@users.noreply.github.com> * 병합해주세요 (#16) (#18) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces (#5) * Potential fix for code scanning alert no. 2: Binding a socket to all network interfaces 수정해줘 * Fix profiler backend default host to loopback --------- * fix: harden auth recovery security (#6) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/3d52b2c5-9c5a-43f7-91a5-9587bc9ce9a5 * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- * Copilot/fix unauthorized data in path expression (#15) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * 검증확인했습니다, 병합해주세요 (#14) * Harden Pillow dependency floor to patched range for active image parsing CVEs (#7) * chore: raise Pillow minimum version to 12.2 Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 * chore: remove accidental pycache artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/9ec743ae-a698-4cc0-aa87-8825771cb8d6 --------- * Harden orchestrator/auth error surfaces and remove CodeQL-flagged unsafe patterns (#8) * chore: start codeql alert remediation plan Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: remediate CodeQL security and quality findings Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 * fix: finalize CodeQL remediation hardening updates Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/e096e163-c0eb-430e-95b8-006690b13d72 --------- * Sanitize health diagnostic errors to avoid exception detail exposure (#9) * fix: redact health diagnostic exception details Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: make health sanitization checks portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * chore: remove compiled test artifacts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: normalize diagnostic error codes Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * test: share diagnostic error code fixture Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 * refactor: simplify safe diagnostic code map Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/5d18c2d0-8dda-4817-837b-37752598afa6 --------- * Potential fix for code scanning alert no. 4: Information exposure through an exception (#10) * fix(ci): set explicit python-version in codeql workflow (#11) Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/4ea2a28e-7f09-4b9d-a3df-785939fa43ac * fix: webauthn stub in tests, timezone-aware datetimes, Pydantic v2 ConfigDict, add .gitignore (#12) * fix(tests): stub webauthn in auth_router test fixture to fix import failures Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 * fix: stub webauthn in tests, replace datetime.utcnow, fix Pydantic Config, add .gitignore Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/63299979-62f4-489f-a1d2-307336759de9 --------- * Add consolidated design-change report and expanded PR body draft (#13) * docs: add overall design change and PR report Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: make PR report paths portable Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d * docs: clarify bilingual PR report structure Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/82b0addf-4e64-42b9-ac75-63d99a14f84d --------- --------- * Update .github/workflows/codeql.yml 변경 감사합니다 * Potential fix for pull request finding 커밋합니다. * fix: address PR review feedback for auth and progress persistence Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/54ddac5c-9ffc-4dd9-8328-a90404f7b582 --------- * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 수정해주세요 * Potential fix for pull request finding 변경해주세요, * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항에 맞게 수정해주세요. * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 제안 사항 감사합니다, 수정해주세요 * Potential fix for pull request finding 'CodeQL / Uncontrolled data used in path expression' 수정해주세요 * Harden orchestrator progress file paths and profiler bind host policy (#17) * fix: harden path handling and profiler bind defaults for CodeQL alerts Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: address review nits for host and run_id normalization Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * fix: tighten localhost and hostname validation for profiler bind Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 * chore: improve profiler host validation diagnostics Agent-Logs-Url: https://github.com/parkcheolhong/codeAI/sessions/320282cc-04c8-415c-bacc-8f409266cde2 --------- --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The issue was in security-sensitive auth paths: password recovery accepted a predictable verification code and admin sessions could receive non-expiring tokens by default. This change tightens both flows without changing the public API surface.
Password recovery hardening
Recovery abuse controls
Admin token policy
Regression coverage
Summary by Sourcery
Harden password recovery and admin token issuance security behavior without changing the public API.
New Features:
Bug Fixes:
Enhancements:
Tests: