fix codeql issue

This commit is contained in:
Wendong-Fan 2026-02-04 07:17:45 +08:00
parent bf6b2aad79
commit abc157e048
2 changed files with 76 additions and 43 deletions

View file

@ -160,27 +160,35 @@ def env(key: str, default=None):
First checks thread-local user-specific environment,
then falls back to global environment.
Security: Uses sanitized path stored in _thread_local.env_path
which has already been validated by set_user_env_path.
Security: Re-validates path at point of use to ensure integrity.
"""
# If we have a user-specific environment path, try to reload it
# to get latest values.
# Note: _thread_local.env_path is already sanitized by set_user_env_path
if hasattr(_thread_local, "env_path") and os.path.exists(
_thread_local.env_path
):
# Temporarily load user-specific env to get the latest value
from dotenv import dotenv_values
if hasattr(_thread_local, "env_path"):
# Re-validate path at point of use for security
stored_path = _thread_local.env_path
validated_path = sanitize_env_path(stored_path)
user_env_values = dotenv_values(_thread_local.env_path)
if key in user_env_values:
value = user_env_values[key] or default
logger.debug(
f"Environment variable retrieved from user-specific "
f"config: key={key}, env_path={_thread_local.env_path}, "
f"has_value={value is not None}"
if validated_path and os.path.exists(validated_path):
# Temporarily load user-specific env to get the latest value
from dotenv import dotenv_values
user_env_values = dotenv_values(validated_path)
if key in user_env_values:
value = user_env_values[key] or default
logger.debug(
f"Environment variable retrieved from user-specific "
f"config: key={key}, env_path={validated_path}, "
f"has_value={value is not None}"
)
return value
elif stored_path and not validated_path:
# Path failed validation - clear it and log warning
logger.warning(
f"Security: Thread-local env_path failed re-validation, "
f"clearing: {stored_path}"
)
return value
delattr(_thread_local, "env_path")
# Fall back to global environment
value = os.getenv(key, default)

View file

@ -101,9 +101,12 @@ async def install_tool(tool: str):
" the tool.",
}
except Exception as e:
logger.error(f"Failed to install {tool} toolkit: {e}")
logger.error(
f"Failed to install {tool} toolkit: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to install {tool}: {str(e)}"
status_code=500,
detail=f"Failed to install {tool}. Check server logs for details.",
)
elif tool == "google_calendar":
try:
@ -151,9 +154,12 @@ async def install_tool(tool: str):
"requires_auth": True,
}
except Exception as e:
logger.error(f"Failed to install {tool} toolkit: {e}")
logger.error(
f"Failed to install {tool} toolkit: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to install {tool}: {str(e)}"
status_code=500,
detail=f"Failed to install {tool}. Check server logs for details.",
)
elif tool == "linkedin":
try:
@ -240,9 +246,12 @@ async def install_tool(tool: str):
"oauth_url": "/api/oauth/linkedin/login",
}
except Exception as e:
logger.error(f"Failed to install {tool} toolkit: {e}")
logger.error(
f"Failed to install {tool} toolkit: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to install {tool}: {str(e)}"
status_code=500,
detail=f"Failed to install {tool}. Check server logs for details.",
)
else:
raise HTTPException(
@ -421,9 +430,10 @@ async def uninstall_tool(tool: str):
"deleted_files": deleted_files,
}
except Exception as e:
logger.error(f"Failed to uninstall {tool}: {e}")
logger.error(f"Failed to uninstall {tool}: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to uninstall {tool}: {str(e)}"
status_code=500,
detail=f"Failed to uninstall {tool}. Check server logs for details.",
)
elif tool == "google_calendar":
@ -479,9 +489,10 @@ async def uninstall_tool(tool: str):
" authentication tokens",
}
except Exception as e:
logger.error(f"Failed to uninstall {tool}: {e}")
logger.error(f"Failed to uninstall {tool}: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to uninstall {tool}: {str(e)}"
status_code=500,
detail=f"Failed to uninstall {tool}. Check server logs for details.",
)
elif tool == "linkedin":
try:
@ -501,9 +512,10 @@ async def uninstall_tool(tool: str):
"message": f"Uninstalled {tool} (no tokens found to clean up)",
}
except Exception as e:
logger.error(f"Failed to uninstall {tool}: {e}")
logger.error(f"Failed to uninstall {tool}: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to uninstall {tool}: {str(e)}"
status_code=500,
detail=f"Failed to uninstall {tool}. Check server logs for details.",
)
else:
raise HTTPException(
@ -557,7 +569,7 @@ async def save_linkedin_token(token_request: LinkedInTokenRequest):
return {
"success": True,
"message": "LinkedIn token saved (verification pending)",
"warning": str(e),
"warning": "Token verification failed. Check server logs.",
}
else:
raise HTTPException(
@ -566,9 +578,10 @@ async def save_linkedin_token(token_request: LinkedInTokenRequest):
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to save LinkedIn token: {e}")
logger.error(f"Failed to save LinkedIn token: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to save token: {str(e)}"
status_code=500,
detail="Failed to save token. Check server logs for details.",
)
@ -627,9 +640,10 @@ async def get_linkedin_status():
return result
except Exception as e:
logger.error(f"Failed to get LinkedIn status: {e}")
logger.error(f"Failed to get LinkedIn status: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to get status: {str(e)}"
status_code=500,
detail="Failed to get status. Check server logs for details.",
)
@ -768,9 +782,12 @@ async def open_browser_login():
}
except Exception as e:
logger.error(f"Failed to open Electron browser for login: {e}")
logger.error(
f"Failed to open Electron browser for login: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to open browser: {str(e)}"
status_code=500,
detail="Failed to open browser. Check server logs for details.",
)
@ -863,9 +880,10 @@ async def list_cookie_domains(search: str = None):
}
except Exception as e:
logger.error(f"Failed to list cookie domains: {e}")
logger.error(f"Failed to list cookie domains: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to list cookies: {str(e)}"
status_code=500,
detail="Failed to list cookies. Check server logs for details.",
)
@ -907,9 +925,12 @@ async def get_domain_cookies(domain: str):
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to get cookies for domain {domain}: {e}")
logger.error(
f"Failed to get cookies for domain {domain}: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to get cookies: {str(e)}"
status_code=500,
detail="Failed to get cookies. Check server logs for details.",
)
@ -955,9 +976,12 @@ async def delete_domain_cookies(domain: str):
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to delete cookies for domain {domain}: {e}")
logger.error(
f"Failed to delete cookies for domain {domain}: {e}", exc_info=True
)
raise HTTPException(
status_code=500, detail=f"Failed to delete cookies: {str(e)}"
status_code=500,
detail="Failed to delete cookies. Check server logs for details.",
)
@ -994,7 +1018,8 @@ async def delete_all_cookies():
except HTTPException:
raise
except Exception as e:
logger.error(f"Failed to delete all cookies: {e}")
logger.error(f"Failed to delete all cookies: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to delete cookies: {str(e)}"
status_code=500,
detail="Failed to delete cookies. Check server logs for details.",
)