Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firebase/Analytics (GoogleAppMeasurement.framework) is using Keychain APIs incorrectly #4742

Closed
jklausa opened this issue Jan 24, 2020 · 6 comments

Comments

@jklausa
Copy link

jklausa commented Jan 24, 2020

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 11.3.1
  • Firebase SDK version: 6.15.0
  • Firebase Component: Analytics
  • Component version: 6.2.1 (for Analytics),
  • Installation method: CocoaPods

[REQUIRED] Step 2: Describe the problem

The GoogleAppMeasurement.framework is misusing the system Keychain APIs.

The documentation for kSecAttrAccount constant says:

The corresponding value is of type CFString and contains an account name

(emphasis mine)

Firebase / GoogleAppMeasurement misuses this API and sends along value of type CFData / NSData.

Steps to reproduce:

  1. Integrate FirebaseAnalytics.
  2. Explore keychain (either via code, or using a library like FLEX)
  3. Notice an item that has account name that's not a string, but a NSData object.

I figured it's coming from y'alls by running:

$ grep -R _pfo .
Binary file ./Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/GoogleAppMeasurement matches

Relevant Code:

Here's an easy way to reproduce it by just throwing this bit of Swift code into an existing application (it's pretty horrible, but for the purposes of illustration, etc)

var query = [kSecClass: kSecClassGenericPassword,
                     kSecReturnAttributes: true,
                     kSecMatchLimit: kSecMatchLimitAll] as [CFString : Any]

var result: AnyObject? = nil

_ = SecItemCopyMatching(query as! CFDictionary, &result)

let dict = result as! [[String: AnyObject]]

dump(dict.map { return "kSecAttrAccount value: \($0[kSecAttrAccount as String]!), type: \(type(of: $0[kSecAttrAccount as String]!))" })
dump(String(data: dict.first![kSecAttrAccount as String] as! Data, encoding: .utf8)!)

On my machine/app it prints the following:

▿ 2 elements
  - "kSecAttrAccount value: {length = 4, bytes = 0x5f70666f}, type: __NSCFData"
  - "kSecAttrAccount value: SOME_SORT_OF_IDENTIFIER_THAT_I'M_NOT_SURE-IF_ITS-PRIVATE__FIRAPP_DEFAULT, type: __NSCFString"
- "_pfo"
@google-oss-bot

This comment has been minimized.

@jklausa
Copy link
Author

jklausa commented Jan 24, 2020

hey, I tried my best there google-bot :(

@paulb777
Copy link
Member

Thanks for the report. Filed internally to the Analytics team at b/148272122.

@morganchen12 Any idea what went wrong with the google-bot?

@morganchen12
Copy link
Contributor

Looks like we may have missed a deploy when I updated the template paths. Google bot should be fixed now.

@morganchen12
Copy link
Contributor

https://forums.developer.apple.com/thread/46429#135833
https://developer.squareup.com/blog/uncovering-inconsistent-keychain-behavior-while-fixing-a-valet-ios-bug/

We should definitely do this soon, but the change is a little complicated since we need to migrate the old keychain entries over from Data to String without losing any of them.

@morganchen12
Copy link
Contributor

This issue should be fixed in the latest SDK release (6.18).

@morganchen12 morganchen12 added this to the 6.18.0 - M65 milestone Feb 26, 2020
@firebase firebase locked and limited conversation to collaborators Mar 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
4 participants