Fetcher: do not use cookies to avoid CSRF checks (#312)

* Fetcher: do not use cookies to avoid CSRF checks

* Explain why we disable cookies

* Rename getURLSession() → createURLSession() and move it below
This commit is contained in:
Nikolay Edigaryev
2022-11-09 14:27:45 -05:00
committed by GitHub
parent ee0fbdd83d
commit b21dbbe3a3
+20 -2
View File
@@ -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<Data, Error>, HTTPURLResponse) {
if viaFile {
@@ -13,7 +15,7 @@ class Fetcher {
private static func fetchViaMemory(_ request: URLRequest) async throws -> (AsyncThrowingChannel<Data, Error>, HTTPURLResponse) {
let dataCh = AsyncThrowingChannel<Data, Error>()
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<Data, Error>, HTTPURLResponse) {
let dataCh = AsyncThrowingChannel<Data, Error>()
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)
}