Skip to content

Commit 5080103

Browse files
Fix code scanning alert: Clear-text logging of sensitive information (#27)
Address security issue identified in: https://github.com/jpstroop/fitbit-client-python/security/code-scanning/8 - Add docs/SECURITY.md with comprehensive guidance on debug mode security - Add explicit security warnings to debug output in _base.py - Update docstrings in debug-related methods to highlight security risks Debug mode intentionally includes OAuth tokens for troubleshooting, but now includes proper documentation and warnings about secure usage. --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent 5cd195f commit 5080103

File tree

4 files changed

+70
-7
lines changed

4 files changed

+70
-7
lines changed

docs/SECURITY.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Security Considerations
2+
3+
## Debug Mode Security Considerations and Warning
4+
5+
This library includes a debug mode feature that generates complete cURL commands
6+
for troubleshooting API requests. This feature is designed to help during
7+
development and debugging only.
8+
9+
When you enable debug mode by setting `debug=True` in any API method call:
10+
11+
```python
12+
# This will print a complete curl command to stdout
13+
client.get_profile(debug=True)
14+
```
15+
16+
The generated cURL command includes:
17+
18+
- The full API endpoint URL
19+
- All request parameters and data
20+
- The OAuth bearer token used for authentication
21+
22+
**WARNING: This exposes sensitive authentication credentials that could allow
23+
API access as the authenticated user.**
24+
25+
1. **NEVER use debug mode in production environments**
26+
2. **NEVER log debug mode output to persistent storage**
27+
3. **NEVER share debug mode output without removing the authorization token**
28+
4. **NEVER commit debug mode output to version control**
29+
30+
## General Security Considerations
31+
32+
### OAuth Token Management
33+
34+
- Store OAuth tokens securely, preferably in an encrypted format
35+
- Implement token rotation and refresh mechanisms properly
36+
- Never hard-code tokens in application code
37+
- Use environment variables or secure configuration management for client IDs
38+
and secrets
39+
40+
### Production Deployment
41+
42+
- Ensure token refresh callbacks use HTTPS
43+
- Validate that your callback URL is properly secured
44+
- Follow OAuth 2.0 best practices for authentication flows
45+
- Set appropriate token expiration times

fitbit_client/resources/_base.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# fitbit_client/resources/_base.py
22

3+
34
# Standard library imports
45
from datetime import datetime
56
from inspect import currentframe
67
from json import JSONDecodeError
78
from json import dumps
89
from logging import getLogger
10+
import re
911
from time import sleep
1012
from typing import Dict
1113
from typing import Optional
@@ -480,7 +482,8 @@ def _make_request(
480482
requires_user_id: Whether the endpoint requires user_id in the path
481483
http_method: HTTP method to use (GET, POST, DELETE)
482484
api_version: API version to use (default: "1")
483-
debug: If True, prints a curl command to stdout to help with debugging
485+
debug: If True, prints a curl command to stdout to help with debugging.
486+
WARNING: This exposes authentication tokens! See docs/SECURITY.md for guidance.
484487
485488
Returns:
486489
JSONType: The API response in one of these formats:
@@ -516,7 +519,9 @@ def _make_request(
516519

517520
if debug:
518521
curl_command = self._build_curl_command(url, http_method, data, json, params)
519-
print(f"\n# Debug curl command for {calling_method}:")
522+
print(f"\n# DEBUG MODE: Security Warning - contains authentication tokens!")
523+
print(f"# See docs/SECURITY.md for guidance on sharing this output safely.")
524+
print(f"# Debug curl command for {calling_method}:")
520525
print(curl_command)
521526
print()
522527
return None
@@ -628,7 +633,8 @@ def _make_direct_request(self, path: str, debug: bool = False) -> JSONType:
628633
629634
Args:
630635
path: Full relative API path including query string (e.g., '/1/user/-/sleep/list.json?offset=10&limit=10')
631-
debug: If True, prints a curl command to stdout to help with debugging
636+
debug: If True, prints a curl command to stdout to help with debugging.
637+
WARNING: This exposes authentication tokens! See docs/SECURITY.md for guidance.
632638
633639
Returns:
634640
JSONDict: The API response as a dictionary
@@ -641,7 +647,9 @@ def _make_direct_request(self, path: str, debug: bool = False) -> JSONType:
641647

642648
if debug:
643649
curl_command = self._build_curl_command(url, "GET")
644-
print(f"\n# Debug curl command for {calling_method} (pagination):")
650+
print(f"\n# DEBUG MODE: Security Warning - contains authentication tokens!")
651+
print(f"# See docs/SECURITY.md for guidance on sharing this output safely.")
652+
print(f"# Debug curl command for {calling_method} (pagination):")
645653
print(curl_command)
646654
print()
647655
return {}

fitbit_client/utils/curl_debug_mixin.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ def _build_curl_command(
3737
"""
3838
Build a curl command string for debugging API requests.
3939
40+
WARNING: Security Risk - The generated command includes the actual OAuth bearer token,
41+
which should never be logged, shared, or committed to version control.
42+
See docs/SECURITY.md for guidance on securely using this feature.
43+
4044
Args:
4145
url: Full API URL
4246
http_method: HTTP method (GET, POST, DELETE)
@@ -49,7 +53,7 @@ def _build_curl_command(
4953
5054
The generated command includes:
5155
- The HTTP method (for non-GET requests)
52-
- Authorization header with OAuth token
56+
- Authorization header with OAuth token (SENSITIVE INFORMATION)
5357
- Request body (if data or json is provided)
5458
- Query parameters (if provided)
5559

tests/fitbit_client/resources/test_base.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,14 @@ def test_make_direct_request_with_debug(mock_build_curl, mock_print, base_resour
619619
# Verify the curl command was built correctly
620620
mock_build_curl.assert_called_once_with("https://api.fitbit.com/test", "GET")
621621

622-
# Verify print was called with the right message pattern
623-
mock_print.assert_any_call("\n# Debug curl command for test_pagination (pagination):")
622+
# Verify security warning messages were printed
623+
mock_print.assert_any_call(
624+
"\n# DEBUG MODE: Security Warning - contains authentication tokens!"
625+
)
626+
mock_print.assert_any_call(
627+
"# See docs/SECURITY.md for guidance on sharing this output safely."
628+
)
629+
mock_print.assert_any_call("# Debug curl command for test_pagination (pagination):")
624630

625631

626632
@patch("fitbit_client.resources._base.BaseResource._handle_json_response")

0 commit comments

Comments
 (0)