diff --git a/SECURITY.md b/SECURITY.md index 1e37ea9..baf4e62 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,148 +2,6 @@ ## Last Updated: 2026-04-18 -## Executive Summary - -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. - -## Vulnerabilities Identified and Fixed - -### 1. CRITICAL - SQL Injection Vulnerabilities - -**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:** -```python -# 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): -```python -# 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. - ---- - -### 2. CRITICAL - Hardcoded API Key - -**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:** -```python -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: -```python -# 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. - ---- - -### 3. HIGH - Sensitive Data Exposure in Logs - -**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:** -```python -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 -```python -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. - ---- - -### 4. HIGH - Session State Exposure in Debug Mode - -**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:** -```python -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: -```python -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. - ---- - ## Security Best Practices Implemented ### 1. Parameterized SQL Queries