Privacy Evaluation: Social Fixer

Social Fixer Logo

Introduction

I don’t know about you, but I have to admit that quarantine life is starting to get to me. Especially as someone who lives alone (aside from a very social cat), I find myself relying more and more on social media to stay connected with the rest of the world outside of work. The problem is that all of the negativity, politics, and just downright depressing posts surrounding COVID are probably not the best things to be dwelling on; especially when you are interacting with a computer screen instead of a face to face conversation. I suppose it would be easy enough to take a break for a week or so, but I also rely on Facebook for interacting with various tech and business groups which tend to be very beneficial to my work, and I don’t necessarily want to give those up, or the “fun” posts on Facebook from my friends and family either.

Social Fixer (https://socialfixer.com/) is a browser extension that would seem to help filter the majority of these posts (in addition to other categories such as ads, politics, etc.) in order to take a break for awhile and help focus on more positive content. But, all things considered, adding browser extensions (especially free browser extensions) is something that should be done with extreme caution as they often have access to a considerable amount of data about you, often including having access to passwords, session data, PII, and more. On their FAQ page, Social Fixer states the following “Requests are made back to the Facebook servers to retrieve your personal data like your friends list, groups, etc. This data is stored in your browser and nowhere else! None of your data is ever transmitted to any other site, nor stored anywhere but in your browser. The only requests made to non-Facebook servers are the requests made to socialfixer.com to check for new versions and to check for any important messages that need to be displayed. No uniquely identifying information is ever sent. None of your Facebook settings or data is ever changed by Social Fixer. It does not update your personal information, or your status, or your friends lists, or any other information about you or in your account. It only processes information – it never changes it.” (https://socialfixer.com/faq.html) This is great, but given what I see at work, I generally like to use a “trust but verify” approach… which spawned this research.

Version information

I tested the Chrome browser extension downloaded from the Google Web Store. The version of Chrome at the time of testing was 84.0.4147.105. The version of the extension was version 25.0.0, updated on June 30, 2020. The SHA256 for the data contained in the extension’s folder is: B1F9C50D7D258EFE72B46C9BAA70E9DCCE48C3E53C97FB450DD90D333103C6B6

Screenshot showing the Google Web Store entry of the extension which shows version 25.0.0 - updated June 30, 2020.

Permissions analysis

The extension can read and change all data on facebook[.]com, socialfixer[.]com, and matt-kruse[.]github[.]io. This is to be expected for an extension like this as it needs to be able to read data from facebook[.]com. Socialfixer[.]com and matt-kruse[.]github[.]io is ostensibly for maintenance purposes; however, it does suggest that data could be sent to matt-kruse[.]github[.]io which is different than the FAQ states (although admittedly not very concerning).

Traffic interception

The first thing to check in an evaluation like this is for obvious network traffic. Back when most traffic on the web was unencrypted, Wireshark was usually enough for this; but since most traffic is encrypted with TLS these days, intercepting meaningful traffic is not quite as simple. Luckily, there is Burpsuite. Burp allows researchers to install a trusted certificate in their browser and use Burp to intercept encrypted traffic by acting as a Man in the Middle (MitM) proxy between the browser and the site. Since the browser trusts the certificate presented by Burpsuite, it sends the requests to Burp as if Burp was the intended server. Burp then forwards those requests to the server. The server responds to Burp which then responds back to the browser. Since it has been in between the entire communication between the browser and the server, all of the data exchanged can be viewed in Burp.

Using Burp, I configured the browser as described above. I started by navigating Facebook and using it for a few minutes to generate a baseline of legitimate Facebook traffic to compare data collected during Social Fixer’s testing. Once I collected a baseline, I forked the Burp project, and installed the extension, cleared all cache and cookies and navigated back to Facebook and logged in again, ran through a basic configuration of Social Fixer (only enabling the “Hide Sponsored and Suggested Posts” filter, and began browsing similarly to last time.

Taking into account data that was most likely generated through normal browsing and system processes and by Facebook itself; 4 other requests were observed which were attributed to Social Fixer.

Screenshot showing requests to: https://matt-kruse[.]github[.]io/socialfixerdata with endpoints of filters.json, news.json, tweaks.json, and a request to https://socialfixer.com/version.txt.

Other than the omission of https://matt-kruse[.]github[.]io (which is obviously a site hosted on github related to the developer) from the FAQ page, nothing extremely concerning so far. Inspection of each request shows that the most concerning piece of data sent is the User-Agent; however, that is not a direct identifier, only an indirect identifier.

GET /socialfixerdata/filters.json HTTP/1.1
Host: matt-kruse.github.io
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: */*
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.facebook.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-None-Match: W/"5f13da94-475f"
If-Modified-Since: Sun, 19 Jul 2020 05:31:00 GMT
GET /socialfixerdata/news.json HTTP/1.1
Host: matt-kruse.github.io
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: */*
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.facebook.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
GET /socialfixerdata/tweaks.json HTTP/1.1
Host: matt-kruse.github.io
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: */*
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.facebook.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
GET /version.txt HTTP/1.1
Host: socialfixer.com
Connection: close
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: */*
Origin: https://www.facebook.com
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://www.facebook.com/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-None-Match: "5f203fc3-6"
If-Modified-Since: Tue, 28 Jul 2020 15:09:55 GMT

Overall, we could nitpick that requests are sent to https://matt-kruse[.]github[.]io when the website FAQ said they would only be sent to Facebook or Socialfixer[.]com; however, that seems like a very small issue; especially if you consider that the www subdomain of socialfixer[.]com seems to be a CNAME of matt-kruse[.]github[.]io and that the A records for the root domain point to the same IP addresses indicating that the same servers are in use for both matt-kruse[.]github[.]io and socialfixer[.]com; but beyond that nothing seems too concerning within the network capture.

nslookup showing that www.socialfixer.com is a CNAME for matt-kruse.github.io and that socialfixer.com points to the same A records.

Source code review

Traffic interception is all well and good for a cursory examination; but it’s just an example of what happened in that specific circumstance. How do we know there isn’t hidden functionality that only activates under certain conditions or after a certain amount of time? The best way to verify this is with source code review. Luckily Chrome extensions are just zipped files containing readable source code, which makes this easier than compiled code. At first glance the source for this extension might seem rather complex, but in most cases those folders simply contain a single code file that does a specific function.

Screenshot of the source code folder

Rather than going in-depth about what each part does, it makes more sense to just summarize the files which contain the ability to make requests out to external (non-Facebook) sites or other notable abilities.

  • external_css\external_css.js
    • This file makes a request to a [sanitized] user-specified URL in order to load an external CSS per a user’s request.
  • hide\hide.js
    • This file has an anchor tag which links to socialfixer[.]com/support
    • It also makes a request to https://matt-kruse[.]github[.]io/socialfixerdata/hideable.json to get the definitions of the types of posts which the function can hide.
  • menu\menu.js
    • This file adds links to https://socialfixer[.]com/support/ and http://socialfixer[.]com/donate.html
    • The file also make a calls to https://matt-kruse[.]github[.]io/socialfixerdata/news.json to get definitions of “news” blurbs about social fixer.
  • options\options.js
    • This file adds links to https://matt-kruse[.]github[.]io/socialfixerdata/support.html, https://matt-kruse[.]github[.]io/socialfixerdata/donate.html, https://matt-kruse[.]github[.]io/socialfixerdata/about.html, https://github[.]com/matt-kruse/SocialFixer/wiki/Post-Filtering#filter-list, and https://github[.]com/matt-kruse/SocialFixer/wiki/Post-Filtering#edit-filter.
  • post_filters\post_filters.js
    • While this file does not directly make requests, it does rewrite some links on the page to simplify them. It does not appear to redirect them to other hosts though.
  • regex_tester\regex_tester.js
    • Adds an anchor tag to https://developer[.]mozilla[.]org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
  • sfx_collision\sfx_collision.js
    • References http://tiny[.]cc/sfx-only-1, http://tiny[.]cc/sfx-saveprefs, and https://socialfixer[.]com/support in a Javascript alert.
  • stats\stats.js
    • Makes call to https://socialfixer[.]com/version[.]txt
  • sticky_note\sticky_note.js
    • Injects content into the page without sanitization within the function that injects the content.
  • stretch_wide\stretch_wide.js
    • Adds link to https://userstyles[.]org/styles/browse?as=1&per_page=25&search_terms=facebook+wide
  • subscriptions\subscriptions.js
    • Makes calls to https://matt-kruse[.]github[.]io/socialfixerdata/[variable].json

The main area of concern I had after the initial code review was the sticky_note function injecting content into the page without sanitization, which at face value presents itself as a security concern. I did a further review to find all references of the sticky_note function, and none of them used variable messages, they were all pre-programmed static messages which makes it less of an issue that there is no sanitization. With that being said; in general it would be best practice to sanitize that input at the function level in case future updates add the ability for that function to be called with variables of any kind that could result in the extension being used with a XSS attack; however, at this point there is no obvious way in which this could be exploited.

Conclusion

Overall there were no major privacy concerns I could identify without some pretty extreme nitpicking. The injection of unsanitized content into the page through the sticky_note function doesn’t sit well with me; however, since the content is static and not variable, the conditions in which such an issue could be exploited make the exploitation of the issue unnecessary as an attacker would already have the level of access that the exploit could provide in order to perform the exploit in the first place. My main unease is with how such a function may be used in future updates, but as of this time there is nothing to suggest that this is a notable vulnerability or that future update plans are in place to expand the use of this specific function. In fact, it is such a minor note that I will not even be bothering to file a responsible disclosure which would be my normal procedure before publishing if I believed I had found a vulnerability in something I was researching.

My “verdict” on this extension is that I will without a doubt be installing it on my personal computer and will use it as much as possible when browsing Facebook for at least the next few weeks.

Considerations

This analysis is a point in time review on one particular browser, and it is possible that the extension could be updated at any time with additional functionality or operate differently on other browsers. This analysis may not be adequate for future versions/updates; however, it is in-depth for the current version and shows that at least in the current version, it does what it claims, and no more with the exception of the one slight correction in domain names it reaches out to. In order to aid future analysis, a hash list of each file investigated is attached so that only modified files will need to be inspected in the future.

Hash list: https://semsec.net/wp-content/uploads/2020/07/SocialFixerHashList2020-07-29.csv

About thegeekkid

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.