Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

### Topics

InfoQ Homepage News LinkedIn iOS Clipboard Copying Was Bug

# LinkedIn iOS Clipboard Copying Was Bug

This item in japanese

When iOS 14 (Beta) was released at WWDC, a number of new security features were added. One of them was the ability to find out if an app was interacting with the clipboard at unusual times; many apps have been indicated that they are copying the clipboard unnecessarily. This could be a problem if the user has recently copied a sensitive password or other personal application, leading some to question whether this was an intentional feature.

@DonCubed reported on twitter that the LinkedIn app was copying data on each keystroke, and thanks to the fact that it's possible to share clipboard data from a linked macOS system, it was able to copy data that had been used on the laptop as well:

LinkedIn is copying the contents of my clipboard every keystroke. IOS 14 allows users to see each paste notification.

I’m on an IPad Pro and it’s copying from the clipboard of my MacBook Pro.

Tik tok just got called out for this exact reason.

Many other apps were implicated doing similar things, and since it's not possible to (easily) determine the reason why, it's potential to leap to bad conclusions that they were nefariously stealing information.

In the case of LinkedIn, however, it seems that this may have been an unintentional bug. Erran Berger, VP engineering of consumer products at LinkedIn, clarifed that it was an issue that has been fixed:

Hi @DonCubed. Appreciate you raising this. We've traced this to a code path that only does an equality check between the clipboard contents and the currently typed content in a text box. We don't store or transmit the clipboard contents.

An example of this is in a library we have open sourced, and you can find the fix here https://github.com/linkedin/Hakawai/commit/c3f89585c097863c2017beb2a1774df21ad42da4

We will follow up once the fix is live in our app.

It's possible that other applications are using the open-source Hakawai component in their applications, which might explain why similar error messages are being seen across multiple apps. An alternative explaination is that maybe the code was stackoverflowed and simpl ended up in many places.

In this case, the custom text field that was being used by the Hakawai component was comparing the text the user was typing in with the contents of the pasteboard to determine if that content was pasted in. The repeated access of the [[UIPasteboard generalPasteboard] string] – which is UIPasteboard.general.string in Swift syntax – was causing the notifications to be shown in the app.

The fix removed the offending code from the library, and used a different logical path to determine the paste, sourced from the actual paste operation itself rather than monitoring the clipboard itself:

- NSString *const pasteboardString = [[UIPasteboard generalPasteboard] string];
- if (pasteboardString) {
-   self.changeIsPaste = [text isEqualToString:pasteboardString];
- } else {
-   self.changeIsPaste = NO;
- }
+ self.changeIsPaste = wasPaste;

The LinkedIn app has yet to be rebuilt against the new library and deployed to the app store, but it is likely that a change is imminent. The app is updated relatively frequently, with the last update a week ago, so it's likely that we'll see a version of this with the fix in place within a matter of days.

If you're building an iOS app, check to see if you're using the UIPasteboard and consider only using it if needed for specific requirements; in iOS 14 each use will now notify the user each time it is called.

Style

## Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.25750553607940674, "perplexity": 3229.2722375564945}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2023-06/segments/1674764499946.80/warc/CC-MAIN-20230201144459-20230201174459-00803.warc.gz"}