Skip to content

Commit 706bc2f

Browse files
SNOW-1546127: Fix python connector log leaking token inside http response body (#2011)
1 parent 3eaa331 commit 706bc2f

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

DESCRIPTION.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
88

99
# Release Notes
1010

11+
- v3.12.1(TBD)
12+
- Fixed a bug that session token is logged when renewing session.
13+
1114
- v3.12.0(July 24,2024)
1215
- Set default connection timeout of 10 seconds and socket read timeout of 10 minutes for HTTP calls in file transfer.
1316
- Optimized `to_pandas()` performance by fully parallel downloading logic.

src/snowflake/connector/network.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ def _token_request(self, request_type):
568568
token=header_token,
569569
)
570570
if ret.get("success") and ret.get("data", {}).get("sessionToken"):
571-
logger.debug("success: %s", ret)
571+
logger.debug("success: %s", SecretDetector.mask_secrets(str(ret)))
572572
self.update_tokens(
573573
ret["data"]["sessionToken"],
574574
ret["data"].get("masterToken"),
@@ -577,7 +577,7 @@ def _token_request(self, request_type):
577577
logger.debug("updating session completed")
578578
return ret
579579
else:
580-
logger.debug("failed: %s", ret)
580+
logger.debug("failed: %s", SecretDetector.mask_secrets(str(ret)))
581581
err = ret.get("message")
582582
if err is not None and ret.get("data"):
583583
err += ret["data"].get("errorMessage", "")

test/unit/test_renew_session.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from __future__ import annotations
77

8+
import logging
89
from unittest.mock import Mock, PropertyMock
910

1011
from snowflake.connector.network import SnowflakeRestful
@@ -57,3 +58,51 @@ def fake_request_exec(**_):
5758
del rest._master_token
5859
rest._renew_session()
5960
assert rest._connection.errorhandler.called # error
61+
62+
63+
def test_mask_token_when_renew_session(caplog):
64+
caplog.set_level(logging.DEBUG)
65+
OLD_SESSION_TOKEN = "old_session_token"
66+
OLD_MASTER_TOKEN = "old_master_token"
67+
NEW_SESSION_TOKEN = "new_session_token"
68+
NEW_MASTER_TOKEN = "new_master_token"
69+
connection = mock_connection()
70+
connection.errorhandler = Mock(return_value=None)
71+
type(connection)._probe_connection = PropertyMock(return_value=False)
72+
73+
rest = SnowflakeRestful(
74+
host="testaccount.snowflakecomputing.com", port=443, connection=connection
75+
)
76+
rest._token = OLD_SESSION_TOKEN
77+
rest._master_token = OLD_MASTER_TOKEN
78+
79+
# inject a fake method (success)
80+
def fake_request_exec(**_):
81+
return {
82+
"success": True,
83+
"data": {
84+
"sessionToken": NEW_SESSION_TOKEN,
85+
"masterToken": NEW_MASTER_TOKEN,
86+
},
87+
}
88+
89+
rest._request_exec = fake_request_exec
90+
91+
# no secrets recorded when renew succeed
92+
rest._renew_session()
93+
assert "new_session_token" not in caplog.text
94+
assert "new_master_token" not in caplog.text
95+
assert "old_session_token" not in caplog.text
96+
assert "old_master_token" not in caplog.text
97+
98+
def fake_request_exec(**_):
99+
return {"success": False, "message": "failed to renew session", "code": 987654}
100+
101+
rest._request_exec = fake_request_exec
102+
103+
# no secrets recorded when renew failed
104+
rest._renew_session()
105+
assert "new_session_token" not in caplog.text
106+
assert "new_master_token" not in caplog.text
107+
assert "old_session_token" not in caplog.text
108+
assert "old_master_token" not in caplog.text

0 commit comments

Comments
 (0)