Peach App Token Reuse Flaw

TL;DR - Peach tokens never expire.

TL;DR: Peach tokens never expire, even after ‘logging out’.

Team Peach has responded below.


In the world of social media, the growing trend of security & privacy being an after thought is becoming more prevalent than ever. Every new social media app that comes out on the App store or the Play store it’s all the same, API’s get reversed, third party clients mimic the app and the end result? Database gets owned and credentials leaked over the internet, It’s almost like a tradition.

Following this trend, from 2013 to 2015 there was Snapchat, Yo, Yik Yak and even PuffChat. Now, we have another app that is being talked about on the web.

Peach is a simple app to keep up with your friends and to be yourself, as the site says. You update your status in your 'space’ and everyone can see your message. You can send 'magic words’ to your friends. For instance gif for an animated gif; or here to share your current location with your friends. I will not drone on further than that, so trying out Peach is an exercise for the reader.

There is something I did find odd about Peach when I looked deeper into the app, and its not that you cannot delete your account.

The Vulnerability

To demonstrate the vulnerability, We have three actors:

  • Mario
  • Princess Peach
  • Bowser (the attacker)

Let’s say that Princess Peach would like to send a message to Mario to meet her at the Mushroom Kingdom because she baked a big cake for all her friends.

(Story is read from left to right)

Now, take the scenario that Mario is talking to Princess Peach using the Peach app inside a café and that he is connected to a public wifi hotspot. The MitM attack (Man in the Middle Attack) is an attack which is nothing new and can be done by using existing tools.

Who’s to say that the café owners are currently MitM'ing Mario? Or that Mario is connected to a malicious network under disguise by an attacker inside the café?

Or even worse, Mario uses an insecure third-party app that communicates with Peach’s servers.

If either the above is true, then the attacker (Bowser) can see all the traffic coming from Mario. In this case with the Peach app, As soon as Mario either signs in or does any activity on the Peach app, all Bowser needs to sniff from Mario’s traffic is the Authorization Header.

GET /connections HTTP/1.1
Authorization: Bearer [token]
User-Agent: Peach App/1.0.11 (iPhone; iOS 8.0.2; Scale/2.00)
Accept: application/json 
Host: v1.peachapi.com
Accept-Encoding: gzip
Connection: keep-alive

Response: 200

{
  "data": {
    "connections": [
      {
        "id": "[redacted]",
        "name": "[redacted]",
        "displayName": "Princess Peach",
        "avatarSrc": "[redacted]",
        "isPublic": false,
        "youFollow": true,
        "followsYou": true,
        "posts": [
          {
            "id": "[redacted]",
            "message": [
              {
                "text": "Dear Mario I baked a 🎂 for you meet me at the Mushroom Kingdom. And make sure nobody sees this message except my friends and you Mario.",
                "type": "text"
              }
            ],
            "commentCount": 0,
            "likeCount": 1,
            "likedByMe": true,
            "isUnread": false,
            "createdTime": 1452533274,
            "updatedTime": 1452533274
          }
        ],
        "unreadPostCount": 0,
        "lastRead": 1452534813,
        "lastOnline": 1452817854
      }
    ],
    "inboundFriendRequests": [],
    "outboundFriendRequests": [],
    "requesterStream": {
      "id": "[redacted]",
      "name": "[redacted]",
      "displayName": "Mario",
      "avatarSrc": "[redacted]",
      "isPublic": false,
      "posts": [],
      "unreadPostCount": 0,
      "lastRead": 1452817970,
      "lastOnline": 1452818491
    }
  },
  "success": 1
}

The worse part of this of course, is that once either Mario or Princess Peach logs out, the token is not invalidated, thus making the attacker able to reuse this token in order to read, post or do pretty much anything on the app as long as they have the token.

With the scenario reversed and that Princess Peach logs out of the Peach app but is also being MitM’d by an attacker, the attacker can post messages acting as Princess Peach even though she has “logged out” of the app.

In this case Bowser can trick Mario by posting as Princess Peach using her authorization token.

POST /post HTTP/1.1
Authorization: Bearer [token]
User-Agent: Peach App/1.0.9 (iPhone; iOS 9.0.2; Scale/2.00)
Accept: application/json 
Host: v1.peachapi.com
Accept-Encoding: gzip
Connection: keep-alive
Content-Length: 185

Request Body:

{
    "message": [
        {
            "text": "Change of plan Mario, I need you to be safe, Go to the woods. Toad will meet you there.", 
            "type": "text"
        }
    ]
}

Response: 200 (Princess Peach is logged out)

{
  "data": {
    "id": "[redacted]",
    "message": [
      {
        "text": "Change of plan Mario, I need you to be safe, Go to the woods. Toad will meet you there.",
        "type": "text"
      }
    ],
    "commentCount": 0,
    "likeCount": 0,
    "likedByMe": false,
    "isUnread": false
  },
  "success": 1
}

Mario would then go into the woods and unknowingly confront Bowser with no idea that Bowser was able to read and post messages as Princess Peach.

Steps to recreate this vulnerability:

  1. Login or signup.
  2. Token is given1. (Save this token)
  3. Logout of the app.
  4. Do any authenticated methods with saved token.
  5. All authenticated responses should return 200.

The only way to really logout, is to log back in again, which then the token truly expires.

But following these steps above, I have reused a Peach authorization token whilst still being 'logged out’ for over a week. This can be fixed by just invalidating tokens immediately when logging out the app. Or generating tokens based on some timestamp with a combination of other values and making the server check the token to prevent reusable tokens. I’ve setup a gist for those who are interested on the flaw.

Since this vulnerability above applies to dedicated attackers, You would find in a matter of months third party apps of the Peach app. And that the users authorization token does not expire when logging out. This would give more than enough time for a sophisticated attacker to snoop and post messages in the app.

There has already been controversy over Peach, and especially this post. While I disagree with the web stance in this Medium post, this line summarises the app the best.

Peach is a fruity meta-data honeypot.

Not very peachy for users if you ask me, Since we all know who’s going to take advantage of this.


UPDATE2:

Team Peach got back to my email I sent two weeks ago.

Hi Wesley,

Thanks for writing in to us here. First of all, we apologize for how long it took us to get back to you. We’ve gotten a lot of requests for help through this email address and we’re a small team, so we’ve been working very hard to catch up and respond to things in as timely a manner as possible.

We’re aware of the token invalidation issue and will address it in an upcoming release.

We also realize the need for a better way to get in touch with security-related issues, so we’ll be setting up a more direct line of communication that will ensure we don’t miss important stuff like this in the future.

Thanks again for reaching out.

- Team Peach

EDIT: The vulnerability has been fixed and invalidates the token once you log out.


  1. Since Peach is developed by Byte Inc., Peach’s auth API is similar to Byte’s API. I have no idea whether they intended for tokens to live forever in Peach even when logging out, but that shouldn’t happen. 

  2. I have tried to contact Peach first regarding this flaw two weeks ago, before disclosing this issue publicly. 

Written by on