Fix access token issue when connection pool enabled#1403
Conversation
b2dde91 to
97983ce
Compare
870b7e5 to
72dd098
Compare
72dd098 to
ae1f808
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## dev #1403 +/- ##
==========================================
+ Coverage 83.61% 83.63% +0.02%
==========================================
Files 22 22
Lines 7853 8727 +874
==========================================
+ Hits 6566 7299 +733
- Misses 1287 1428 +141 🚀 New features to boost your workflow:
|
8bc5e4e to
71e7dcd
Compare
71e7dcd to
6293a91
Compare
|
Fix for issue #1396 |
|
Any update on this? |
- Identified critical security vulnerability (authentication bypass) - Analyzed proposed fix for access token pooling issue - Raised concerns about platform coverage (Windows NTS only) - Documented testing and security requirements - Provided recommendations for improvement
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
AI Analysis of this PRThe PR attempts the token-cache approach for Windows NTS builds while keeping the existing (buggy) early-free for ZTS. It's the right direction, but has several serious issues: 1. Double-free: dual ownership of token memoryThe same
When the connection is destroyed ( 2. Double-free on same-token reuse pathWhen the same token content is found in the cache: sqlsrv_free(get_access_tokens()[current_token_index]); // frees the bufferThis frees the allocation that the previous connection's 3. Doesn't actually achieve pooling for identical tokensThe "same token found" path:
But the ODBC driver already hashed the old pointer for the pooled connection's key. The new pointer has a different address → different 4. Windows NTS onlyThe fix is guarded by 5. Minor issues
What a correct implementation would needFor the token cache to work properly:
TestsFor a fix that changes connection pooling semantics around access tokens, you'd want tests covering at minimum:
The existing tests cover basic access token validation (empty token, conflicting credentials) and general connection pooling, but there's no test that combines both — i.e., testing pooling behavior when access tokens are involved. A proper fix for #1396 should include tests like: Test 1: Different tokens must not share a pooled connection// Connect with token1, get identity
$conn1 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token1; ConnectionPooling=1");
$user1 = $conn1->query("SELECT USER_NAME()")->fetchColumn();
unset($conn1); // returns to pool
// Connect with token2, must NOT get token1's connection
$conn2 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token2; ConnectionPooling=1");
$user2 = $conn2->query("SELECT USER_NAME()")->fetchColumn();
unset($conn2);
assert($user1 !== $user2, "Different tokens must yield different identities");Test 2: Same token should reuse a pooled connection$conn1 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token1; ConnectionPooling=1");
$spid1 = $conn1->query("SELECT @@SPID")->fetchColumn();
unset($conn1);
$conn2 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token1; ConnectionPooling=1");
$spid2 = $conn2->query("SELECT @@SPID")->fetchColumn();
unset($conn2);
assert($spid1 === $spid2, "Same token should reuse pooled connection");Test 3: Pooling disabled always creates fresh connections$conn1 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token1; ConnectionPooling=0");
$spid1 = $conn1->query("SELECT @@SPID")->fetchColumn();
unset($conn1);
$conn2 = new PDO("sqlsrv:server=$server; Database=$db; AccessToken=$token1; ConnectionPooling=0");
$spid2 = $conn2->query("SELECT @@SPID")->fetchColumn();
unset($conn2);
assert($spid1 !== $spid2, "Pooling disabled must not reuse connections");These tests require Azure AD infrastructure (two identities with tokens), so they'd need to be gated behind environment variables similar to the existing |
No description provided.