StrandHogg: How Android's Task System Became a UI Spoofing Vulnerability
You open your banking app. The login screen looks correct. Every pixel matches. You type your password anyway, because why would not you. Except the app that just captured it was not your banking app at all.
In this post
- The premise behind StrandHogg
- Android's task system, and the assumption it made
- What made it convincing rather than just clever
- The part that surprised researchers most
- How Google actually closed it
- Why this still matters even though it is patched
- What developers and users should take from it
StrandHogg is the kind of vulnerability that is easy to underestimate when described in technical terms, and genuinely alarming once the implications land. It did not rely on a broken permission model or a leaked signing key. It relied on something far more mundane: the way Android decides which app's screen to show you when you tap an icon. That mundane detail turned out to be enough to display convincing fake login screens for real banking apps, on unmodified devices, without any prior compromise.
The premise behind StrandHogg
That is the entire premise behind StrandHogg, a vulnerability disclosed by the Norwegian security firm Promon in late 2019. A user opens what they believe is their banking app. The login screen looks correct, every pixel matches, the app name at the top of the screen is the one they expect to see. They type their password, and the app that just captured it was not their banking app at all.
The technique worked on essentially any Android app that had a login screen worth spoofing. Banking apps, email clients, password managers, social media apps, anything where an attacker could gain value from capturing credentials. Because the spoofed screen inherited the visual identity of the legitimate app, users had essentially no way to tell they were looking at something hostile.
Android's task system, and the assumption it made
Android organizes running apps into tasks, essentially stacks of activities that represent what you have navigated through inside an app. When you switch back to an app from your recents screen, Android brings its existing task to the foreground rather than starting a fresh one. This is normal, sensible behavior. It is also the exact mechanism StrandHogg abused.
A manifest attribute called taskAffinity lets a developer control which task an activity belongs to. Under most circumstances this is harmless, used for legitimate navigation patterns within a single app's own set of screens. StrandHogg's trick was setting a malicious activity's task affinity to match the package name of a completely different, legitimate app.
When the malicious app got launched, in some configurations it managed to insert its own activity into the target app's task, or trick the system into bringing the malicious activity to the front while the recents thumbnail and app identity still displayed as the legitimate app. The system believed the malicious activity belonged to the legitimate app's task, and treated it accordingly.
The design assumption that made it possible: Android's task system was built on the assumption that an activity's declared task affinity reflects its actual identity. StrandHogg demonstrated that this assumption could be violated by a malicious app declaring an affinity it did not legitimately own, and the system had no mechanism to verify the declaration against the app's actual package identity.
What made it convincing rather than just clever
A spoofed login screen only works if it looks right, and StrandHogg's implementation went further than most phishing overlays. Because the malicious activity was sitting inside what the system still treated as the target app's own task, it could inherit the correct recents entry, the correct icon, sometimes the correct name shown at the top of the screen.
Promon's own writeup and demo of the vulnerability showed a permission prompt appearing to come from a legitimate app while actually requesting camera, microphone, and location access on behalf of the malicious one, with the user having essentially no visual cue that anything was wrong.
| What the user saw | What was actually happening |
|---|---|
| Familiar login screen, correct app name | A different app's activity, rendered on top of the legitimate task |
| A permission dialog they recognized | A request originating from the malicious app, not the one displayed |
| Credentials submitted normally | Captured directly by the attacker-controlled activity |
| Recent apps list showing the correct app | The system still attributed the task to the legitimate package name |
| No obvious visual differences | Layout, icon, and styling all matched the legitimate app |
The combination of these factors is what made StrandHogg stand out from the earlier category of overlay attacks, where a malicious app draws a fake screen on top of a legitimate one. Those overlays could be detected by comparing what the user sees to what the system believes is running. StrandHogg's activities were inside the legitimate task, so the comparison returned the wrong answer. The system itself was confused about what the user was looking at.
The part that surprised researchers most
StrandHogg did not need root, and it did not need the device to be compromised beforehand in any deep sense. It worked on unmodified devices running contemporary Android versions at the time, exploiting a design assumption in the task system rather than a memory corruption bug or a privilege escalation flaw.
That is part of why it got the attention it did. Most headline mobile vulnerabilities involve some kind of exotic technical failure, a buffer overflow, a race condition, a use-after-free. This one involved a manifest attribute that had existed, documented, for years. The vulnerability was not in the code that processed the attribute, but in the design assumption the attribute encoded.
The vulnerability was not a mistake in how Android checks permissions. It was a mistake in how Android decided what you were looking at. Every permission check the system performed was technically correct. The problem was that the user's mental model of which app was asking for the permission did not match the system's model, and there was no mechanism to reconcile the two.
How Google actually closed it
Google addressed the core issue through changes to how taskAffinity interacts with newly launched activities, tightening the conditions under which one app's declared affinity can influence another app's task. Android's official developer documentation on tasks and the back stack reflects these tightened rules directly today.
A follow-up variant, sometimes called StrandHogg 2.0, surfaced in 2020 using a different technical path, reflection-based rather than manifest-based, which Google patched through a separate security update. Both cases followed the same coordinated disclosure pattern common across the industry: private report, development window, then public detail once a fix shipped.
The response pattern is worth noting because it is consistent across major mobile vulnerabilities. The researcher reports privately, the platform vendor develops and tests a fix, the fix ships as part of a security update, and the public writeup follows once users have had a chance to update. This coordinated approach limits the window of exposure while still giving the security community enough detail to understand and learn from the issue.
Why this still matters even though it is patched
The specific bugs are fixed. The category they belong to, UI spoofing through task or overlay manipulation rather than through a fake lookalike app icon, is not something a single patch retires permanently.
It is a reminder that mobile security research does not only look for buffer overflows and kernel exploits. Some of the most effective attacks target the assumptions a UI framework makes about identity and continuity, the same broad category that overlay-based tapjacking and permission spoofing techniques fall into. That is a much harder category to close off with one update than a single memory safety bug ever is, because the vulnerabilities come from design choices rather than implementation errors.
For anyone building Android apps today, the practical lesson is not really about StrandHogg specifically. It is that manifest attributes controlling task behavior deserve the same scrutiny given to permissions, because the two categories can combine in ways that are easy to overlook when reviewing only one of them in isolation.
For users, the takeaway is less direct, since the specific vulnerability is patched and the defense was primarily in Google's hands. But the broader pattern is worth internalizing. When a screen looks correct, that is not the same as a guarantee that it is coming from the app you think it is. Avoiding unofficial app sources, keeping the system updated, and being cautious about unfamiliar permission prompts remain meaningful defenses against the entire category of attacks that StrandHogg belongs to, not just the specific instance of it that was publicly disclosed.
What developers and users should take from it
The lesson for developers is fairly specific. Manifest attributes like taskAffinity, launchMode, and the various activity flags in intents are not decorative. They influence how the system attributes identity to running activities, and misunderstandings about their effects can create exploitable paths.
The lesson for users is broader and more general. Visual appearance is not a reliable guarantee of provenance in any computing environment. When Android's own task system could be confused about which app was on the screen, the same lesson applies at every layer above. Verifying where apps come from, keeping the system updated, and treating unexpected permission requests with skepticism are the practices that matter most, regardless of which specific vulnerability is currently making headlines.
Key Takeaways
- StrandHogg exploited Android's task system to make malicious activities appear as part of legitimate apps
- The vulnerability required no root and no prior compromise of the device
- A manifest attribute called taskAffinity was used to insert malicious activities into legitimate app tasks
- The spoofed screens inherited the correct icon, name, and recents entry of the target app
- Google patched the issue and a follow-up variant through coordinated security updates
- The broader category of UI spoofing attacks is harder to close than individual bugs
- Developers should scrutinize task-related manifest attributes as carefully as permissions
- Users should treat visual appearance as insufficient proof of app identity