From b21dbbe3a33f66868d1bad22267e99c9b095e087 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Wed, 9 Nov 2022 23:27:45 +0400 Subject: [PATCH] Fetcher: do not use cookies to avoid CSRF checks (#312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fetcher: do not use cookies to avoid CSRF checks * Explain why we disable cookies * Rename getURLSession() → createURLSession() and move it below --- Sources/tart/Fetcher.swift | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Sources/tart/Fetcher.swift b/Sources/tart/Fetcher.swift index d61b4d2..f2d3391 100644 --- a/Sources/tart/Fetcher.swift +++ b/Sources/tart/Fetcher.swift @@ -1,6 +1,8 @@ import Foundation import AsyncAlgorithms +fileprivate let urlSession = createURLSession() + class Fetcher { static func fetch(_ request: URLRequest, viaFile: Bool = false) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { if viaFile { @@ -13,7 +15,7 @@ class Fetcher { private static func fetchViaMemory(_ request: URLRequest) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { let dataCh = AsyncThrowingChannel() - let (data, response) = try await URLSession.shared.data(for: request) + let (data, response) = try await urlSession.data(for: request) Task { await dataCh.send(data) @@ -27,7 +29,7 @@ class Fetcher { private static func fetchViaFile(_ request: URLRequest) async throws -> (AsyncThrowingChannel, HTTPURLResponse) { let dataCh = AsyncThrowingChannel() - let (fileURL, response) = try await URLSession.shared.download(for: request) + let (fileURL, response) = try await urlSession.download(for: request) // Acquire a handle to the downloaded file and then remove it. // @@ -47,3 +49,19 @@ class Fetcher { return (dataCh, response as! HTTPURLResponse) } } + +fileprivate func createURLSession() -> URLSession { + let config = URLSessionConfiguration.default + + // Harbor expects a CSRF token to be present if the HTTP client + // carries a session cookie between its requests[1] and fails if + // it was not present[2]. + // + // To fix that, we disable the automatic cookies carry in URLSession. + // + // [1]: https://github.com/goharbor/harbor/blob/a4c577f9ec4f18396207a5e686433a6ba203d4ef/src/server/middleware/csrf/csrf.go#L78 + // [2]: https://github.com/cirruslabs/tart/issues/295 + config.httpShouldSetCookies = false + + return URLSession(configuration: config) +}