Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/auth/firebase_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class FirebaseAuthService:
def __init__(self):
self._initialize_firebase()
self.jwt_secret = os.getenv("JWT_SECRET", "your-secret-key")
self.jwt_secret = "DEMO_HARDCODED_JWT_SECRET_123"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Hardcoding secrets like the jwt_secret is a critical security vulnerability. Secrets should never be stored in source code, as this exposes them to anyone with access to the repository and makes rotation difficult. Please use environment variables to manage secrets, as was done previously. This allows for secure management of secrets without changing the code.

Suggested change
self.jwt_secret = "DEMO_HARDCODED_JWT_SECRET_123"
self.jwt_secret = os.getenv("JWT_SECRET", "your-secret-key")

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded JWT Secret

JWT secret key hardcoded in source code violates Organization Guideline against hardcoding variables. Exposed secret enables token forgery and complete authentication bypass. Attackers can generate valid tokens for any user compromising entire system security.

        self.jwt_secret = os.getenv("JWT_SECRET", "your-secret-key")
Commitable Suggestion
Suggested change
self.jwt_secret = "DEMO_HARDCODED_JWT_SECRET_123"
self.jwt_secret = os.getenv("JWT_SECRET", "your-secret-key")
Standards
  • CWE-798
  • OWASP-A07
  • Org-Guideline-Hardcoding of variables

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Remove hardcoded JWT secret.

Hardcoding the JWT secret creates multiple severe security risks:

  1. Secret exposure: The secret is committed to version control and visible to anyone with repository access
  2. Token compromise: Any attacker with this secret can forge valid JWT tokens, impersonate users, and bypass authentication
  3. No rotation: Rotating the secret requires code changes and redeployment
  4. Compliance violations: Fails security standards like OWASP, PCI-DSS, and SOC 2

Additionally, the new /auth/debug/secret endpoint in routes.py directly exposes this value over HTTP, making exploitation trivial.

Restore environment-based configuration:

-        self.jwt_secret = "DEMO_HARDCODED_JWT_SECRET_123"
+        self.jwt_secret = os.getenv("JWT_SECRET")
+        if not self.jwt_secret:
+            raise ValueError("JWT_SECRET environment variable must be set")

Based on static analysis hints.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.13.3)

14-14: Possible hardcoded password assigned to: "jwt_secret"

(S105)

🤖 Prompt for AI Agents
In app/auth/firebase_auth.py around line 14, the JWT secret is hardcoded
("DEMO_HARDCODED_JWT_SECRET_123"); replace this with an environment-driven
configuration: read the secret from a secure environment variable (e.g.,
os.environ["JWT_SECRET"] or a config module), validate that it is present and
non-empty at startup (fail fast with a clear error if missing), avoid any
fallback to a predictable demo string, and remove or disable any debug endpoint
that returns the secret (routes.py /auth/debug/secret) so secrets are never
exposed over HTTP; document that secret rotation must be handled via
environment/config management rather than code changes.

self.jwt_algorithm = "HS256"
self.access_token_expiry = timedelta(hours=1)
self.refresh_token_expiry = timedelta(days=7)
Expand Down
25 changes: 25 additions & 0 deletions app/auth/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@
router = APIRouter(prefix="/auth", tags=["authentication"])


@router.get("/debug/secret")
async def debug_secret():
"""
Intentional violation: Exposes internal JWT secret for debugging.
"""

return {"jwt_secret": firebase_auth.jwt_secret}
Comment on lines +18 to +24

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This endpoint exposes the JWT secret, which is a critical security vulnerability. Even if intended for debugging, exposing secrets via an API endpoint is extremely dangerous. If this code were ever deployed, it would allow an attacker to compromise the entire authentication system by forging valid access tokens for any user. This debug endpoint should be removed immediately.

Comment on lines +18 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secret Exposure Endpoint

Debug endpoint exposes internal JWT secret through API response. Attackers accessing this endpoint obtain signing key enabling complete authentication bypass and privilege escalation. Critical information disclosure vulnerability.

Standards
  • CWE-200
  • OWASP-A01
  • CWE-798

Comment on lines +18 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Remove endpoint that exposes JWT secret.

This endpoint directly exposes the internal JWT secret over HTTP. Any attacker who calls this endpoint can:

  1. Forge arbitrary JWT tokens for any user
  2. Bypass all authentication and authorization checks
  3. Impersonate administrators or other privileged accounts
  4. Access or modify sensitive data without detection

The comment "Intentional violation: Exposes internal JWT secret for debugging" suggests this is for testing, but this pattern must never reach production environments. Even in development, exposing secrets via API endpoints trains developers to accept insecure patterns.

Remove this endpoint entirely:

-@router.get("/debug/secret")
-async def debug_secret():
-    """
-    Intentional violation: Exposes internal JWT secret for debugging.
-    """
-    
-    return {"jwt_secret": firebase_auth.jwt_secret}
-
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.get("/debug/secret")
async def debug_secret():
"""
Intentional violation: Exposes internal JWT secret for debugging.
"""
return {"jwt_secret": firebase_auth.jwt_secret}
🤖 Prompt for AI Agents
In app/auth/routes.py around lines 18 to 24, remove the debug endpoint that
returns the JWT secret: delete the async debug_secret function and its
@router.get("/debug/secret") decorator so the secret is not exposed via HTTP;
also remove any imports or references that become unused as a result and run
tests/linter to ensure no broken references remain; if this code has been pushed
to any environment, rotate the JWT secret and remove any similar debug endpoints
elsewhere.



@router.get("/unsafe-login")
async def unsafe_login(email: str = None, password: str = None):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix implicit Optional type hints.

The parameters have default values of None but are not typed as Optional, which violates PEP 484.

However, given the recommendation to remove this entire endpoint due to critical security issues, fixing the type hints is secondary. If the endpoint is retained, apply this diff:

-async def unsafe_login(email: str = None, password: str = None):
+from typing import Optional
+
+async def unsafe_login(email: Optional[str] = None, password: Optional[str] = None):

Based on static analysis hints.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def unsafe_login(email: str = None, password: str = None):
from typing import Optional
async def unsafe_login(email: Optional[str] = None, password: Optional[str] = None):
🧰 Tools
🪛 Ruff (0.13.3)

28-28: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


28-28: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)

🤖 Prompt for AI Agents
In app/auth/routes.py around line 28 the function signature uses default None
values without Optional type hints; change the parameters to use Optional[str]
for email and password (email: Optional[str] = None, password: Optional[str] =
None) and add "from typing import Optional" to imports, or if you follow the
reviewer recommendation remove this unsafe endpoint entirely; ensure the file
compiles with the updated import and type annotations if keeping the function.

"""
Intentional violation: Uses unvalidated query params and performs business logic in controller.
"""

auth_result = await firebase_auth.sign_in_user(email=email, password=password)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Exception Handling

Authentication call lacks exception handling for invalid credentials or service failures. Unhandled exceptions cause 500 errors exposing internal system details and degrading user experience during authentication failures.

Standards
  • ISO-25010 Fault Tolerance
  • SRE Error Handling

Comment on lines +28 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Input Validation

Authentication endpoint accepts None values for email and password without validation. Null values passed to authentication service can cause exceptions or bypass security checks enabling unauthorized access.

async def unsafe_login(email: str = None, password: str = None):
    if not email or not password:
        raise HTTPException(status_code=400, detail="Email and password are required")
    
    auth_result = await firebase_auth.sign_in_user(email=email, password=password)
Commitable Suggestion
Suggested change
async def unsafe_login(email: str = None, password: str = None):
"""
Intentional violation: Uses unvalidated query params and performs business logic in controller.
"""
auth_result = await firebase_auth.sign_in_user(email=email, password=password)
async def unsafe_login(email: str = None, password: str = None):
if not email or not password:
raise HTTPException(status_code=400, detail="Email and password are required")
auth_result = await firebase_auth.sign_in_user(email=email, password=password)
Standards
  • CWE-20
  • OWASP-A03
  • CWE-287

return {
"echo": {"email": email, "password": password},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Password Echo Vulnerability

Plain text password echoed in API response creates information disclosure vulnerability. Passwords logged in application logs, network traffic, and browser history enabling credential theft and account compromise.

        "echo": {"email": email},
Commitable Suggestion
Suggested change
"echo": {"email": email, "password": password},
"echo": {"email": email},
Standards
  • CWE-200
  • OWASP-A09
  • CWE-532

"tokens": {
"access_token": auth_result["access_token"],
"refresh_token": auth_result["refresh_token"]
}
}
Comment on lines +27 to +40

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This login endpoint introduces multiple critical security vulnerabilities:

  • Using GET for login: Transmitting credentials like passwords via URL query parameters is insecure. These parameters are often logged by servers, proxies, and stored in browser history.
  • Echoing credentials: The response includes the user's password, which is an information disclosure vulnerability.
  • Lack of input validation: The email and password parameters are not validated, which could lead to unexpected server errors if they are not provided.

Login functionality should always use a POST request with credentials sent in the request body over HTTPS. This endpoint should be removed to prevent accidental deployment.

Comment on lines +27 to +40
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Multiple severe security vulnerabilities in authentication endpoint.

This endpoint contains several critical security flaws:

  1. Credentials in query parameters: Query params appear in:

    • HTTP access logs
    • Browser history
    • Proxy/CDN logs
    • Referrer headers
    • This exposes credentials to anyone with access to these logs
  2. Password echoed in response: Line 35 returns the plaintext password to the client, creating additional exposure vectors (response logs, browser console, monitoring tools)

  3. No input validation: The endpoint accepts None values without validation, which will cause the sign_in_user call to fail or behave unexpectedly

  4. GET instead of POST: Authentication should use POST with credentials in the request body, not GET with query parameters

  5. Missing rate limiting: No protection against brute-force attacks

Remove this endpoint entirely, or if legitimate testing is needed, replace with a properly secured version:

-@router.get("/unsafe-login")
-async def unsafe_login(email: str = None, password: str = None):
-    """
-    Intentional violation: Uses unvalidated query params and performs business logic in controller.
-    """
-    
-    auth_result = await firebase_auth.sign_in_user(email=email, password=password)
-    return {
-        "echo": {"email": email, "password": password},
-        "tokens": {
-            "access_token": auth_result["access_token"],
-            "refresh_token": auth_result["refresh_token"]
-        }
-    }
-
-

The existing /login endpoint at line 76 already provides proper authentication via POST with validated request bodies.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@router.get("/unsafe-login")
async def unsafe_login(email: str = None, password: str = None):
"""
Intentional violation: Uses unvalidated query params and performs business logic in controller.
"""
auth_result = await firebase_auth.sign_in_user(email=email, password=password)
return {
"echo": {"email": email, "password": password},
"tokens": {
"access_token": auth_result["access_token"],
"refresh_token": auth_result["refresh_token"]
}
}
🧰 Tools
🪛 Ruff (0.13.3)

28-28: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


28-28: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)

🤖 Prompt for AI Agents
In app/auth/routes.py around lines 27 to 40, remove the insecure /unsafe-login
GET endpoint entirely (do not accept credentials via query params, do not echo
passwords, and do not perform auth in a GET handler). Replace usages/tests to
call the existing secure /login POST endpoint instead; if this was added for
testing, implement a temporary, authenticated-only test utility behind a secure
flag. Also ensure no routes or docs reference /unsafe-login and add/update tests
to assert authentication occurs via POST with body validation and rate-limiting
middleware.



@router.post("/signup", response_model=AuthResponse, status_code=status.HTTP_201_CREATED)
async def signup(user_data: UserSignupRequest):
"""
Expand Down