Skip to content

Commit

Permalink
Fetch and parse config from server
Browse files Browse the repository at this point in the history
Summary:
Some advertisers pass "sensitive parameters" as a part of their events. We want to filter out these sensitive parameters on the client-side to minimize risk.

This diff enables us to fetch and parse the sensitive parameters returned in the server configuration.

Reviewed By: Nathaaaalie

Differential Revision: D54371238

fbshipit-source-id: 603e78b036e254113b6d5e4d1d182dfc95a669ce
  • Loading branch information
ryantobinmeta authored and facebook-github-bot committed Mar 22, 2024
1 parent 5153838 commit 36082dd
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 1 deletion.
Expand Up @@ -10,14 +10,30 @@ import Foundation

final class SensitiveParamsManager: NSObject, _AppEventsParameterProcessing {

private var isEnabled = false
private var sensitiveParamsConfig = [String: Set<String>]()
private var defaultSensitiveParams = Set<String>()
private static let sensitiveParamsKey = "sensitive_params"
private static let defaultSensitiveParamsKey = "_MTSDK_Default_"

var configuredDependencies: ObjectDependencies?

var defaultDependencies: ObjectDependencies? = .init(
serverConfigurationProvider: _ServerConfigurationManager.shared
)

func enable() {
// TODO: Implement this
guard let dependencies = try? getDependencies() else {
return
}
guard let sensitiveParams = dependencies.serverConfigurationProvider
.cachedServerConfiguration()
.protectedModeRules?[SensitiveParamsManager.sensitiveParamsKey] as? [[String: Any]]
else { return }
configureSensitiveParams(sensitiveParams: sensitiveParams)
if !sensitiveParamsConfig.isEmpty || !defaultSensitiveParams.isEmpty {
isEnabled = true
}
}

func processParameters(
Expand All @@ -27,10 +43,44 @@ final class SensitiveParamsManager: NSObject, _AppEventsParameterProcessing {
// TODO: Implement this
return nil
}

private func configureSensitiveParams(sensitiveParams: [[String: Any]]) {
for sensitiveParamDict in sensitiveParams {
if let key = sensitiveParamDict["key"] as? String,
let value = sensitiveParamDict["value"] as? [String] {
let sensitiveParamSet = Set(value)
if key == SensitiveParamsManager.defaultSensitiveParamsKey {
defaultSensitiveParams = sensitiveParamSet
} else if !sensitiveParamsConfig.keys.contains(key) {
sensitiveParamsConfig[key] = sensitiveParamSet
} else {
sensitiveParamsConfig[key] = sensitiveParamsConfig[key]?.union(sensitiveParamSet)
}
}
}
}
}

extension SensitiveParamsManager: DependentAsObject {
struct ObjectDependencies {
var serverConfigurationProvider: _ServerConfigurationProviding
}
}

// MARK: - Testing

#if DEBUG
extension SensitiveParamsManager {
func getIsEnabled() -> Bool {
isEnabled
}

func getSensitiveParamsConfig() -> [String: Set<String>] {
sensitiveParamsConfig
}

func getDefaultSensitiveParams() -> Set<String> {
defaultSensitiveParams
}
}
#endif
@@ -0,0 +1,165 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/

@testable import FBSDKCoreKit

final class SensitiveParamsManagerTests: XCTestCase {

let serverConfigDict = [
"protectedModeRules": [
"sensitive_params": [
[
"key": "test_event_name_1",
"value": ["test_sensitive_param_1", "test_sensitive_param_2"],
],
[
"key": "test_event_name_2",
"value": ["test_sensitive_param_2", "test_sensitive_param_3", "test_sensitive_param_4"],
],
[
"key": "_MTSDK_Default_",
"value": ["default_param_1", "default_param_2"],
],
],
],
]

lazy var serverConfiguration = ServerConfigurationFixtures.configuration(withDictionary: serverConfigDict)

// swiftlint:disable implicitly_unwrapped_optional
var provider: TestServerConfigurationProvider!
var sensitiveParamsManager: SensitiveParamsManager!
// swiftlint:enable implicitly_unwrapped_optional

override func setUp() {
super.setUp()
sensitiveParamsManager = SensitiveParamsManager()
provider = TestServerConfigurationProvider(configuration: serverConfiguration)
sensitiveParamsManager.configuredDependencies = .init(
serverConfigurationProvider: provider
)
}

override func tearDown() {
super.tearDown()
sensitiveParamsManager = nil
provider = nil
}

func testDefaultDependencies() throws {
sensitiveParamsManager.resetDependencies()
XCTAssertTrue(
sensitiveParamsManager.serverConfigurationProvider === _ServerConfigurationManager.shared,
"Should use the shared server configuration manger by default"
)
}

func testConfiguringDependencies() {
XCTAssertTrue(
sensitiveParamsManager.serverConfigurationProvider === provider,
"Should be able to create with a server configuration provider"
)
}

func testEnable1() {
let expectedSensitiveParamsConfig: [String: Set<String>] = [
"test_event_name_1": ["test_sensitive_param_1", "test_sensitive_param_2"],
"test_event_name_2": ["test_sensitive_param_2", "test_sensitive_param_3", "test_sensitive_param_4"],
]
let expectedDefaultSensitiveParams: Set<String> = ["default_param_1", "default_param_2"]
sensitiveParamsManager.enable()
XCTAssertTrue(sensitiveParamsManager.getIsEnabled())
XCTAssertTrue(sensitiveParamsManager.getSensitiveParamsConfig() == expectedSensitiveParamsConfig)
XCTAssertTrue(sensitiveParamsManager.getDefaultSensitiveParams() == expectedDefaultSensitiveParams)
}

func testEnable2() {
let testServerConfigDict = [
"protectedModeRules": [
"sensitive_params": [
[
"key": "test_event_name_1",
"value": ["test_sensitive_param_1", "test_sensitive_param_2"],
],
[
"key": "test_event_name_2",
"value": ["test_sensitive_param_2", "test_sensitive_param_3", "test_sensitive_param_4"],
],
],
],
]
let serverConfig = ServerConfigurationFixtures.configuration(withDictionary: testServerConfigDict)
provider = TestServerConfigurationProvider(configuration: serverConfig)
sensitiveParamsManager.configuredDependencies = .init(
serverConfigurationProvider: provider
)
let expectedSensitiveParamsConfig: [String: Set<String>] = [
"test_event_name_1": ["test_sensitive_param_1", "test_sensitive_param_2"],
"test_event_name_2": ["test_sensitive_param_2", "test_sensitive_param_3", "test_sensitive_param_4"],
]
sensitiveParamsManager.enable()
XCTAssertTrue(sensitiveParamsManager.getIsEnabled())
XCTAssertTrue(sensitiveParamsManager.getSensitiveParamsConfig() == expectedSensitiveParamsConfig)
XCTAssertTrue(sensitiveParamsManager.getDefaultSensitiveParams().isEmpty)
}

func testEnable3() {
let testServerConfigDict = [
"protectedModeRules": [
"sensitive_params": [
[
"key": "_MTSDK_Default_",
"value": ["default_param_1", "default_param_2"],
],
],
],
]
let serverConfig = ServerConfigurationFixtures.configuration(withDictionary: testServerConfigDict)
provider = TestServerConfigurationProvider(configuration: serverConfig)
sensitiveParamsManager.configuredDependencies = .init(
serverConfigurationProvider: provider
)
let expectedDefaultSensitiveParams: Set<String> = ["default_param_1", "default_param_2"]
sensitiveParamsManager.enable()
XCTAssertTrue(sensitiveParamsManager.getIsEnabled())
XCTAssertTrue(sensitiveParamsManager.getSensitiveParamsConfig().isEmpty)
XCTAssertTrue(sensitiveParamsManager.getDefaultSensitiveParams() == expectedDefaultSensitiveParams)
}

func testEnable4() {
let testServerConfigDict = [
"protectedModeRules": [
"sensitive_params": [],
],
]
let serverConfig = ServerConfigurationFixtures.configuration(withDictionary: testServerConfigDict)
provider = TestServerConfigurationProvider(configuration: serverConfig)
sensitiveParamsManager.configuredDependencies = .init(
serverConfigurationProvider: provider
)
sensitiveParamsManager.enable()
XCTAssertFalse(sensitiveParamsManager.getIsEnabled())
XCTAssertTrue(sensitiveParamsManager.getSensitiveParamsConfig().isEmpty)
XCTAssertTrue(sensitiveParamsManager.getDefaultSensitiveParams().isEmpty)
}

func testEnable5() {
let testServerConfigDict = [
"protectedModeRules": [],
]
let serverConfig = ServerConfigurationFixtures.configuration(withDictionary: testServerConfigDict)
provider = TestServerConfigurationProvider(configuration: serverConfig)
sensitiveParamsManager.configuredDependencies = .init(
serverConfigurationProvider: provider
)
sensitiveParamsManager.enable()
XCTAssertFalse(sensitiveParamsManager.getIsEnabled())
XCTAssertTrue(sensitiveParamsManager.getSensitiveParamsConfig().isEmpty)
XCTAssertTrue(sensitiveParamsManager.getDefaultSensitiveParams().isEmpty)
}
}

0 comments on commit 36082dd

Please sign in to comment.