by

Parler isn’t safe (parlez-vous danger?)

Reading Time: 13 minutes

In direct response to the recent election (I don’t even need to say which, you know the one), I have observed that many of my conservative friends and family touting a new platform for free-speech-minded folks: Parler.

Being an ever-curious individual with a degree in French, I decided to sign up for Parler. My interest was the content, but what caught my attention was the performance of the site, difficulty of the registration process, and numerous errors that give me cause to believe that Parler is not safe, stable, or secure.

I’ve been hanging around the web, doing weby things for about twelve years, so I’ll be speaking from my experiences in design, front-end development, and web software development. I welcome any technical criticism of my methods and observations.

If you are a not-so-technical person, I would encourage you to first read my (mostly) non-technical mythbusting about internet tracking, social networks, and security as it lays the foundation for many of my claims that Parler is not safe, stable, or secure.

Overflow on the Landing Page

When I went to the Parler landing page (parler.com/auth/access), the first thing I noticed was the horizontal scrollbar.

That little scroll bar, right… over there

“So? What’s the big deal?”

In my experience delivering sites for Nationwide Insurance, Boston Consulting Group, and Starbucks, this would be called something like a “Brand integrity issue”. It’s not anything that’s broken, but it’s a noticeable thing that can cause consumers to lose faith in the brand. It’s a bit like not wiping up excess grout after laying tile. You just wouldn’t do that.

The issue is caused by width: 100vw!important; set on both the body and the html element.

Resolution for the issue involves removing a single line of code.

I observed the issue on Tuesday, November 9th and it’s still visible today. In my experience, the only reason this kind of issue would persist for longer than a day is because there are more critical issues that require resolution.

Landing Page Performance

Often, I see things like overflow-x or width on an html/body as attempts to fix other layout problems; they’re bandaids on flesh wounds. The page had taken a noticeable time to load, so I cracked open Chrome’s Lighthouse tool to see what it had to say.

Chrome’s Lighthouse tool reports fantastic SEO, excellent accessibility, great adherence to best practices, and very very bad page performance

Users notice, and abandon, a web page after three seconds. Parler is very close to that in in first contentful paint alone. But the time to interactive is most alarming.

I pay for fiber optic internet and pull 500gb/s downstream. I cannot imagine how this site loads under less-than-ideal internet.

Parler performance issues
Almost every performance metric is bad, with exception to “cumulative layout shift”

Parler could cover up some of these paint problems using some tricks I’ve used before: fade-ins and animations (see frankmtaylor.com ).

Adventures in Markup: SVG loading logo

If you look at the source for their page, what you’ll see is that the page that’s initially served in the browser has an SVG and a stylesheet for animating it.

Parler homepage's source code
The Parler homepage HTML source code

So the user sees an SVG with what are probably some pretty cool animations, but as soon as all the JavaScript kicks in, this element is removed and the user has to watch Angular try to render the page in 2.5 seconds (or so).

If Parler would leave the SVG and have it fade-out once Angular finished loading, this wouldn’t be so jarring.

Alternatively, Parler could try server-side rendering. I don’t see any reason why their homepage; the most important page in their site, must be fully rendered in a browser.

Registration is Quirky

Signing up for Parler took me upwards of two hours. Not necessarily because of any single thing wrong with Parler, but because I was taking ridiculous measures to avoid using any real personal information, and Parler has some points where it’s hard to avoid that.

Privacy and Terms

When I clicked on “Create New Account”, I was met with a modal window to agree to the privacy and terms.

I was expecting a super long window of terms to read scroll through quickly. Instead, Parler doesn’t provide legalese in the window like other sites. The Privacy Policy, ToS, and Community Guidelines are all PDFs. In fact, they’re PDF’s that link to each other which will make it difficult to manage them as links change.

I did notice that the PDFs don’t have much metadata.

image of community guidelines metadata in Adobe Acrobat
The only metadata is the title, which is the name of the MS Word file this was generated from.

Registering on Parler

Once I’ve agreed to the things written in PDFs from legal.parler.com, I get a registration “window”, which is still a modal. But let’s jump out of the desktop experience to mobile for a few minutes.

I would’ve assumed that they’d chosen a JavaScript framework like Angular on account of the fact that it can be used to deliver the same experience in desktop as mobile. It turns out the experiences aren’t the same, with some interesting added features for mobile users.

Registering on Mobile

I started noticing some oddities from the first screen after downloading from the Android Play store.

Password Rules are Revealed, but not Visible

Parler Mobile Registration where it gives real-time feedback
Instead of showing users the password rules, Parler chooses to reveal the infractions as the user types

Parler will correct the user in both fields if the password violates a constraint.

Clicking on “Password Directions” reveals a modal window with a one-sentence explanation that the user will need to commit to memory.

Password Rules aren’t Visible, but the Password is

I can’t emphasize enough how deeply unsettling it is to see a password visible without my permission. Parler is keeping my password in memory and showing it to me in plain text.

Parler tooltip revealing the password
When typing in the password confirmation window, Parler reveals the password I should be typing as a tooltip

I have no doubt that the average user of Parler finds this convenient and may think nothing of it. But I will again say that I find this very unsettling.

There are ways to compare passwords without ever keeping the password in memory. I came up with an example in about ten minutes that compares the values of two inputs without ever retrieving a password in any way and “saving it for later”.

The fact that passwords can be compared without ever “storing” the password is relevant because this isn’t a case of developers “taking advantage” of some functionality. This is a case of developers intentionally keeping a password in memory for the sole purpose of being able to to show it. This is not how we do security.

The only reason I should ever see my password in a session is if I have clicked a small “reveal” icon in the input field.

It was at this point that I felt the app was extremely suspicious, abandoned registration in the app, and decided to complete registration on desktop.

Registering in Desktop

On desktop, registration is in a modal window, which I don’t care for. My chief complaint about putting forms in modal windows is that it’s easy to click away and lose your data. Parler did a good job with this, however, by disabling clicks outside of the modal; I can’t accidentally close it.

Parler registration window
Parler asks for three things to register: an email, a phone, and a password. It also makes the password constraints visible

None of those pesky password tooltips

What I like about the desktop version is that, quite the opposite of showing me my password, it never shows any tooltips.

Parler Desktop Registration  with a password constraint showing only a red border for a field
Any violation of the password constraints causes the password field to have a red border*
Adventures in Markup: “Red Border”

If a front-end developer closely investigates this form, that developer may discover that the “border” is in fact three separate divs with left, top/bottom, and right border properties applied.

Source code for the outline of a field in the registration form
I cannot think of a valid reason why this needs to be done.

Imagine a picture frame made with seven pieces of wood, instead of four: two for the left, one for the top, another for the bottom, and three for the right. Maybe if you’ve never seen a picture frame before in your life would you consider buying this. But if you have, in fact, seen pictures framed by exactly four pieces of wood, you will have a curious fascination about the kind of person who intentionally made an easy thing the hardest way possible so that it could be less useful.

The Captcha is a nice touch

After completing registration, the user will be shown a Captcha in a modal.

If the Terminator franchise taught us anything, it’s that robots can be defeated by asking them to read 8 clear letters/ numbers.

Parler Registration Captcha, which shows "Phone number undeliverable" at the bottom
The input field* is not red, even though I have an error message
Adventures in Markup: Input “field”

Front-end developers will also be delighted to see that the input does use a valid label element, complete with redundant aria attributes. Developers may also be interested in the fact that the the captcha has a maxlenght="8" attribute (note the misspelling). There is additional validation that disables the next button if the user types too many characters

Phone Number Undeliverable

Because of my suspicions with the mobile app, I made a concerted effort to not use any real data, including a phone number. I instead chose to set up a Google Voice phone number and provide that, instead.

As it turns out, Parler is doing some sort of validation on phone numbers where it won’t allow Google Voice mobile numbers. I don’t know what service it’s using because the validation is happening server-side. I can only remark that this is an interesting security measure.

Signing in to Parler

After conceding to use a real phone number, I was ready to login in. Quite surprisingly, I still had to prove I was not on a mission to kill John Connor.

Parler Signin Captcha
So far, the Captcha seems to be the only gate-keeper in all of Parler

Two-Factor After the Captcha

As it turns out, there’s more authentication. Signing in requires me using an authentication app on my phone to provide a pass code.

Parler requires me to use my authentication app
Parler wants an authentication token from my app to sign in.

What’s great about this is that I’m not actually signed in yet.

Three-factor Authentication

Using my authentication app to provide a token results in a token being texted to me

Parler showing a screen requesting an SMS code
Parler has now sent the user a text message with the code to login

A nice touch on this screen is that the next button is useless. As soon as I type in the code, I’m taken into Parler.

I should commend Parler for this. They’re the only social media site I know that requires a user to provide a password, defeat a Captcha, use an authentication app, and enter a code texted to them, just to see content.

Exploring Parler

The first thing I want to do when I create an account is set up notifications and edit my profile.

Debug Messages in the Console

It’s always a nice surprise to see my profile information right there in the console. I don’t see this as a major security risk, but it’s nice to see how they’re structuring their data.

My profile information is logged into the console; this seems to include ALL information
I’m not sure if I should feel offended that human is set to false

For those curious, here’s the full object that’s logged when I go to the Notifications page.

{
    accountColor: "#004b9d",
    badges: [],
    bio: "",
    blocked: false,
    blockedBy: false,
    caps: {
        canBan: false,
        canDarkPost: false,
        canModerate: false,
        canViewInfluence: false,
        deniesTips: false,
        isTippable: false,
        noSensitive: true,
        selfSensitive: false,
        sensitiveLockout: false
    },
    comments: "0",
    coverPhoto: null,
    dob: null,
    followed: false,
    followers: "0",
    following: "2",
    human: false,
    id: "b56b91d38fbb48438bd3c9b67b27f675",
    integration: false,
    joined: Mon Nov 09 2020 13:08:29 GMT-0600 (Central Standard Time),
    likes: "0",
    location: null,
    media: "0",
    muted: false,
    name: "Hvalthur",
    pendingFollow: false,
    pendingFollowers: "0",
    points: 0,
    posts: "1",
    private: false,
    profilePhoto: null,
    rss: false,
    score: "0",
    state: 1,
    subscribed: false,
    title: null,
    username: "hvalthur",
    verified: false,
    verifiedComments: false,
    _id: "b56b91d38fbb48438bd3c9b67b27f675"
}

I don’t see that id visible anywhere in the UI, but it looks like that’s my unique identifier for their APIs.

Checking out localStorage

I was curious what information the app was using, so I glanced in localStorage.

Parler LocalStorage
LocalStorage shows way more about me than the console ever did.

I can’t help but find myself a little annoyed with allowFindMeFromPhoneOrEmail: true. It’s pretty obvious what that means, which is why I didn’t want to have to give a phone number. Even more annoyingly, this is not a feature in the UI anywhere.

Even with setting my account to private and disabling every single option within Parler, this value did not update. It doesn’t appear that this is a control available to end-users.

Thankfully, when I put my phone number in the search box, I don’t find myself.

Searching in Parler

I decided to search for “test” to see if there were any test accounts. When I develop software, I often have test accounts in my staging and development environments. When we migrate to production (live) environments, we don’t bring forward the test accounts. But it’s nice to see they do things differently at Parler.

Parler test accounts, not all of which are private
These are the most interesting people on Parler, as far as I’m concerned

Following People

I didn’t really learn anything interesting about the test accounts, so, I decided to look at that “People to Follow” over there on the right. Parler has zero information on me; it’s an email address I created for this, and it is unfortunately my real phone number. So it’s neat how the folks it recommends I follow are Ted Cruz, Sean Hannity, and Mark Levin.

So, why not? I click on Ted Cruz’ profile. Boy are load times rough

Parler network requests.
78 requests, 105kb transferred, 22.2mb in resources, and DOMContentLoaded in 1.57s

The APIs are neat

I just want to point out really quick an API request:

https://api.parler.com/v1/post/creator?id=6466e8b8bf6d4d56be2cceba3ef2da18&limit=20

That value there is Ted Cruz’ id. So that’s sporty. Ted Cruz is 6466e8b8bf6d4d56be2cceba3ef2da18 , and just like me, he isn’t human.

That’s a relief. I was getting worried.

There’s a creator API and a profile API

I caught something strange in Ted Cruz’ creator API request.

Preview of the response to the API call
Users. Apparently there can be account creators, and account users.

There’s users in there. That’s weird. Why would that be the case?

For brevity, I’ve removed the “posts” from the JSON payload. But it looks like the same person who manages Ted Cruz’ account manages others

{
  "badge": 0,
  "badgeString": "0",
  "last": false,
  "next": "2020-10-09T01:38:15.789Z_145996972",
  "pendingFollowers": "0",
  "posts": [
  ],
  "users": [
    {
      "id": "6466e8b8bf6d4d56be2cceba3ef2da18",
      "bio": "Father of two, Heidi’s husband, fighter for liberty. Representing the great state of Texas in the U.S. Senate. www.tedcruz.org",
      "blocked": false,
      "followed": false,
      "human": false,
      "integration": false,
      "joined": "20200603213849",
      "muted": false,
      "name": "Ted Cruz",
      "rss": false,
      "private": false,
      "profilePhoto": "b912bbf214744dfc8ce10c8003b8de8e",
      "username": "TedCruz",
      "verified": true,
      "verifiedComments": false,
      "badges": [
        1
      ],
      "score": "635k",
      "interactions": 258
    },
    {
      "id": "4b8638eca2db4b17b3a7203e40ac8ce7",
      "bio": "TV Host Fox News Channel 9 PM EST. Nationally Syndicated Radio Host 3-6 PM EST | Hannity.com",
      "blocked": false,
      "coverPhoto": "b5017b332afe45cebe06c20d11bbb7e6",
      "followed": false,
      "human": true,
      "integration": false,
      "joined": "20200624142814",
      "muted": false,
      "name": "Sean Hannity",
      "rss": false,
      "private": false,
      "profilePhoto": "d5db6005647148a5a04881c5e9940f06",
      "username": "SeanHannity",
      "verified": true,
      "verifiedComments": false,
      "badges": [
        1,
        0
      ],
      "score": "6.1m",
      "interactions": 263
    },
    {
      "id": "9dea4d0e716345f5be054c6d2ea64b36",
      "bio": "Decorated Combat Veteran, NYT Best Selling Author, Father, Leader, Republican Candidate for the 17th Congressional District of Pennsylvania",
      "blocked": false,
      "coverPhoto": "61af2479e9a649619d96e2ae6cd11e0f",
      "followed": false,
      "human": true,
      "integration": false,
      "joined": "20200619114213",
      "muted": false,
      "name": "Sean Parnell",
      "rss": false,
      "private": false,
      "profilePhoto": "f7847cc070544f7c9c76d06757f1c1ae",
      "username": "SeanParnellUSA",
      "verified": true,
      "verifiedComments": false,
      "badges": [
        1,
        0
      ],
      "score": "4.2k",
      "interactions": 259
    },
    {
      "id": "7be81a1075b0a509adfa13054b87a60a",
      "bio": "Husband, father, cancer survivor, Congressman from the Great State of Texas. Freedom works. http://chiproy.com #TX21",
      "blocked": false,
      "coverPhoto": "3cb1c90789fc4fa698b0ff6d33bffb56",
      "followed": false,
      "human": false,
      "integration": false,
      "joined": "20181210032702",
      "muted": false,
      "name": "Chip Roy",
      "rss": false,
      "private": false,
      "profilePhoto": "7ce19dfcb5b64480a21252c843bd1eed",
      "username": "ChipRoyTX",
      "verified": true,
      "verifiedComments": false,
      "badges": [
        1
      ],
      "score": "8.9k",
      "interactions": 259
    }
  ]
}

I don’t know what this creator API does, but I do know that when I go to each of the profiles listed, I have a creator GET request that returns the same set of users.

I don’t feel like people should be using an app that exposes stuff like the fact that Sean Hannity and a senator from Texas have some sort of a connection.

Maybe it’s just me.

The Tracking

I’m fond of using Brave for social media sites because I like Brave’s built-in tracking protection and adblocking. Of course, I can enable these features in other browsers, but Brave has it all turned on by default.

Last week the site didn’t even work in Brave. It just didn’t. No sooner than I logged in was I logged out. It’s nice to know that this week the site is usable with adblockers and anti trackers.

the console of Brave when ad/privacy tracking is cranked up shows a lot of red
22 of 200 requests are blocked

It seems like doubleclick, an internet ad service owned by Google, is very popular on Parler.

Parler doesn’t seem to do anything to prevent embedded content from tracking its users

Brave reports it's blocked 8 different cros-site trackers
I’d like to give a big shoutout to Brave for blocking a lot of requests.

Worth noting is that while you see a lot of YouTube up there, I don’t see any YouTube videos visible above the fold.

Last week I was seeing trackers for Fox News content and I had to scroll 30 items down to see a posting from Fox News. It appears that embedded content is allowed to load its own trackers, regardless of being visible.

Far from protecting privacy, Parler seems to have no issue talking to other services that collect user data.

If I contrast this with Facebook, there’s a stark difference in the tracking:

Brave only blocks one item on facebook
Brave only has one item to block on Facebook
Facebook, having 12 of 351 requests blocked.

This doesn’t make Facebook less evil. But it does show that Facebook is more interested in keeping their data to themselves than parler

Parlez-vous Danger?

The code is poorly written and wrought with errors that I simply wouldn’t expect to see. I cannot fathom why Parler would have these coding issues outside of the fact that there are more serious concerns.

I am absolutely uncomfortable with how they handle passwords in their mobile app.

Their registration process is fickle with hidden requirements.

Their sign in process is the most difficult I’ve ever seen. Ever. And I’ve had to use government websites.

The API exposes somethings that, while not harmful, give me cause to suspect that some accounts have a relationship with each other that isn’t known to the public.

Add to this that the legalese is in PDF form and not even as content on the site, and that to be a verified user you must upload either a driver’s license or passport (really).

Parler wants a unique individual and a sole owner of an account. And the only way to do this is by sharing your personal identification
That includes your social security number

I would not trust this app to keep my phone number safe, let alone tax information.

Parler seems dangerous. And I’m not the only one who thinks so.


Categories:

1 Comment


  1. Thank you!
    I’ve blocked several Google domains/api’s on my phone. Unlike Twitter or other non-Google apps, parler won’t load the data/feed. It stays blanco, nothing works. This makes me wonder, what the hell is parler.

Comments are closed.