Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto committed Nov 27, 2024
2 parents 9129000 + 23103cf commit 573052a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 11 deletions.
5 changes: 4 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ disabled_rules:
- trailing_comma
- opening_brace

line_length: 160
line_length:
warning: 160
ignores_comments: true

file_length:
warning: 1000
error: 1200
Expand Down
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

- no user facing changes

## 3.15.7 - 2024-11-25

- fix: detect and mask out system photo library and user photos ([#261](https://github.com/PostHog/posthog-ios/pull/261))
- This can be disabled through the following `sessionReplayConfig` options:

```swift
config.sessionReplayConfig.maskAllSandboxedViews = false
config.sessionReplayConfig.maskPhotoLibraryImages = false
```
## 3.15.6 - 2024-11-20

- fix: read accessibilityLabel from parent's view to avoid performance hit on RN ([#259](https://github.com/PostHog/posthog-ios/pull/259))
Expand Down Expand Up @@ -383,4 +392,4 @@ Fix issues with launching the library and screen tracking.

## 1.0.0 - 2020-04-22

First Release.
First Release.
2 changes: 1 addition & 1 deletion PostHog.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "PostHog"
s.version = "3.15.6"
s.version = "3.15.7"
s.summary = "The hassle-free way to add posthog to your iOS app."

s.description = <<-DESC
Expand Down
2 changes: 1 addition & 1 deletion PostHog/PostHogVersion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

// if you change this, make sure to also change it in the podspec and check if the script scripts/bump-version.sh still works
// This property is internal only
public var postHogVersion = "3.15.6"
public var postHogVersion = "3.15.7"

public let postHogiOSSdkName = "posthog-ios"
// This property is internal only
Expand Down
51 changes: 44 additions & 7 deletions PostHog/Replay/PostHogReplayIntegration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//
#if os(iOS)
import Foundation
import PhotosUI
import SwiftUI
import UIKit
import WebKit
Expand Down Expand Up @@ -82,6 +83,8 @@

private let reactNativeTextView: AnyClass? = NSClassFromString("RCTTextView")
private let reactNativeImageView: AnyClass? = NSClassFromString("RCTImageView")
// These are usually views that don't belong to the current process and are most likely sensitive
private let systemSandboxedView: AnyClass? = NSClassFromString("_UIRemoteView")

static let dispatchQueue = DispatchQueue(label: "com.posthog.PostHogReplayIntegration",
target: .global(qos: .utility))
Expand Down Expand Up @@ -291,6 +294,15 @@
}
}

// detect any views that don't belong to the current process (likely system views)
if config.sessionReplayConfig.maskAllSandboxedViews,
let systemSandboxedView,
view.isKind(of: systemSandboxedView)
{
maskableWidgets.append(view.toAbsoluteRect(window))
return
}

// if its a generic type and has subviews, subviews have to be checked first
let hasSubViews = !view.subviews.isEmpty

Expand Down Expand Up @@ -388,6 +400,24 @@
image.imageAsset?.value(forKey: "_containingBundle") != nil
}

// Photo library images have a UUID identifier as _assetName (e.g 64EF5A48-2E96-4AB2-A79B-AAB7E9116E3D)
// SF symbol and bundle images have the actual symbol name as _assetName (e.g chevron.backward)
private func isPhotoLibraryImage(_ image: UIImage) -> Bool {
guard config.sessionReplayConfig.maskPhotoLibraryImages else {
return false
}

guard let assetName = image.imageAsset?.value(forKey: "_assetName") as? String else {
return false
}

if assetName.isEmpty { return false }
if image.isSymbolImage { return false }
if isAssetsImage(image) { return false }

return true
}

private func isAnyInputSensitive(_ view: UIView) -> Bool {
isTextInputSensitive(view) || config.sessionReplayConfig.maskAllImages
}
Expand Down Expand Up @@ -437,14 +467,21 @@
}

private func isImageViewSensitive(_ view: UIImageView) -> Bool {
var isAsset = false
if let image = view.image {
isAsset = isAssetsImage(image)
} else {
// if there's no image, there's nothing to mask
return false
// if there's no image, there's nothing to mask
guard let image = view.image else { return false }

// sensitive, regardless
if view.isNoCapture() {
return true
}
return (config.sessionReplayConfig.maskAllImages && !isAsset) || view.isNoCapture()

if config.sessionReplayConfig.maskAllImages {
// asset images are probably not sensitive
return !isAssetsImage(image)
}

// try to detect user photo images
return isPhotoLibraryImage(image)
}

private func toWireframe(_ view: UIView) -> RRWireframe? {
Expand Down
11 changes: 11 additions & 0 deletions PostHog/Replay/PostHogSessionReplayConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@
/// Default: true
@objc public var maskAllImages: Bool = true

/// Enable masking of all sandboxed system views
/// These may include UIImagePickerController, PHPickerViewController and CNContactPickerViewController
/// Experimental support
/// Default: true
@objc public var maskAllSandboxedViews: Bool = true

/// Enable masking of images that likely originated from user's photo library
/// Experimental support (UIKit only)
/// Default: true
@objc public var maskPhotoLibraryImages: Bool = true

/// Enable capturing network telemetry
/// Experimental support
/// Default: true
Expand Down

0 comments on commit 573052a

Please sign in to comment.