A comprehensive security audit was conducted on the CryptoUpdate application. Multiple critical and high-severity vulnerabilities were identified and remediated. All project dependencies have been upgraded to their latest secure versions. This document outlines the vulnerabilities found, fixes applied, dependency status, and security best practices.
Location: modules/database/swaps.py
Lines Affected: 55, 107, 120, 122
Description:
The code used f-strings to construct SQL queries, allowing potential SQL injection attacks. An attacker could manipulate the tag or entry_id parameters to execute arbitrary SQL commands.
Vulnerable Code:
# Line 107
cursor.execute(f"DELETE FROM Swaps WHERE id = {entry_id}")
# Line 120
cursor.execute(f"UPDATE Swaps SET tag = NULL WHERE id = {entry_id}")
# Line 122
cursor.execute(f"UPDATE Swaps SET tag = '{tag}' WHERE id = {entry_id}")
# Lines 55-66
tag_filter = f"WHERE tag = '{tag}'"
cursor.execute(f"SELECT ... FROM Swaps {tag_filter} ...")Fix Applied:
Implemented parameterized queries using SQLite's parameter substitution (? placeholders):
# Fixed delete
cursor.execute("DELETE FROM Swaps WHERE id = ?", (entry_id,))
# Fixed update
cursor.execute("UPDATE Swaps SET tag = ? WHERE id = ?", (tag, entry_id))
# Fixed select
cursor.execute("SELECT ... FROM Swaps WHERE tag = ? ...", (tag,))Impact: Prevents SQL injection attacks that could lead to data theft, data manipulation, or database compromise.
Location: modules/cmc.py
Lines Affected: 32, 95
Description: A sandbox API key was hardcoded in the source code for CoinMarketCap API access in debug mode. This exposed the API key in version control and could lead to unauthorized API usage.
Vulnerable Code:
headers = {"X-CMC_PRO_API_KEY": "b54bcf4d-1bca-4e8e-9a24-22ff2c3d462c"}Fix Applied: Removed the hardcoded key and now uses the configured API token from settings for both production and debug modes:
# In debug mode, use the sandbox API with the provided token
# Sandbox API keys should be configured in settings
headers = {"X-CMC_PRO_API_KEY": str(self.coinmarketcap_token)}Impact: Prevents unauthorized API usage and ensures all API keys are properly managed through configuration.
Location: modules/cmc.py
Lines Affected: 48, 77, 124
Description: Full API responses and error messages were logged at INFO and ERROR levels, potentially exposing sensitive data in log files.
Vulnerable Code:
logger.info("Get current market prices from Coinmarketcap successfully\n%s", content)
logger.error(response.text)Fix Applied:
- Moved detailed API response logging to DEBUG level
- Changed ERROR level logs to only include status codes, with details in DEBUG
logger.info("Get current market prices from Coinmarketcap successfully")
logger.debug("API response data: %s", content)
logger.error("API request failed with status code: %d", response.status_code)
logger.debug("Error response: %s", response.text)Impact: Reduces risk of sensitive data exposure in production logs while maintaining debugging capability.
Location: app.py
Lines Affected: 95-97
Description: When debug mode was enabled, the entire session state including API tokens and passwords was displayed in the Streamlit UI.
Vulnerable Code:
if st.session_state.settings["debug_flag"]:
st.write("Debug mode is ON")
st.write(st.session_state)Fix Applied: Implemented filtering to redact sensitive information before displaying:
if st.session_state.settings["debug_flag"]:
st.write("Debug mode is ON")
# Filter out sensitive data from session state before displaying
safe_session_state = {
k: v for k, v in st.session_state.items()
if k not in ["settings"] and not k.endswith("_token")
}
# Add non-sensitive settings
if "settings" in st.session_state:
safe_session_state["settings"] = {
k: ("***REDACTED***" if "token" in k.lower() or "password" in k.lower() else v)
for k, v in st.session_state.settings.items()
}
st.write(safe_session_state)Impact: Prevents accidental exposure of API keys and passwords in the UI while maintaining debugging capability.
All database operations now use parameterized queries to prevent SQL injection:
- ✅
operations.py- Already using parameterized queries - ✅
portfolios.py- Already using parameterized queries - ✅
swaps.py- Now fixed to use parameterized queries - ✅
market.py- Already using parameterized queries - ✅
tokensdb.py- Already using parameterized queries
- API keys are managed through configuration files (not hardcoded)
- Sensitive data is redacted from debug output
- API responses are logged at DEBUG level only
The application uses settings.json for configuration. Users should:
- Never commit
settings.jsonto version control - Store API keys securely
- Use environment variables or secret management systems in production
- Ensure
.gitignoreincludessettings.json
- Sensitive data only logged at DEBUG level
- Production logs (INFO/ERROR) do not contain API responses or keys
- Error messages are descriptive but don't leak sensitive information
Consider migrating from settings.json to environment variables for sensitive configuration:
import os
from dotenv import load_dotenv
load_dotenv()
COINMARKETCAP_TOKEN = os.getenv("COINMARKETCAP_TOKEN")
AI_APITOKEN = os.getenv("AI_APITOKEN")
NOTION_TOKEN = os.getenv("NOTION_TOKEN")Implement robust input validation for all user inputs:
- Validate token symbols (alphanumeric only)
- Validate numeric inputs (amounts, timestamps)
- Sanitize file uploads
- Validate portfolio names
Consider implementing rate limiting for:
- API calls to external services
- User actions (if multi-user support is added)
- Database operations
If deploying as a web service, implement security headers:
- Content-Security-Policy
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security
Regularly scan dependencies for vulnerabilities:
# Using pip-audit
pip install pip-audit
pip-audit
# Or using safety
pip install safety
safety checkFor production deployments:
- Use Streamlit secrets management (
st.secrets) - Consider HashiCorp Vault or AWS Secrets Manager
- Implement secret rotation policies
- Use encryption at rest for SQLite database
- Implement regular database backups
- Consider using encrypted database connections
- Add database integrity checks
- Implement mandatory security reviews for database operations
- Check for hardcoded secrets in pre-commit hooks
- Use static analysis tools (e.g., Bandit for Python)
- SQL Injection testing on all database operations
- Verify no secrets in logs at INFO/ERROR levels
- Test debug mode with various session states
- Verify API error responses don't leak sensitive data
- Test with invalid/malicious inputs
- Verify
.gitignoreexcludes sensitive files - Check for any remaining hardcoded secrets
Consider integrating these tools:
-
Bandit - Python security linter
pip install bandit bandit -r . -ll -
pip-audit - Dependency vulnerability scanner
pip install pip-audit pip-audit
-
Semgrep - Static analysis tool
pip install semgrep semgrep --config=auto .
- API keys are now properly protected
- Personal data (if any) should comply with GDPR/privacy laws
- Consider adding privacy policy if handling user data
- All database operations are logged
- Consider implementing audit logging for sensitive operations
- Maintain security patches and update history
For security concerns or to report vulnerabilities:
- Create a private security advisory on GitHub
- Follow responsible disclosure practices
- Do not publicly disclose vulnerabilities until patched
pip-audit scan results: 1 known vulnerability (mitigated)
All direct project dependencies have been upgraded to their latest secure versions. The only remaining vulnerability is in pip itself, which is mitigated by Python 3.12.3's PEP 706 implementation.
Vulnerability: GHSA-4xh5-x5gv-qwph / CVE-2025-8869
Description: pip's fallback tar extraction doesn't check symbolic links point to extraction directory. In the fallback extraction path for source distributions, pip used Python's tarfile module without verifying that symbolic/hard link targets resolve inside the intended extraction directory.
Affected Versions: pip <= 25.2
Fix Version: pip 25.3 (not yet released as of 2025-10-22)
Mitigation Status: ✅ MITIGATED
The project uses Python 3.12.3, which implements PEP 706 safe-extraction behavior. This provides defense-in-depth protection against this vulnerability and other tarfile extraction issues. While upgrading to pip 25.3 is recommended when available, the current configuration is considered secure.
References:
The following major dependencies have been verified as secure:
| Package | Version | Security Status | Notes |
|---|---|---|---|
| streamlit | 1.50.0 | ✅ Secure | Fixes CVE-2025-1684, CVE-2024-42474 |
| requests | 2.32.5 | ✅ Secure | Fixes .netrc credentials leak |
| urllib3 | 2.5.0 | ✅ Secure | Fixes CVE-2025-50182, CVE-2024-37891 |
| openai | 2.6.0 | ✅ Secure | Updated from 1.109.1, minor breaking changes |
| dash | 3.2.0 | ✅ Secure | Fixes CVE-2024-21485 (XSS) |
| pandas | 2.3.3 | ✅ Secure | Latest stable version |
| pillow | 11.3.0 | ✅ Secure | Latest stable version |
| jinja2 | 3.1.6 | ✅ Secure | Latest stable version |
| certifi | 2025.10.5 | ✅ Secure | Latest CA bundle |
The following packages were upgraded to their latest versions:
Major Version Updates:
- openai: 1.109.1 → 2.6.0
- pylint: 3.3.8 → 4.0.2
- isort: 6.0.1 → 7.0.0
- astroid: 3.3.11 → 4.0.1
Minor/Patch Updates:
- certifi: 2025.8.3 → 2025.10.5
- numpy: 2.3.3 → 2.3.4
- pandas: 2.3.2 → 2.3.3
- matplotlib: 3.10.6 → 3.10.7
- ruff: 0.13.2 → 0.14.1
- And 15+ other patch updates
Compatibility: All upgrades have been tested for basic import compatibility. The OpenAI 2.x upgrade includes minor breaking changes to ResponseFunctionToolCallOutput, which does not affect this project's usage.
- Upgraded all dependencies to latest secure versions
- Addressed 25+ package updates including 4 major version upgrades
- Documented pip vulnerability mitigation via Python 3.12.3 PEP 706
- Verified all CVEs fixed in updated packages
- Initial security audit completed
- Fixed 4 critical/high severity vulnerabilities
- Implemented security best practices
- Created security documentation