diff --git a/AmplifyPlugins/Core/AmplifyCredentials/CustomHttpClientEngine/FoundationClientEngine.swift b/AmplifyPlugins/Core/AmplifyCredentials/CustomHttpClientEngine/FoundationClientEngine.swift index fb6c241bd8..def8d54ca7 100644 --- a/AmplifyPlugins/Core/AmplifyCredentials/CustomHttpClientEngine/FoundationClientEngine.swift +++ b/AmplifyPlugins/Core/AmplifyCredentials/CustomHttpClientEngine/FoundationClientEngine.swift @@ -11,10 +11,12 @@ import SmithyHTTPAPI @_spi(FoundationClientEngine) public struct FoundationClientEngine: HTTPClient { + let urlSession: URLSession + public func send(request: SmithyHTTPAPI.HTTPRequest) async throws -> SmithyHTTPAPI.HTTPResponse { let urlRequest = try await URLRequest(from: request) - let (data, response) = try await URLSession.shared.data(for: urlRequest) + let (data, response) = try await urlSession.data(for: urlRequest) guard let httpURLResponse = response as? HTTPURLResponse else { // This shouldn't be necessary because we're only making HTTP requests. // `URLResponse` should always be a `HTTPURLResponse`. @@ -30,7 +32,16 @@ public struct FoundationClientEngine: HTTPClient { return httpResponse } - public init() {} + public init() { + // These requests carry Cognito tokens and AWS credentials. Disable URL + // caching so that responses are never persisted to disk (e.g. Cache.db), + // where they could be recovered by inspecting the app container. This + // mirrors the cache-disabling behavior used for the Hosted UI session. + let configuration = URLSessionConfiguration.default + configuration.urlCache = nil + configuration.requestCachePolicy = .reloadIgnoringLocalCacheData + self.urlSession = URLSession(configuration: configuration) + } /// no-op func close() async {} diff --git a/AmplifyPlugins/Core/AmplifyCredentialsTests/Utils/FoundationClientEngineTests.swift b/AmplifyPlugins/Core/AmplifyCredentialsTests/Utils/FoundationClientEngineTests.swift new file mode 100644 index 0000000000..d45ab2b027 --- /dev/null +++ b/AmplifyPlugins/Core/AmplifyCredentialsTests/Utils/FoundationClientEngineTests.swift @@ -0,0 +1,32 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +@_spi(FoundationClientEngine) +@testable import InternalAmplifyCredentials +import XCTest + +class FoundationClientEngineTests: XCTestCase { + + /// Given: A `FoundationClientEngine`. + /// When: The engine is initialized. + /// Then: Its `URLSession` has URL caching disabled so that responses + /// carrying Cognito tokens / AWS credentials are never persisted + /// to disk (e.g. Cache.db). + func test_urlSession_disablesCaching() { + let engine = FoundationClientEngine() + let configuration = engine.urlSession.configuration + + XCTAssertNil( + configuration.urlCache, + "URLSession must not have a URLCache, otherwise credential responses are persisted to disk." + ) + XCTAssertEqual( + configuration.requestCachePolicy, + .reloadIgnoringLocalCacheData + ) + } +}