From 9eada435a89b73e5cc7c4b54c39caaac958c84d6 Mon Sep 17 00:00:00 2001 From: Raphael Cruzeiro Date: Sat, 3 Oct 2020 02:12:01 +0100 Subject: [PATCH 1/2] Using the keyFilters parameter of the Bugsnag configuration to filter out sensitive data from the request headers. Fixes #74 --- Sources/Bugsnag/BugsnagReporter.swift | 14 +++++++++++++- Tests/BugsnagTests/BugsnagTests.swift | 8 ++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Sources/Bugsnag/BugsnagReporter.swift b/Sources/Bugsnag/BugsnagReporter.swift index 6f6f782..5473a6a 100644 --- a/Sources/Bugsnag/BugsnagReporter.swift +++ b/Sources/Bugsnag/BugsnagReporter.swift @@ -102,10 +102,22 @@ extension BugsnagReporter { } else { eventRequestBody = nil } + + var headerDict: [String : Any] = request.headers.reduce([:], { result, value in + var copy = result + copy[value.0] = value.1 + return copy + }) + strip(keys: configuration.keyFilters, from: &headerDict) + + let filteredHeaders: [(String, String)] = headerDict.map { + k, v in (k, v as! String) + } + eventRequest = .init( body: eventRequestBody, clientIp: request.headers.forwarded.first(where: { $0.for != nil })?.for ?? request.remoteAddress?.hostname, - headers: .init(uniqueKeysWithValues: request.headers.map { $0 }), + headers: .init(uniqueKeysWithValues: filteredHeaders), httpMethod: request.method.string, referer: "n/a", url: request.url.string diff --git a/Tests/BugsnagTests/BugsnagTests.swift b/Tests/BugsnagTests/BugsnagTests.swift index dac91df..fd4cc7c 100644 --- a/Tests/BugsnagTests/BugsnagTests.swift +++ b/Tests/BugsnagTests/BugsnagTests.swift @@ -57,7 +57,7 @@ final class BugsnagTests: XCTestCase { app.bugsnag.configuration = .init( apiKey: "foo", releaseStage: "debug", - keyFilters: ["email", "password"] + keyFilters: ["email", "password", "Authorization"] ) app.clients.use(.test) @@ -90,7 +90,9 @@ final class BugsnagTests: XCTestCase { application: app, method: .POST, url: "/test", - on: app.eventLoopGroup.next() + headers: [ + "Authorization": "Bearer SupErSecretT0ken!" + ], on: app.eventLoopGroup.next() ) try request.content.encode(vapor) try request.bugsnag.report(Abort(.internalServerError, reason: "Oops")).wait() @@ -103,6 +105,7 @@ final class BugsnagTests: XCTestCase { User.self, from: Data(payload.events[0].request!.body!.utf8) ) + let headers = payload.events[0].request!.headers XCTAssertEqual(user.name, "Vapor") XCTAssertEqual(user.email, "") XCTAssertEqual(user.password, "") @@ -110,6 +113,7 @@ final class BugsnagTests: XCTestCase { XCTAssertEqual(user.user?.email, "") XCTAssertEqual(user.user?.password, "") XCTAssertNil(user.user?.user) + XCTAssertEqual(headers["Authorization"], "") } } From 87c1e33b6c385b5ad92d8f41606e1b8d483ce699 Mon Sep 17 00:00:00 2001 From: Raphael Cruzeiro Date: Thu, 8 Oct 2020 11:26:06 +0100 Subject: [PATCH 2/2] Made the code safer by removing the force cast and modified the header dictonary building to use reduce(into:) so that the overall code is more idionatic Swift --- Sources/Bugsnag/BugsnagReporter.swift | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Sources/Bugsnag/BugsnagReporter.swift b/Sources/Bugsnag/BugsnagReporter.swift index 5473a6a..6569403 100644 --- a/Sources/Bugsnag/BugsnagReporter.swift +++ b/Sources/Bugsnag/BugsnagReporter.swift @@ -103,15 +103,14 @@ extension BugsnagReporter { eventRequestBody = nil } - var headerDict: [String : Any] = request.headers.reduce([:], { result, value in - var copy = result - copy[value.0] = value.1 - return copy - }) + var headerDict: [String : Any] = request.headers.reduce(into: [:]) { result, value in + result[value.0] = value.1 + } strip(keys: configuration.keyFilters, from: &headerDict) - let filteredHeaders: [(String, String)] = headerDict.map { - k, v in (k, v as! String) + let filteredHeaders: [(String, String)] = headerDict.compactMap { k, v in + guard let value = v as? String else { return nil } + return (k, value) } eventRequest = .init(