DeepAI
Log In Sign Up

Analyzing the Security of the Business Collaboration Platform App Model

03/08/2022
by   Yunang Chen, et al.
0

Business Collaboration Platforms like Microsoft Teams and Slack enable teamwork by supporting text chatting and third-party resource integration. A user can access online file storage, make video calls, and manage a code repository, all from within the platform, thus making them a hub for sensitive communication and resources. The key enabler for these productivity features is a third-party application model. We contribute an experimental security analysis of this model and the third-party apps. Performing this analysis is challenging because commercial platforms and their apps are closed-source systems. Our analysis methodology is to systematically investigate different types of interactions possible between apps and users. We discover that the access control model in these systems violates two fundamental security principles: least privilege and complete mediation. These violations enable a malicious app to exploit the confidentiality and integrity of user messages and third-party resources connected to the platform. We construct proof-of-concept attacks that can: (1) eavesdrop on user messages without having permission to read those messages; (2) launch fake video calls; (3) automatically merge code into repositories without user approval or involvement. Finally, we provide an analysis of countermeasures that systems like Slack and Microsoft Teams can adopt today.

READ FULL TEXT VIEW PDF

page 1

page 2

page 3

page 4

11/05/2021

Security and Privacy Perceptions of Third-Party Application Access for Google Accounts (Extended Version)

Online services like Google provide a variety of application programming...
10/18/2022

Comparison of Popular Video Conferencing Apps Using Client-side Measurements on Different Backhaul Networks

Video conferencing platforms have been appropriated during the COVID-19 ...
09/13/2021

Forensics for Microsoft Teams

Microsoft Teams is a collaboration and communication platform developed ...
08/06/2018

Cross-App Interference Threats in Smart Homes: Categorization, Detection and Handling

A number of Internet of Things (IoTs) platforms have emerged to enable v...
08/06/2018

Cross-App Threats in Smart Homes: Categorization, Detection and Handling

A number of Internet of Things (IoTs) platforms have emerged to enable v...
06/25/2019

Large-Scale Analysis of Pop-Up Scam on Typosquatting URLs

Today, many different types of scams can be found on the internet. Onlin...
04/02/2020

Typosquatting for Fun and Profit: Cross-Country Analysis of Pop-Up Scam

Today, many different types of scams can be found on the internet. Onlin...

1 Introduction

Business Collaboration Platforms (BCPs) like Slack and Microsoft Teams are indispensable collaboration and productivity tools. Beyond multi-user chat features, BCPs enhance productivity by allowing users to integrate third-party resources. For example, users can make video calls with Zoom, store files on DropBox, chat with customers, and manage code repositories, all from within the BCP. A vibrant third-party app ecosystem allows many such integrations. Thus, BCPs not only host private communications between users but also serve as a hub for all their sensitive resources from third-party systems. As such, it is vital to understand the security and privacy properties of this emerging class of distributed multi-user collaboration platforms.

We contribute to understanding the security of BCPs by performing an experimental analysis of the third-party app model. We focus on the app model because it allows BCPs to access sensitive data from third-party systems. Although there is work on understanding the operational security issues of BCPs (e.g., web security flaws [slack-android-password, slack-feature-withdraw]), to our knowledge, no work has examined the third-party app model. We focus our work on Slack and Microsoft Teams — two of the most widely-used BCPs with mature app ecosystems [bcp-survey]. Furthermore, these two systems share design-level commonalities and potentially with other BCPs. Thus, any security findings are potentially broadly applicable to BCP design.

Performing the security analysis of Slack and Microsoft Teams is challenging because these systems, including their apps, are closed-source. Specifically, apps themselves are remotely-hosted web services whose endpoints are only known to the BCP. This precludes classical analysis techniques such as source code and binary analysis or API endpoint testing. As an external party, we can only interact with apps the way a human user would — through the BCP itself. Therefore, we focus our analysis efforts on the interactions between apps and users, such as sending messages and reacting to them. To conduct the analysis methodically, we first systematize an access control model that describes the approaches taken by Slack and Teams using a uniform vocabulary. We then explore how an attacker can violate the access control model by experimentally studying each interaction method.

We find that the BCP app model uses a two-level access control system consisting of the OAuth protocol and a runtime policy enforcer. Abstractly, a BCP app requests OAuth tokens to interact with categories of resources. For example, an app might request an OAuth token to read chat messages. However, this token does not entirely dictate what specific messages the app can read. Thus, the user has to specify the fine-grained access control policy at runtime. Once the user installs an app and permits it to read chat messages, the user can additionally specify that the app may read messages from specific channels (e.g., the “usenix-security-submission” channel). Whenever an app issues an API request to the BCP server to read a chat message from a specific channel, the access control system first verifies the OAuth token and then executes a runtime policy check to verify that the app is authorized to read from that specific channel.

By examining each interaction method between BCP apps and users, we establish that this two-level access control system does not adequately confine third-party application behavior. Concretely, we have discovered that the BCP access control system violates two standard security principles: (1) least privilege and (2) complete mediation[saltzer1975protection]. This allows malicious apps to escalate their privilege and violate the confidentiality and integrity of private chat messages and third-party resources connected to BCPs. To demonstrate the concrete harms posed to end-users, we introduce three attack classes for BCPs along with attack prototypes: (1) App-to-app delegation attacks, (2) User-to-app confusion attacks, and (3) App-to-user confidentiality violations. We briefly overview these attack classes.

(1) App-to-App Delegation Attacks (Section 4): BCPs support apps that can interact with each other for productivity reasons, independently of human involvement. To support such meaningful interactions, the BCP access control model allows apps to act on behalf of a user. We show how malicious apps can exploit this to violate the confidentiality and integrity of resources that victim apps manage. Our proof-of-concept attacks include sending arbitrary emails on a victim’s behalf, merging code pull requests, and retweeting any links using the victim’s account.

(2) User-to-App Confusion Attacks (Section 5): BCP apps can customize how users interact with them and with workspace features. For example, an app can introduce new ‘slash commands’ into a workspace or manipulate how URLs get unfurled. For example, one can start a Zoom video call by entering /zoom on the Slack UI. We show how a second malicious app can interfere when a user attempts to interact with a benign app, a problem similar to DNS domain squatting and voice assistant skill squatting [kumar2018skill, zhang2019dangerous].

(3) App-to-User Confidentiality Violations (Section 6): BCP apps interact with users by participating in any approved channels or conversations, where a human user explicitly ‘adds’ the app as a member. BCPs implement runtime policy checks to enforce security policies in these situations. We show how a malicious app can exploit gaps between OAuth and these runtime mechanisms to leak private messages it does not have permission to view.

Contributions.

  • We contribute an experimental security analysis of the app model in two widely-used BCPs — Microsoft Teams and Slack. To guide the analysis, we derive a common access control model for these two BCPs and then experimentally examine each interaction method between apps and users. We find that the access control model violates the principle of least privilege and complete mediation.

  • We introduce three new attack classes that leverage this fundamental shortcoming of the access control model: (1) App-to-app delegation attacks, (2) User-to-app confusion attacks, and (3) App-to-user confidentiality violations. We constructed proof-of-concept attacks for these classes to achieve effects such as (1) sending arbitrary emails on behalf of victims, (2) merging code requests, (3) launching fake video calls with loose security settings, and (4) stealing private messages without having the appropriate permission. In certain cases, we also demonstrate how an attacker can maintain their presence even after app uninstallation.

  • We build tools to scrape app manifest data to estimate the potential for such attacks to occur. Of the 2,460 Slack apps we analyze, we find that 1,493 (61%) are potentially vulnerable to delegation attacks, and 563 (23%) request the necessary permissions to carry out these attacks. Of the 1,304 Microsoft Teams apps we analyze, we find that 427 (33%) are vulnerable to delegation attacks. We also find that 1,266 (51%) Slack apps use slash commands; these apps are potentially vulnerable to both the user-to-app attacks and capable of performing user-to-app attacks.

Finally, we propose a set of countermeasures that BCPs like Microsoft Teams and Slack can adopt today as a temporary solution to mitigate the attacks (Section 7). For example, enforcing user confirmation before every app-to-app interaction and command name collision can fix most issues, but this is undoubtedly a user-hostile solution. As a result, solutions with acceptable security and usability trade-offs necessitate rethinking the app and access control model in multi-user communication platforms.

Ethics and Disclosure.

We conducted all experiments inside private workspaces with the authors as the only members. We did not exercise cross-workspace features; thus, our investigations did not influence other workspaces. We did not distribute or submit our test malicious apps to any BCP app directory, so our attack did not affect BCP users other than the authors’ testing accounts. We have ethically disclosed all vulnerabilities we found within Slack, which have confirmed their existence. But due to Slack’s view of the workspace as a trusted environment and the assumption that the workspace administrator will correctly manage app security, Slack has not taken action to address these issues. We are in the process of disclosing the Microsoft Teams vulnerabilities.

Figure 1: Overview of BCP’s ecosystem: A BCP user interacts with their BCP clients to communicate with the BCP server. BCP apps, which are maintained as separate web services by different third-party developers, communicate with BCP server via API calls and event notifications. A user has to install and authorize an app before accessing its functionalities.

2 Business Collaboration Platforms

Business Collaboration Platforms (BCPs) provide chatrooms that facilitate online collaboration among a group of people, who usually belong to the same workspace, such as a project team or a research group. In BCPs, one can create a virtual workspace to host all conversations for a group. It supports discussions among the users who joined the workspace through various conversation channels. Users can open a new channel which can be public — any user can join — or private — only those who are invited can join. Users can also send direct messages to any other user or group of users in the workspace. To use a BCP, a human user interacts with their BCP client on their computer or mobile device, which then communicates with the backend servers of the BCP through various APIs. The backend server then responds to the client, updating what the user sees. We illustrate this communications framework in Figure 1.

In this paper, we focus on Microsoft Teams and Slack, due to their popularity and mature third-party app ecosystem. A recent survey of 900 businesses [bcp-survey] has shown that they are the top two most popular BCPs 111The original survey listed Skype for Business as the top spot, but it has since been discontinued and replaced by Microsoft Teams.  and are the only ones that provide a list of officially supported third-party apps.

2.1 BCP App

Beyond basic chatting features, modern BCPs usually offer many third-party integrations, commonly known as apps, which are cloud services providing additional productivity-enhancing functionalities in the workspace, often connecting user’s data from other services (such as email or online storage) to the workspace. These BCP apps exist on cloud servers not maintained by the BCP. These app backends communicate with the BCP servers by subscribing to event notification APIs and reacting when information about a new event is received, as depicted in Figure 1. Generally, a BCP app can simultaneously act in three roles: workspace feature provider, interactive bot, and user delegate.

Workspace feature provider.

The app may enhance a workspace’s existing features. For example, an app made by Twitter can customize the default link unfurling feature to preview tweets linked in messages automatically. The app may also provide user-invokable actions through slash commands. As another example, Google’s Slack app [gcal] shows a user’s recent schedule when the user types /gcal.

Interactive bot.

The app can present itself in the workplace as a bot user and interact with other users the same way as a typical human user. The user can, for example, chat with the app’s bot user directly, invite it to a channel, or share files with it. Due to these convenient features, this role has become the app’s primary communication interface with its users.

User delegate.

If permitted, the app may also perform actions on behalf of users. This role is particularly beneficial for enhancing productivity. For example, when users visit Dropbox’s web page and wish to share files with others in their Slack workspace, they must divert their attention back and forth between Dropbox and Slack. In contrast, with the delegation ability, Dropbox enables the user to click a button without leaving the webpage and let Dropbox’s Slack app [dropbox] share files on their behalf. As a result, the shared files appear to have been sent directly from the user.

2.2 Life Cycle of BCP Apps

A BCP app generally goes through the following stages in its life cycle: deployment, publication, installation, per-user authorization, in-use, and removal.

Registration.

To enable the various functionalities in Section 2.1, an app needs to query different web APIs or subscribe to different event notification APIs on the BCP’s backend server, which in turn usually require different permissions. The app developer must register the app in the corresponding BCP’s developer portal by specifying its backend URL, required permissions, and subscribed events. An example of such information is shown in Appendix C. We note that, in both Microsoft Teams and Slack, a third-party app developer does not need to submit any of the app’s codebase, as all their apps are hosted purely inside the developer’s server. No client-side code is accessible by Slack, Microsoft, or the end-users.

Publication.

After the app has been successfully deployed, the developer can choose to either distribute the app through its advertising channels or submit the app to the official app directory [slack-app-directory, teams-appsource]. For the second option, the app must follow submission guidelines, such as enforcing TLS connections and providing security compliance information. However, as both Microsoft Teams and Slack apps are closed-source and their codes are not submitted for examination, it is difficult to enforce these guidelines strictly.

Installation.

In Microsoft Teams and Slack, any user222Although Microsoft Teams and Slack provide a setting for the administrators of a workspace to limit which users are allowed to install apps and which apps can be installed, the default for both BCPs is that any user can install any apps from any source.  can install an app to the workspace. During installation, a permission request page will be presented to the user, detailing what the app can do, as illustrated in Appendix C. The user then either accepts all permissions or rejects all permissions. This installation is relatively invisible to other users; they are not notified when a new app is installed, and the list of installed apps is often hidden in secondary menus in the UI.

Per-User Authorization.

If an app wants to act as the delegate of some users in the workspace, it may initiate a separate permission request to each user, usually by sending the request link via the app’s bot user. Once the user authorizes it, the app gains permission to act on behalf of that user.

In-use and Removal.

After the app is installed and authorized, it may additionally ask for integration with the user’s account on third-party services. For example, Google’s Slack app requests the user to authorize access to their Google account. BCPs do not manage the communications between BCP apps and third-party services.

Re-Installation.

If the app developer updates an app by requesting a different set of permissions, the user has to reinstall the app and go through the permission prompts as before. Finally, when a user uninstalls an app, it loses access to all BCP-managed resources. However, there is no guarantee that the app properly disconnects itself from third-party services.

2.3 Security and Privacy Concerns

The widespread usage of BCPs in remote work environments implies that a lot of sensitive information passes through it. With the potential ability to access such information, BCP apps lead to security and privacy concerns. Moreover, some of the design choices that we described earlier exacerbate such concerns: (1) all-or-nothing permissions that disallow selective toggling of permissions; (2) imperceptible installation that reduces the chances for users to notice what kinds of apps are installed and also prevents any workspace-wide consent mechanisms; (3) pure server-side implementation that prevents BCPs or other entities from inspecting the app’s behavior through traditional tools like static or dynamic analysis. This also allows the app to change its behavior at will.

3 Analysis of App Permission Model in BCP

We study the permission systems in Microsoft Teams and Slack to identify their similarities and differences to understand the potential security design issues and systematically perform experimental security analysis. We focus on these two BCPs since they are the top two most popular ones [bcp-survey] and have mature app ecosystems. We also introduce a practical threat model and the methodology we will use to analyze the third-party apps in these two BCPs.

3.1 App Permission System

Figure 2: An example of Slack permission system. We show three example scopes that App 1 may acquire. The arrow lines indicate that a token can be used to query all resource instances of the types allowed by the token’s scope. However, Slack performs additional runtime policy checks (indicated by the red crosses) to determine which of these instances can actually be accessed.

At a high level, Microsoft Teams and Slack have designed their access control model based on a similar permission-based system. This permission system controls whether or not an app has access to various resources in a workspace. An app must first declare a set of permission scopes it requires, with each scope representing the permission to read or write a type of resource. However, such scopes are statically defined by the BCPs and thus do not allow more dynamic and fine-grained access control over the specific instances under a single type of resource. To solve this problem, the BCP permission system includes runtime policies that are usually user-configurable. For example, to read a message in a private channel, a Slack app not only needs the groups:history scope but also has to be added to the channel’s member list by some user, as shown in Fig. 2. We now examine this two-level permission system in detail and show that it has security design issues that can violate the least privilege principle and cause privilege escalation.

Level 1: static permission scopes.

An app needs to acquire several different permission scopes to perform all of its functionality. Each scope represents the permission to read or write a type of resource in a workspace, such as channel messages or shared files.

To install the app, the user must accept all of its requested permissions; neither BCPs provide options to selectively toggle them. Slack’s permission scopes are implemented as standard OAuth permission scopes. Slack provides two types of scopes for its apps: bot token scope, which allows an app to provide workspace features or act as a bot user, and user token scope, which allows an app to perform actions on behalf of an authorized user. For example, the chat:write bot token scope permits the app to send messages with its bot user as the author, while the chat:write user token scope allows sending messages as the user. Microsoft Teams follows a similar design: a set of core app capabilities that must be declared in an app’s manifest is the equivalent of Slack’s bot token scope, while Microsoft Graph API’s OAuth permission scopes are equivalent to Slack’s user token scope. The difference is that only the first type of scope is shown during the app installation; the second type can only be acquired by initiating a separate permission request to the user after installation.

These scopes are static, in the sense that they are predefined based on how BCPs categorize the workspace resources, and therefore might not align with the user’s desired security policies, which can vary by workspaces and evolve. To compensate for the static nature of scopes, both BCPs impose a second level of permission checking.

Level 2: runtime policy checks.

Microsoft Teams and Slack implement runtime policies to determine which instances in a resource type an app can access based on various conditions. Users can usually control these conditions to express their desired security policies. For example, users can have more fine-grained control of which messages in private channels an app (that has the prerequisite permission scope) can view: in Slack, they can invite the app to a specific channel, indicating that the app can view all messages inside this channel; in Microsoft Teams, they can @-mention the app in the messages that they wish the app to read. In this way, runtime monitors grant users some flexibility to dynamically adjust the set of resources of an app can access.

Attack Slack Teams Prerequisites Attack Effect Surface
Delegation Permission to perform actions (primarily read & write direct messages) on victim’s behalf. Invoke actions in victim’s other apps to manipulate data in victim’s connected third-party accounts.
– post app removal * App has acquired the above permission before removal. Incur delegation attack after the app is removed. *In Slack, this can only be achieved via pre-scheduled messages.
Interaction hijacking
– slash command Permission to add slash commands. Hijack any slash command in the workspace stealthily, affecting everyone using the command.
– link unfurl Permission to provide customized unfurling. Replace any other app’s unfurled content stealthily, affecting the links sent by victim.
Message extraction
– via link unfurl Permission to read & write direct messages on victim’s behalf. Read messages in any private channel where victim is a member of.
– via pin/star/reaction Permission to pin, star, or react to messages on victim’s behalf. Read victim’s direct messages and messages in any private channel where victim is a member of.
Figure 3: Summary of proof-of-concept attacks and their requirements and threats. Per our threat model, the victim is a user who has authorized all the app’s requested permissions.
Security design issues.

Despite the two-level checking, we uncover two design issues in the BCP permission system that violate basic security principles.

  1. The runtime policies are ad-hoc and incomplete. As a result, not all user security policies can be correctly expressed. We find that not only do they differ in each BCP, but even in the same BCP there are often inconsistencies between the runtime policies of similar types of resources. For example, Slack treats public channel messages and direct messages as two separate types of resources; however, it only imposes a policy on the former by checking whether the app is invited to the channel, but provides no mechanism to limit which user the app can send direct messages to. The incompleteness of runtime policies leads to coarse-grained access control, violating the principle of least privilege.

  2. The ownership or provenance of some resources is not properly tracked or enforced. This frequently happens when a user delegates an app to create resources. For example, Microsoft Teams does not differentiate between messages sent by a real user and a delegated app. In addition, due to the multi-user multi-app nature of BCP workspace, the ownership of a resource can sometimes be hard to define correctly. When the ownership or provenance is absent, or the system assumes the wrong one, the principle of complete mediation can be violated and potentially lead to privilege escalation.

Although it is possible to build a BCP permission system to fix the above problems by allowing the user to specify the security policy for every instance of resources and tracking every resource’s provenance, we will see in Sections 4 to 5 that such an ideal system is hard to design and often requires sacrificing usability.

3.2 Threat Model

Based on our analysis of the permission model above, we derive a threat model for BCP apps. We assume that the attacker has targeted a BCP workspace containing a number of users and already-installed apps. The attacker has also tricked one of the users (referred to as the victim) into installing the attacker-controlled malicious app, i.e., the victim has granted all the permission scopes requested by the malicious app. This is reasonable because, by default any user in the workspace is allowed to install any app from any source. In our threat model, the attacker can be either an outsider or a curious user inside the workspace who wants to gain the information they cannot access. For example, an admin can recommend everyone in the organization to install a malicious app (disguised as an innocent management app), hoping to steal chat logs from private channels they are not invited.

In addition, we assume that the BCP’s clients and its backend server are secure and do not collude with the attacker — attacking such infrastructure is an orthogonal research direction. Therefore, the capacity of the malicious app is limited to the functionality defined by the BCP’s API. We also assume that the other apps installed in the workspace are benign and secure, which means they follow the security guidelines [slack-guidelines, teams-guidelines] and do not contain any implementation-level flaws such as exposing their tokens directly.

3.3 Security Analysis Methodology

We perform experimental security analysis on Microsoft Teams and Slack to study how a malicious app (defined by our threat model) can exploit the two security design issues in these two BCPs’ permission systems. Specifically, we examine every type of interaction the malicious app can have with other entities in the workspace and check whether such interaction involves resources that have incomplete runtime policy or suffer from improper ownership tracking. If so, we explore attacks causing security-critical consequences. We detail our findings in Sections 4 to 6. For each attack, we analyze how it stems from the security design issues in the permission system, how it violates the security principles, and how it jeopardizes the workspace’s integrity or confidentiality guarantees expected by the user. We summarize the prerequisites and effect surface for each attack in Fig. 3.

In addition, we also build a tool to extract the information of the apps from the two BCPs’ official app catalog. We examine all 2,460 Slack apps from the Slack App Directory [slack-app-directory] on April 7, 2021 and all 1,304 Microsoft Teams apps from the Microsoft Teams App Store [teams-appsource] on November 17, 2021. For each attack, we investigate how many of them are capable of executing the attack (if they have the necessary permissions) or may potentially fall prey to the attack (if they hold resources that can be exploited).

4 App-to-App Delegation Attacks

One of the core functionalities provided by BCP apps is to chat with users through their bot users interactively. However, a BCP app can also send and receive messages on the user’s behalf and, therefore, chat with other app bot users. In this section, we present the delegation attack, where one malicious app abuses such app-app interactions and causes security-critical consequences (Sections 4.1 to 4.2). We then show that the source of this vulnerability roots in the fundamental design issues of current BCP permission systems (Section 4.3) — a violation of least privilege.

4.1 App-to-App Interactions

Both Microsoft Teams and Slack allow their apps to present themselves in a workspace as bot users so that human users can send direct messages to these bot users to instruct them to perform certain tasks. This functionality is commonly used to let users manage their data in other online services, such as emails and file storage, without leaving the BCP.

At the same time, these two BCPs also allow apps to perform certain actions in the workspace on behalf of the user. If an app sends a message in this way, this message will appear as if the user sent it. Such delegation can be useful to enhance productivity. For example, Dropbox’s BCP app [dropbox] utilizes it to share files in channels on behalf of the user. In Slack, this can be achieved if the app has acquired the chat:write user token scope in its OAuth permission request with the user; in Microsoft Teams, although none of its standard app capabilities grants permissions to delegate, one can still employ the advanced Microsoft Graph API and ask for the Chat.ReadWrite scope.

By combining the above two functionalities, we can enable app-to-app interactions in BCPs: one app that has the delegated permission to send user’s messages can interact with another app’s bot user. Such interaction can be beneficial; for example, Dokkio’s Slack app [dokkio] can organize files sent by Dropbox’s app into a coherent page for the workspace and tag them as shared by different users. Slack regards app-app interaction as an important feature with growing demand [goodman-wilson_2016]. However, allowing one app to communicate with other app’s bot users has severe security implications. When the former app turns malicious, it can potentially invoke actions from the latter app, and such actions might affect data in the user’s connected third-party account. We refer to attacks exploiting this vulnerability as delegation attacks.

We note app-app interactions can happen in other ways. Although receiving a message from the user is the most intuitive trigger event to indicate when the app should perform its actions, an app may subscribe to other triggers as well, like when a file is shared (see Appendix A) or an emoji reaction is added. As such, apps with delegated permissions to produce these triggers can also launch potential delegation attacks.

Post-removal interactions.

Even after an app’s removal from the workspace, it can have residual effects that cause delegation attacks. Slack provides its apps the ability to schedule a message to be sent at a future time (using the same chat:write user token scope). We find that if the app is removed before the message’s scheduled time, its message will still be sent, potentially invoking actions from other apps. In Microsoft Teams, although there is no scheduling feature, this issue is more severe due to its two separate permission schemes. Upon uninstallation, only the app’s core capabilities declared in the manifest will be removed, while its delegation permissions acquired through the Graph API remain entirely intact. Therefore, uninstalling a Teams app has no effects on the app’s delegation permissions, and the app can continue to execute the attack as before.

4.2 Delegation Attack

We now focus on the delegation attack targeting both Microsoft Teams apps and Slack apps. We have built a tool that crawls the information of a targeted app from the two BCPs’ official app directories and analyzes which trigger events the app is subscribing to. In the case of Microsoft Teams, we can also extract all message keywords that trigger the targeted app’s actions. We set up a workspace as defined per our threat model. The attacker app has acquired the appropriate delegated permission from a victim user who has also installed the targeted apps with connection to third-party services. The attacker app produces the trigger events, and we observe whether the targeted app will be tricked into performing the actions. Here we examine several examples where security-critical actions have been triggered. A more comprehensive survey of all official apps is in the next subsection.

 Send emails on victim’s behalf.

MailClark’s Slack app  [mailclark] allows sending emails directly from Slack to include non-Slack users in a Slack conversation. MailClark provides a unique email address for a list of non-Slack guests in a channel configured by the user. The email account and the recipients are only accessible to MailClark and the user. The attacker app induces MailClark to send any emails of the attacker’s choice to recipients configured by the user. Specifically, the malicious app launches this attack by sending messages to the channel as the user. During this procedure, MailClark will automatically send the attacker’s message as an email to all recipients and indicate the author as the user.

 Chat with victim’s website visitors.

Chatlio [chatlio] is a service that lets developers add live chat functionality to their websites. It also provides an accompanying Slack app that automatically forwards any messages of the website visitors to a Slack channel and vice versa. Therefore, website owners can chat with any visitors in real-time through Slack. Unfortunately, this convenient feature makes Chatlio’s app a victim of delegation attacks. Our attacker app can post messages directly into the channels used by Chatlio to chat with website visitors and thus launch further phishing attacks or harvest sensitive user info, as it now appears like a trustworthy entity to the visitors.

 Merge pull requests in victim’s code repository.

BitBucket’s Microsoft Teams app [bitbucket] will merge a given pull request if it receives a message starting with the keyword merge. It will then ask for confirmation, at which point the attacker app can reply with the text yes to approve the merge. The attacker app may additionally use the list keyword to ask BitBucket’s app to display all pull requests in the victim user’s connected repos or the find keyword to locate a specific pull request. If the repo is public, the attacker can even submit and merge its own pull request, leading to code poisoning or backdoor injection.

 Execute victim’s automation flows.

Microsoft Power Automate has a Teams app [powerautomate] that, upon receiving the message Run flow [id], will execute the specified automation flow in the user’s account. These flows can perform various actions in a wide range of services connected to Power Automate. The app also accepts messages like List flows and Describe flow [id] that can be utilized by the attacker to learn more about the user’s flows and conduct more targeted attacks.

 Retweet on victim’s behalf.

Ziri [ziri] is a Slack app that helps users interact with tweets in a non-disruptive way. It connects to the user’s Twitter account and requests permission to retweet. After that, whenever a Twitter link is shared in Slack, and the user adds a Twitter emoji reaction to that message, Ziri will automatically retweet the shared Twitter on the user’s behalf. The attacker app can thus send a message containing a link to a chosen tweet (that includes harmful information) and add an emoji to the message on behalf of the user. After that, Ziri will successfully detect the tweet link and retweet it using the victim user’s account. Such uncontrolled tweets can have detrimental effects, especially when the connected account is high profile, such as the organization’s official twitter.

Summary.

The first four attacks rely on message events to trigger the actions in the targeted app, while the last one relies on a reaction event. We note that once the attacker and targeted apps are installed and properly authorized, the attacks do not require additional user inputs and can happen anytime, even when the user is not logged into its BCP client. In addition, the attacker app can delete the traces of trigger events once the attack is finished, making it even sneakier (since in both BCPs, the permission to send messages or add emoji reactions also grants for free the permission to delete them).

4.3 Analysis of Root Cause and
Potentially Prevalence

The delegation attack is possible because both BCPs’ permission systems violate the principle of least privilege. Currently, the permission to send delegated messages is governed by Slack’s chat:write or Microsoft Teams’s Chat:ReadWrite scope; however, these two scopes allow the app to send messages to any place that the user has access to, be it a public channel, direct message with other users, or direct message with other app’s bot user, and neither BCPs provide additional runtime policies to limit the destinations. Therefore, even if a simple app only wants to send delegated messages to other users for sharing or notification purposes, it must request these two scopes. Thus, it unavoidably gains the ability to launch delegation attacks.

We note that Microsoft Teams and Slack do have workarounds that can prevent the delegation attack. These BCPs allow apps to interact with users through alternative ways, such as slash commands and interactive UI windows. This prevents other apps from interfering since the system does not allow an app to send slash commands or click buttons in a UI. Slack in particular also tracks which messages are sent by a real user through the Slack client and which are sent by a delegated app, so that the app receiving the messages can choose whether to respond or not. However, both of these mechanisms require the receiving app’s developer to decide which actions can be triggered by other apps, but the current design of BCP permission system does not provide any ways for it to learn whether the delegated messages align with the user’s actual intent, making it impossible to arrive at the correct decision.

A principled fix would trade-off functionality or usability. Entirely preventing app-app interaction would hurt the functionality of the BCP, as there are legitimate and beneficial use cases of app-app interaction showcased in Section 4.1. A more reasonable approach would be allowing each user to specify their own intent, i.e., which app is allowed to talk to which app for every possible pair of installed apps, so that the BCP permission system can make informed runtime checks. While this approach should solve the problem, it will quickly become unusable as more apps are installed.

App’s residual permissions after removal.

The reason why a removed app can still keep some residual permission differs in two BCPs. Slack’s permission system violates the principle of complete mediation by failing to check that the proper provenance of the scheduled message, which is the removed app, should have no permissions at the time when the message is sent. Whereas in Microsoft Teams, it is the result of two separate permission systems: only the app’s core capabilities are associated with Teams, while the Graph API’s permissions are tied to the user’s Microsoft Account (outside the permission system of Teams). Therefore, when the app is uninstalled in Teams, only the former is revoked while the latter is not affected. We note this issue is not Teams-specific, but also exists in other systems when permissions are managed by different trust domains [yuan2020shattered].

Potential Prevalence.

We report the number of apps capable of executing the delegation attack and that are vulnerable to the attack. For Microsoft Teams, we find vulnerable apps by counting apps that use bot commands capability, as these apps will accept text input from the user (or a delegated app) to perform various actions. We observe that 427 (33%) of Teams apps use bot commands, implying that they are vulnerable to a delegation attack. However, Teams apps do not list whether they will request any delegated permission since it is acquired through a separate system. For Slack, we find 563 Slack apps (23%) request at least one ‘write’ user scope, allowing them to interact with other apps adversarially, while 1,493 Slack apps (61%) request at least one ‘read’ scope, implying that they are subscribing to events in the workspace and thus can be potentially affected by the attack. We note that the measurements for Slack’s vulnerable apps are the worst-case estimation. Since these apps are third-party web services with hidden endpoints, it is impossible to learn the app’s behavior directly. Furthermore, most apps only perform actions after a third-party account is connected, preventing us from fully automating the evaluation of apps on a large scale. Thus we may miscount apps that (1) have already employed a countermeasure by blindly rejecting delegated messages, (2) subscribe the certain events but never trigger their security-critical actions based on these events.

5 User-to-App Interaction Hijacking

BCPs provide various features that serve as entry points for users to interact with apps. Examples of these features includes ‘@’-mention, slash command, and link unfurling (see Section 2.1). In this section, we discuss how a malicious app exploits such interactions between the user and other apps in the workspace. Specifically, we find two different ways that this can happen: the malicious app can hijack other app’s registered slash commands (Section 5.1), and replace another app’s unfurled link content (Section 5.2). In particular, we note that both Microsoft Teams and Slack allow apps to customize their appearance (e.g., name, icon, and description) without restriction. A malicious app can thus completely mimic the appearance of another app333This may not be the case for apps published in the BCP official catalog, as per their security guidelines. Although a Slack app can still requests chat:write.customize to send messages with customized appearance.to exploit the above interactions more stealthily. Finally, we analyze the root cause and potential prevalence of these attacks.

5.1 Slash Command Hijacking

In Slack’s user-to-app interactions, all apps’ slash commands share a single namespace, creating the potential for name collisions. A malicious app can hijack another app’s commands, responding to any user that tries to launch the hijacked command in the victim app’s stead. Two specific design flaws enable this attack. First, Slack only invokes the most recently installed app when multiple apps in a workspace have registered the same command. Second, both creating and renaming commands are silent and do not trigger a notification or permission prompt in Slack. As a result, one can hijack a targeted command in two ways: (1) create a new command with the same name as the targeted one; (2) rename an existing command to the targeted one. In other words, the commands scope becomes over-privileged as it implicitly allows an app to take over any command within a workspace (by exploiting the name collision). However, Slack does not recognize this design issue as a security-critical problem444Slack acknowledged this problem in its document, but only suggests developers to “avoid terms that are … likely to be duplicated,” and not to make the command “too complicated for users to easily remember.”; we find no runtime policy checks of an app’s permission to create or rename commands with a specific name.

(a) The official Zoom app.
(b) The spoofed Zoom meeting.
Figure 4: Zoom meetings created by official and spoofed /zoom commands in Slack. The spoofed Zoom meeting is secretly created by the attacker but publicly shown as started by the victim. The word “Fake” is added clear demonstration, it can be removed in practical attacks.

We demonstrate the command hijacking attack on Zoom’s Slack app [zoom]. From Zoom’s app, users can invoke the command /zoom to start private Zoom meetings and display a Zoom call in Slack, as shown in Figure 3(a). If the command is invoked in a private channel, only users in this private channel will receive this private call. We create a malicious app that masquerades as the official Zoom app. At the time of installation, our malicious app requests the commands scope to implement a benign command called /foo. Once installed, we rename this command as /zoom to hijack the previous official /zoom command. After that, the malicious app will use the attacker’s Zoom account to start meetings every time a user invokes the /zoom command, as shown in Figure 3(b). Attackers can also treat this vulnerability as a novel entry point for phishing attacks, as discussed in Appendix B.

Since Microsoft Teams does not allow apps to register their own commands, it does not suffer from this vulnerability.

5.2 Link Unfurling Hijacking

Microsoft Teams allows an app to provide customized link unfurling for an authorized user. The app can register a domain in its manifest. Whenever the user posts a URL under this domain, the app can append a rich message card containing texts, images, or even interactive buttons. For example, Lucidchart’s Teams app [lucidcharts] unfurls a document sharing URL to preview the document as well as a button to accept the sharing invitation. Such unfurled content can be hijacked similarly to Slack’s slash command: a malicious app can register the same domain as the victim app and, if the malicious app is installed after the victim app, its unfurled content will be displayed instead of the victim app’s one. Moreover, the malicious app can masquerade as the victim app to further deceive the user, as its name and icon will also be part of the unfurled content.

While Slack also allows multiple apps to register the same domain, it chooses to display all app’s unfurled contents in parallel, avoiding the issue of link unfurling hijacking.

5.3 Analysis of Root Cause and
Potential Prevalence

The command and unfurling hijacking attacks work by violating least privilege and complete mediation, which results from an overprivileged scope and the improper tracking of resource ownership. First, the corresponding scope that allows an app to use slash commands or unfurl a domain should not spontaneously grant the ability to modify the app’s currently registered command names or domains; an app that performs such operation should need to be re-installed. Second, whenever an app registers a command or a domain, it should gain ownership of this command or domain, however, given the namespace collision, both BCPs fail to enforce such ownership, which thus can be easily taken over by another newly-installed app.

Potential Prevalence.

In Slack, this slash command attack only exploits the commands scope, which is requested by 1,266 apps (51.5%). These apps can immediately overwrite each other’s commands to hijack their standard workflows. Recall, once installed, these apps can change their slash commands at any time, without requiring re-installation or notifying the users (or admins) of the workspace. We also find that many apps in the Slack App Directory already have conflicting commands: 270 apps register commands used by other apps. This implies the wide reuse of conflicting commands, and thus Slack is likely to preserve this design choice. In Microsoft Teams, the link unfurl attack relies on the messageHandlers capability, which is requested by 77 apps (5.9%). We find that 13 of them register a domain that is also registered by other apps.

6 App-to-User Confidentiality Violations

We analyze the different ways in which BCP apps interact with user messages. Our main discovery is that an attacker can leak messages from private channels without having permission to read from those channels. Concretely, we can exploit two features in Slack: (1) Link unfurling of message URLs (Section 6.1); (2) Pinning, starring, or emoji-reacting to messages (Section 6.2). We additionally find that the root cause behind this privilege escalation is incomplete mediation coupled with a lack of ownership tracking of resources (Section 6.3). We note that in Microsoft Teams these features are either absent or inaccessible to apps, so it does not suffer from this vulnerability.

6.1 Message Extraction Attack via
Link Unfurls

BCPs have a built-in link unfurling feature that previews the website content for any URLs contained in a chat message. We first describe how link unfurling works with message URLs and then show an attack where a malicious app without Slack’s groups:history, the permission scope that controls the read access to messages in private channel, abuses this feature to effectively monitor all chats in any private channel joined by an authorized user.

6.1.1 Unfurling of Message URLs

Slack provides a public URL to every message in a workspace. This URL, if accessed, will only show the message if the login credential of a user who has access to the message is provided. We find that when the user sends a message in their own personal channel (i.e., where users can message themselves) and contains a URL that links to , where can be any message in any of the channels that the user is a member of, Slack will automatically unfurl , adding its text content (up to 8001 characters) and author as an additional attribute to the original message .

While this is a reasonable and useful functionality because the user’s personal channel is intended for drafting messages and keeping links and files handy (as described by Slack), it leads to unwarranted access, as illustrated in Fig. 5. Slack allows an app with im:history user token scope to read the user’s personal channel. This grants the app the ability to read with all its attachments. In this case, the attachments include the unfurled content, which is , a message from a private channel. Therefore, the app is implicitly permitted to read , which is protected under the groups:history scope, and the app with only im:history does not have access to originally.

Figure 5: Privilege escalation exploiting link unfurling.

6.1.2 Attack Workflow

Now, we present a powerful attack based on the issue identified above. Through this attack, a malicious app can achieve privilege escalation — it gains the ability to monitor all chat messages in any private channel where the victim user is a member of, effectively gaining the permissions provided by the groups:history user token scope but without explicitly requesting it.

The key insight enabling this attack is that if the attacker can learn the message URL of a private channel message, it can then instruct the malicious app to post a generated URL to the victim user’s personal channel (using the chat:write scope as we described in Section 4), actively leaking messages from that private channel. We additionally find that Slack’s message URL always follows the format:

https://[workspace].slack.com/archives/ [channel-ID]/p[message-ID]

Therefore, the attacker’s job becomes learning valid combinations of channel ID and message ID.

We have discovered several ways to obtain such combinations without resorting to groups:history and detailed them in Appendix D. Here we describe one method that utilizes groups:read. This user token scope provides the read access to the metadata of the user’s private channels, including the channel ID and the ID of the latest message in the channel. By constantly querying a channel’s metadata, the attacker can pull every message from any private channel the victim user has joined. We note that even if multiple messages occur between two queries, the attacker can still guess their IDs since Slack’s message ID is a counter that increments for consecutive messages (see Appendix D for details).

Extracting other types of messages and files.

This attack also works for other types of messages. An app’s bot user can use this to view any public channel messages without the corresponding bot token scope or invitation to join that channel. Additionally, it can even be applied to read files shared with the user. Unlike message URL, there is no easy way to obtain a valid file URL through alternative approaches; yet, whenever a file is uploaded in a chat message, the file’s public URL will also be included in that message. The attacker can then instruct Slack to unfurl the public URL to obtain a direct-downloadable link. Therefore, the attacker can access files by reading all the messages in the user’s joined channels.

6.2 Message Extraction Attack via
Pins, Stars, or Reactions

We demonstrate another message extraction attack exploiting the incompleteness of resource ownership tracking in Slack. This time we leverage the productivity feature of pinning and starring messages (that add them to a user’s saved message list) and the convenience feature of adding emoji reactions to messages. The attack builds upon the same message ID guessing technique from the prior attack.

To pin, star, or react to a message, the app needs to present the message ID and the ID of the message’s channel to the corresponding Slack API, with the pins:, stars:, or reactions:write user token scope respectively. However, the read counterpart of these scopes (pins:, stars:, or reactions:read) does more than permit the app to view the IDs of the pinned, starred, and reacted messages; they also allow the app to view the contents of these messages. Therefore, after a valid channel ID and message ID is obtained, the app with both read and write scopes can either pin, star, or react to the message, effectively allowing itself to read the given message. As we have seen in the prior attack, an app without permission to read a user’s private channel message is still able to acquire the channel ID and message IDs of that channel’s messages. Hence, a malicious app can repeatedly pin, star, or react to these messages and read through all messages in the channel. We note that the app can also undo these operations using the corresponding write scope again to prevent the user from spotting any suspicious activity. With this attack, the malicious app can read all the messages that the user has access to, using only these seemingly harmless operations.

6.3 Analysis of Root Cause and
Potential Prevalence

In both message extraction attacks, the malicious app obtains the ability to read any messages that the user has access to, with only some irrelevant permission scopes. We consider this behavior as a violation of the user’s privacy expectations. When a user grants the im:history scope to an app, there is no description in the authorization prompt that suggests the app can read private channels555Accessing private channel messages with only im:history will cause Slack API to return an missing_scope error and a message saying that groups:history is needed.. In addition, it puts the privacy of other users in these channels at risk — the messages they posted may suddenly become accessible to an app that they never authorized. Even worse, they have no way of knowing the leakage, since all it takes is for one user to install the app, an action that is hardly perceptible to them (Section 2.2), while the app itself is never a member of the channel.

An adversarial admin can use these attacks to monitor chats in private channels they are not invited to by forcing everyone to install their malicious app that disguises itself as an innocent management app.

Such privacy violation in the first attack is a failure of not enforcing complete mediation, which results from the improper tracking of resource provenance in Slack. Take Fig. 5 for example: when Slack finds a link to in , it blindly appends the content of as ’s attachments, without tracking where originates from. As such, any entity that can read can also read , whereas these two messages have different provenances and should be checked against two separate permissions. The second attack can also be mitigated if Slack tracks and checks who performed the operation. While Slack needs to allow apps to read the content of pinned, starred, or emoji-reacted messages for functionality purposes, this rule should not apply if the app trying to read the message is the one who performed the operation (since it does not make sense for an app to pin a message it does not already know).

Potential Prevalence.

Out of all 1,640 apps (66.7%) that do not request explicit scopes to read private channels (i.e., groups:history), we only counted 11 apps with the necessary permissions to extract messages via pins, stars, reactions, or link unfurls.

7 Potential Countermeasures

We discuss countermeasures for the attacks we previously discussed. We note that these countermeasures are point fixes for the BCP permission model as it currently exists. The attack classes we’ve identified exist because the BCP permission model violates classic security principles. As such, even with these countermeasures, we cannot guarantee that all future issues will be prevented. We characterize each countermeasure from three perspectives: which design issues it attempts to solve, how much it helps mitigate the attacks, and what the cost or trade-off is.

7.1 Finer-grained Scopes

The BCPs we examined define several coarse-grained scopes that manage multiple resources of different types. For example, Slack’s chat:write user scope allows an app to send messages to any target with the identity of the authorizing user. The Microsoft Teams Graph API Chat.ReadWrite scope grants a Microsoft Teams app similar permissions. Therefore, even if the app’s functionality only requires sending messages to human users, it needs to acquire one of these broad scopes, which inevitably comes with the permission to send messages to apps and thus the ability to perform impersonation attacks on other apps. These scopes are coarse-grained as they allow an app to send messages to separate targets (app and non-app). BCPs can break down these scopes into two separate scopes: one that allows sending messages to non-app targets, and another that allows messages to app targets. However, this countermeasure cannot handle the attacks exploiting scopes that do not have finer-grained concepts (such as command hijacking).

7.2 Stricter Runtime Policy Checks

Stricter runtime checks can help address the message extraction attacks found in Slack. Specifically, Slack first needs to fix its coarse-grained modeling of the message resources by decoupling the unfurled content from the message and treating it as a separate type of resource. Slack also needs to track the origin of the unfurled content, for example, whether it is a message from another channel or a file shared with the user. Then, whenever an app requests to read a message, Slack should enforce an additional dynamic condition check to examine whether the provided token has the correct privilege to access the origin of the unfurled content. If not, only the message should be returned to the app, but not the appended unfurled content.

For the attack via pins, stars, or reactions, we present two options. The first is that when an app wants to read the pinned or starred messages, Slack should send the message content only if the app has the privilege to read the original message; otherwise, only the message ID is returned. However, this may inversely encourage malicious apps to request more privileges to maintain their original functionality. The second is for the BCP to consider the entity that issued the pin, star, or react operation. For example, an app can only read the content of a pinned/starred/reacted message if the pinning/starring/reacting is done by a human user or a different app; if it is done by the requesting app itself, then the BCP only returns the message ID. The tracking should occur even when a user has delegated control of their account to an app. When an app performs actions on behalf of a user, those actions should still be tracked as having been taken by an app. This should not hurt any benign app’s functionality because if a message is pinned, starred, or reacted on by a benign app, it is reasonable to assume that the app should already know the message’s content.

However, this countermeasure does not apply to situations where it is difficult for an app or Slack to determine whether an action is malicious or user-intended. In Section 4.1, we demonstrated various legitimate scenarios in which users indeed want apps to perform actions on their behalf.

7.3 Indicate Identity of Action Issuer

To counter delegation attacks, the victim app should be able to determine if a received event comes from a human or an impersonated user and thus choose whether to respond or not. Thus, BCPs should indicate the identity of the action issuer (i.e., whether a real or delegated user performed the action) and therefore allow for identity checks on the victim app’s side. Slack has provided this information for a few actions, such as posting messages but ignored it for other actions such as reacting to a message, which might also lead to exploits. However, as mentioned earlier, in some cases, even if the app knows the action is coming from another app, it is hard to tell whether the intent of the action is malicious or not.

7.4 Explicit User Confirmation

The final countermeasure is to request confirmation from users. From the perspective of victim users, all attacks stem from the fact that either victim apps or the BCPs automatically reacted to malicious events (in an unwanted way). Therefore, before accessing sensitive data, both the apps and the BCP should prompt the user for confirmation. For example, they can create a consent popup UI that involves clicking a button. Based on the current design of Microsoft Teams and Slack, only human users can perform such actions, making it hard to forge UI actions. This will prevent both delegation and message extraction attacks.

To resolve namespace collision attacks, BCPs should actively check for namespace collisions when apps are being installed. For example, Slack should detect when an app attempts to register a command with the same name as a command already registered in the workspace, and Microsoft Teams should detect when an app has the same name as another app already installed in the workspace. We outline three solutions that BCPs may adopt. First, they can refuse to install the new app whose command would conflict with an existing one. However, this robs BCPs of functionality and unfairly penalizes apps installed later. Second, they can permit installation but require the user to make a selection whenever a namespace collision arises during use, but this requires the user to pay attention at all times. Third, after detecting a collision, they can provide an alias mechanism where users can change the conflicting names. In conclusion, runtime user confirmation can mitigate namespace collision attacks, but at the expense of productivity and user convenience.

8 Related Work

To the best of our knowledge, this is the first paper to analyze the security and privacy of third-party apps in business communication platforms. However, considerable work has been done in other types of app platforms that share varying degrees of similarities with BCPs.

Social networks.

Facebook and other social network platforms allow third-party applications that offer users additional functionality and services but generally at the cost of user privacy [chaabane2014closer, robinson2014cognitive]. These apps are similar to BCP apps in terms of pure server-side implementations and all-or-nothing permission, but they are installed in a single-user home space, whereas BCP apps are in a multi-user workspace. Symeonidis et al. show Facebook apps lead to collateral information collection [symeonidis2018collateral], where they can collect not only data of the users who install them but also of their friends. This is akin to our findings of BCP apps; however, BCP apps can also actively affect other users’ actions, such as through confusion attacks. On the other hand, several studies propose different access control schemes for apps in social networks [anthonysamy2012collaborative, viswanath2012keeping, singh2009xbook, shehab2008beyond, cheng2013preserving, tomy2016controlling]. While these solutions aim to solve the problem of coarse-grained permissions, they usually require the social network provider to host some part of the application codes, which does not suit the current communication framework of BCP apps.

Voice assistants.

Amazon Alexa, a voice assistant often built into smart home devices, allows users to install third-party apps called skills. Similar to BCP apps, Alexa skills often appear in the form of chatbots; however the primary way of interacting with Alexa skills is through voice commands. Studies have shown that Alexa skills can be easily squatted to enable phishing attacks [kumar2018skill, zhang2019dangerous], similar to how Slack’s commands can be hijacked. However, skill squatting relies on the inherent ambiguity of voices, whereas we exploit the namespace collisions of commands. In an orthogonal direction, many works try to measure the privacy practices of current Alexa skills and find that many skills do not honor their privacy policy and request overprivileged access [alhadlaq1902privacy, su2020you, guo2020skillexplorer, lentzsch2021hey].

Android.

Many studies have analyzed the security and privacy of Android apps. The closest related attacks to this work are the confused deputy and collusion attacks [davi2010privilege, marforio2011application, schlegel2011soundcomber, bugiel2012towards, lu2020demystifying]. Just as in BCPs, the app-to-app communications in Android can be used with malicious intent; however, they usually aim to achieve privilege escalation to access more user data instead of attacking users’ accounts in other services. In addition, the problem of coarse-grained permission scopes is also found in Android, granting apps powerful capabilities that can be used to exploit various vulnerabilities [jeon2012dr]. Meanwhile, defenses proposed for Android apps usually require static or dynamic analysis [wong2016intellidroid, enck2014taintdroid, wei2014amandroid, gordon2015information, fratantonio2016triggerscope], making them incompatible with BCP apps, which have no client-side codes.

Other OAuth-based systems.

Studies have shown that overprivileged attacks are a common issue in OAuth-based systems [ho2016smart, fernandes2016security, jia2018novel, celik2018soteria, celik2018sensitive]. In addition, despite its wide adoption, OAuth is usually poorly designed and implemented by developers [chen2014oauth, wang2015vulnerability, sun2012devil]. BCPs use coarse-grained scopes for certain operations and couple them with separate runtime policy checks that we have shown to be incomplete.

9 Conclusions

We performed an experimental security analysis of the app model of two popular BCPs: Slack and Microsoft Teams. Our methodology was to study each BCP-facilitated interaction method between apps and users. We found that these BCPs violate two standard security principles: least access and complete mediation. We created proof-of-concept attacks that exploit these violations to (1) impersonate users and trick victim apps into performing unwanted actions; (2) hijack commands; (3) steal messages from private channels without appropriate permissions. Our discussion of countermeasures indicates that while point fixes for these attacks can be deployed at the cost of BCP usability, preventing further issues requires redesigning the BCP app access control model.

Limitations.

For ethical reasons, we did not publish our attack apps to the Slack app directory or the Microsoft Teams app store, and thus cannot comment on their review processes. However, we did analyze their security guidelines [slack-guidelines, teams-guidelines] for publishing an app and found no obvious restrictions that would fundamentally prevent our attacks. They do, however, prohibit two apps from sharing the same name, making it harder for a published app to mimic the appearance of another app; but as we noted in Section 5, a Slack app can circumvent this restriction by requesting the chat:write.customize permission scope, which allows the app the send messages using customized name and icon, avoiding the need to modify the app’s own name and icon declared in the manifest.

References

Appendix A Exploiting File-based Interactions

Dokkio [dokkio] is a cloud service that provides a single place to manage a user or team’s files stored in different cloud storage services, including DropBox, Google Drive, Gmail, and Slack. To manage files in Slack, it connects to the user’s Slack account and request permission to read files uploaded in the workspace. Once the user shares a file in Slack, Dokkio’s Slack app will automatically collect this file and provides numerous add-on services such as content organizing and cognitive services. In this case, the user’s Dokkio account is a resource that only Dokkio and the user can access. Similar to the attacks discussed above, once an app can share files on the user’s behalf, it implicitly gains access to Dokkio’s backend resources.

In this attack, we show that the attacker, though not authorized to access the user’s Dokkio account, can add any files to the user’s file management portal in Dokkio. We design a malicious app that requests the files:write user scope and launch the attack by uploading arbitrary files to Slack on the user’s behalf. After that, Dokkio will automatically collect the shared files and add them to the user’s Dokkio account.

Appendix B Phishing Attacks based on Command Hijacking

Attackers can treat the design issue of command namespace collisions as a novel entry point for phishing attacks. For example, the malicious app can request the user to authorize third-party services. In Figure 6, we demonstrate a phishing attack by hijacking the /gcal command from the Google Calendar app.

Figure 6: Demonstration of phishing attacks using the Command Hijacking attack in Slack. The two messages are sent to the user after invoking the official and hijacked /gcal command, respectively. The attacker can start a valid OAuth authorization process to acquire access to the user’s account.

Appendix C Slack App Installation Page

We provide an illustration of a Slack app’s deployment and installation in Figure 6(a) and Fig. 6(b). We also provide actual screenshots of installing Slack apps that request bot scopes in Figure 10 and user scopes in Figure 10. Note that in Figure 10, the app is able to perform actions as the user, such as sending messages and direct messages.

(a) Deployment (To Slack)
(b) Installation (To User)
Figure 7: Illustration of Slack app’s deployment & installation. The deployment information is registered with Slack. The installation page is presented to the user who installs the app.
User Action Counter Increment
User Posting a message with text 200
App Posting a message with text 100
Posting a message with only file 100
Saving a draft (happens automatically 10 seconds after the user stops typing) 100
Figure 8: Slack Message Counter Increment. For each consecutive message, the counter value is increased by , where starts at and gradually increases based on actions of the users in the channel.
Figure 9: Installing Slack apps with bot scopes.
Figure 10: Installing Slack apps with user scopes.
Scope Description # Apps
User token scope with read access What will the app be able to view?
channels:history – View basic information about your public channels 116
groups:history – View messages and other content in your private channels 47
groups:read – View basic information about your private channels 301
im:history – View messages and other content in your direct messages 35
mpim:history – View messages and other content in your group direct messages 18
pins:read – View pinned content in your channels and conversations 11
reactions:read – View emoji reactions in your channels and conversations and their associated content 34
search:read – Search your workspace’s content 9
stars:read – View your starred messages and files 15
User token scope with write access What will the app be able to do as you?
calls:write – Start and manage calls 5
chat:write – Send messages on your behalf 241
files:write – Upload, edit, and delete files on your behalf 87
pins:write – Add and remove pinned messages and files on your behalf 11
reactions:write – Add and edit emoji reactions on your behalf 17
stars:write – Add or remove stars for you 6
Bot token scope What will the app be able to do?
chat:write.customize – Send messages as @app with a customized username and avatar 120
commands – Add shortcuts and/or slash commands that people can use 1266
Figure 11: A summary of Slack’s OAuth permissions scopes mentioned in the paper, their permission descriptions in OAuth authorization UI, and the number of apps in Slack App Directory that request each scope.

Appendix D Obtaining Channel ID and Message ID

Obtaining channel ID.

Each channel ID is a random string. The direct way to learn the ID of a private channel is by requesting a less alarming scope, groups:read, which provides the read access to a private channel’s metadata. Alternatively, if the attacker knows the name of the channel (through side channels or guessing; per our threat model the attacker can be a curious workspace member who has some prior knowledge), it can use the chat:write scope to write a new message. It can just provide the channel name to the corresponding chat.postMessage API, which will accept this request and return the channel ID as part of the response.

Obtaining message ID.

The direct way to learn the message ID requires groups:history, which also grants the ability to directly read messages, avoiding the need for any attack because an app can simply misuse that permission to leak messages. However, unlike channel ID which is completely randomized, the format of a message ID follows a simple, intuitive pattern, consisting of only the current timestamp and a counter value. An example message ID is shown below:

The first 10 digits represent the UNIX epoch timestamp of the message in seconds, and the last 7 digits is a counter that gets increased for each consecutive message and resets to 0 after approximately 5 days of inactivity. We conducted a series of controlled experiments and empirically found that the counter increments according to the following rules:

  • The increment between two consecutive messages is always a multiple of . Although this increment is usually , it may change based on the user actions listed in Fig. 8.

  • The counters are independent across different channels, as well as user actions in different channels.

Due to the first rule, the attacker cannot predict the exact message ID given the previous ID, as Slack does not provide a way to learn how many drafts are saved internally. However, if the attacker is given two valid IDs separated by a small time interval, then it is straightforward to guess the valid IDs in between. We describe two ways of learning a valid ID. The first way is, again, to rely on the groups:read scope, since the metadata of the channel includes the ID of the latest message in the channel. The second way is to write a new message to the channel, which will cause the Slack API to return the ID of the newly posted message.

Attack workflow.
  • The attacker obtains a valid combination of channel ID and message ID using the techniques described above. We refer to the message ID as . If it obtains the message ID via posting new messages, then it immediately deletes the message to hide its trace, which is also permitted by the chat:write scope.

  • After a short time , the attacker obtains another valid message ID .

  • The attacker guesses all possible message IDs, which is the cartesian product of and .

  • The attacker uses the guessed IDs to generate the message URL and posts it to the user’s personal channel. The URLs of the valid IDs will get unfurled.

By repeating this attack over and over again for different message IDs, the attacker can eventually pull every message from any private channel that the victim user has joined, effectively granting the malicious app the power of the groups:history scope even though this scope is never explicitly requested. We note that the attacker should adjust the time interval dynamically based on the messaging frequency to aim for , so that it can post all possible IDs in step 3 under Slack’s rate limit (which allows unfurling of up to 5 URLs per second).