Share
OAUTH CONSENT PHISHING - FORENSIC BREAKDOWN

The link really was Calendly. The next screen wanted your DMs.

A direct message from a real person, a genuine scheduling page, then X itself asking you to authorize an app called Booking Pass. No password is asked for at any point, which is exactly why this one gets through.

SafeBrowz Threat Research Security Research · · 14 min read

The chain, in short

A direct message offers a chat about an opportunity and carries a calendly.com link. The booking page is real. Submitting it hands you to x.com, where a genuine X consent screen asks you to authorize an app named Booking Pass, and the permissions it wants include sending and managing your direct messages and uploading media as you. Approving it does not leak a password, because none is requested: you are granting an app standing access to your account, which is why a password change afterwards does not undo it. The scheduling story exists only to make that consent screen feel expected. If a booking flow ever ends at an authorization prompt, the correct move is to stop and read what the app is asking for, and if the destination is unfamiliar, check the link before you follow it rather than after you have granted anything.

SafeBrowz reads where a link actually lands, so a booking page that hands off to attacker infrastructure is judged on the destination. Add to Chrome, free Get the free Android app or scan a URL now →

How it arrives: a message from someone real

This was reported to us by a person who received it directly, and the first thing worth saying is that the sender was not a stranger and not an obvious bot. The account was several months old, carried a blue check, had a couple of thousand followers and a detailed, coherent profile naming a real employer and a real university. The message was short and ordinary: a friendly greeting using the recipient's first name, a mention that a named team would like to chat about an opportunity, and the Calendly link.

The account had been taken over. Everything a careful reader would check, the age of the profile, the follower count, the consistency of the bio, the fact that this person genuinely does work where they say they work, was true, because it belonged to a real person before it was used to send this. Judging the sender was never going to work here.

That is also the most useful thing to take away. Advice built on "does this account look legitimate" fails completely once the account is legitimate, and the growing share of scam DMs that arrive from taken-over accounts is why. We covered the takeover side of this in the account takeover guide; this post is about what the stolen account is then used to do.

The same shape with a different opener: an interview request

The message above offered the recipient something. A variant of this technique does the opposite, and it is the one the outlets on the receiving end have started naming publicly, WBUR and LAist among them: it asks you for something instead. Cybernews documented a case under the headline A fake journalist used a real Calendly link to phish a tech founder, and its account of the opening is worth reading literally: "The attack started with an interview request about carbon removal, sent from an X account impersonating WIRED journalist Simon Hill."

The target was Peter Reinhardt, co-founder of Segment and now chief executive of Charm Industrial, a carbon removal company. That detail is the point. The subject of the interview was his actual day job, so the request did not arrive as an offer to be weighed, it arrived as recognition to be accepted. An unsolicited opportunity invites suspicion by design, because most people have learned that one is worth a second look. Being asked for your expertise by a publication that covers your field is far harder to hold at arm's length, and it is hardest of all for the people best qualified to answer, who have a standing and entirely reasonable expectation of being contacted.

The permission-grant ending is the same, but do not assume the route to it is identical to the chain described below, because in this case it was not. Cybernews reports that the genuine Calendly page "eventually led to a WIRED-branded booking page that asked Reinhardt to connect his X account before he could schedule the interview", and that this "attacker-controlled booking page displayed a Calendly-like domain containing a subtle lookalike character (an uppercase I, instead of a lowercase l), making the address easy to mistake for the real thing". The app that then asked for consent was called CalendarBookings, and it "requested permission to read and write posts and access direct messages". So an extra attacker-owned hop sat in the middle, and a homograph did the work of hiding it. Casco security engineer Anthony Gibbs described the assembly precisely: "Calendly appeared at both ends of the attack", the genuine routing form in the original message and a real configured event after consent, and "the attacker placed the authorization request between those familiar scheduling steps." Genuine scheduling at both ends, the attacker's page in the gap.

How far that reaches is partly mapped and partly not. Gibbs traced five publication-branded phishing sites to one shared backend, dubbed Asteria, between 9 and 11 September, and the cluster has since gone offline, according to Gibbs. But Cybernews is explicit that the investigation "did not establish who operated the infrastructure or how many people fell victim", so treat this as the same technique rather than provably the same operator as the specimen in this post.

The interview pretext also has an ending that involves no consent screen at all, and that is where the newsrooms themselves come in. WBUR published a notice on 20 August 2026 stating plainly that "fraudsters are impersonating WBUR hosts and staff to contact potential guests with fake interview invitations to appear on our shows", describing senders who "send fabricated invitations, agreements, identification documents or screenshots" to hold the story together under scrutiny. That notice says nothing about scheduling links or app permissions. What it warns about is the pretext, and a different payoff: the invitations "can include a request for payment or fake donation to participate". So an interview approach can end in an authorisation screen that hands over your account, or in an advance fee dressed as a booking cost, a studio contribution or a donation attached to the appearance. LAist runs a standing notice of its own about the same thing, warning that "scammers are impersonating LAist hosts and staff to contact authors, publicists, and others with fake interview invitations conditioned upon payment of a fee", and answering it in capitals: the station never charges anyone to appear as a guest on any of its programmes. That is the rule across the industry. No legitimate outlet charges a guest to be interviewed.

The verification move here is narrower than for the rest of this chain, and worth keeping separate in your head. Do not assess the request. Assess the route. Find the outlet's own website, use the contact details published there, and ask the newsroom whether that person works for them and whether the approach is theirs. A genuine booker loses nothing when you reach them through the newsroom instead of the thread. An impersonator cannot survive the step, because the only place their identity exists is the message you were sent.

Step one: a genuine Calendly page

The link goes to a real routing form on calendly.com. Not a lookalike domain, not a homograph, not a subdomain trick. It renders Calendly's own interface, carries Calendly's own "Powered by Calendly" badge, and asks for two things: a name, and whether you want 15 or 30 minutes.

Anyone can create one of these in about two minutes with a free account, and that is the entire reason this step exists. A link to calendly.com passes reputation checks, mail filters and the mental check most people perform, because the domain genuinely is what it says it is. The malicious behaviour is not on this page. It is in where the page sends you when you press Submit.

This is a pattern worth naming, because it is spreading: put the first hop on a service with an unimpeachable reputation, and let the second hop do the work. The same logic drives scams that start from a real meeting invite. A trusted domain tells you about the page you are on. It tells you nothing about the next one.

Step two: the consent screen, on the real x.com

Submitting the form does not open a calendar. It redirects to an address on x.com beginning /i/oauth2/authorize, and what appears is a genuine X authorization page. The X logo, the X styling, the real domain in the address bar, and a heading that reads: Booking Pass wants to access your X account.

Underneath it shows the developer account behind the app, which in this case is another aged, real-looking account rather than anything obviously throwaway. Below that sit two buttons, Authorize app and Cancel, and a list headed "Things this App can do".

Nothing on this screen is fake. That is the point of the technique, and it is why every instinct trained on spotting fake login pages misfires. There is no fake login page. There is a real one, doing exactly what it was designed to do.

What Booking Pass is actually asking for

The permission list is where the pretext falls apart, for anyone who reads it. Alongside the routine items, the app requests:

  • To stay connected to your account until you revoke access. Not for the duration of a booking. Indefinitely, until you go and find it and remove it.
  • To send and manage your direct and chat messages, including creating and managing group conversations, deleting messages and leaving group conversations, and reacting to messages.
  • To upload media like photos and videos for you.

The screen collapses two further permissions behind a "2 more" link, which most people never expand.

Hold that against what was offered. You were picking between a 15 minute and a 30 minute meeting slot. A scheduling tool needs a name, an email and a calendar. It does not need to write direct messages as you, and it certainly does not need to delete them afterwards. The ability to delete is the detail that gives the intent away: deletion is not a feature a booking product would ever want, but it is precisely what you need if you are sending messages from someone's account and would rather the owner did not find them in their sent folder.

Why your password and your two-factor do nothing here

This is the section worth keeping, because it is the part that catches people who are otherwise hard to catch.

In ordinary phishing, an attacker builds a convincing copy of a login page and waits for you to type your credentials into it. Everything defensive we have built assumes that shape. A password manager refuses to autofill on the wrong domain. Two-factor authentication demands a second proof. Browser warnings fire on lookalike domains. Advice tells you to check the address bar.

Every one of those defences is silent here, and not because they failed. They were never engaged:

  • No password is requested, so your password manager has nothing to autofill and nothing to refuse.
  • No login code is requested, so two-factor never triggers. You are already signed in.
  • The address bar is correct. It really is x.com, serving a page X wrote.
  • Nothing is stolen. Access is granted, by you, through a mechanism working exactly as designed.

OAuth exists so you can let an app act on your behalf without handing it your password, and that is a genuinely good design. The weakness is not in the protocol. It is that the decision about whether an app deserves that access is delegated entirely to a person reading a permissions list at the exact moment they are expecting to be shown a calendar. Attacks that defeat two-factor by relaying it at least need infrastructure. This one just needs you to press a button that is genuinely yours to press.

Step three: pressing Cancel, and what is really on that domain

Choosing Cancel is instructive, because of where it lands. The browser goes to a callback on whitelistportal[.]com, which shows a small card reading "Authentication failed or was cancelled."

That domain is the attacker's. It was registered on 1 August 2026, making it under three weeks old at the time of writing, through Tucows, with a registrant country of Saint Kitts and Nevis, sitting behind Cloudflare. It is the address the OAuth flow was configured to hand its authorization code to, which means a successful authorization sends your access there rather than to any booking system.

And there is more on it than a callback page. Requesting the root of that domain returns something the victim never sees during the booking flow: a sign-in page titled "Sign in - Twitta", carrying a bird emoji, a username field, a password field and the line "Sign in to your beta account". A credential-harvesting page impersonating Twitter, sitting on the same host as the OAuth callback. The same page answers at /login, and the site's own not-found page comes back branded as "404 - Twitta", which tells you this is a whole cloned site rather than a single file dropped on a host. A snapshot is preserved on the Internet Archive, taken 20 August 2026, in case the content changes.

So the operator is running both plays from one domain. If you grant the app, they take the account through OAuth. If they can steer you to the root instead, they take your password the old-fashioned way. Two paths to the same account, and the second one tells you plainly what the first one is for.

Why it spreads on its own

Look again at the permission that matters and the campaign explains itself. An app that can send direct messages as you, on an account with a real name, a real history and real contacts, is a distribution system. Every authorization produces a fresh sender with the credibility that made the original message work.

That is why the message our reader received came from a genuine person at a genuine company. It is not an unlucky coincidence that the sender looked real. Looking real is what the previous victim was harvested for, and the DM permission is the machinery that turns one taken account into the next batch of convincing messages.

The indicators, for anyone tracking this

  • Malicious host: whitelistportal[.]com - OAuth callback plus a fake "Twitta" credential page on the root. Registered 1 August 2026, Tucows, registrant country KN, Cloudflare nameservers.
  • App name shown on the consent screen: Booking Pass.
  • X app client id: R-WYDF7tmgSwvzPkFWZv:1:ci, appearing base64-encoded in the authorize URL.
  • First hop: a Calendly routing form asking only for a name and a 15 or 30 minute duration. Calendly is legitimate and is being used, not breached.
  • Lure: a direct message referencing a named company and a "potential opportunity", sent from a compromised account whose profile genuinely matches that company.

We are deliberately not naming the accounts involved. The sender's account was taken over and the company named in the message is being impersonated. Both are victims of this campaign, and publishing their handles would punish them for it.

If you already pressed Authorize

  1. Revoke the app first, before anything else. On X: Settings and privacy, then Security and account access, then Apps and sessions, then Connected apps. Select the app and choose Revoke app permissions.
  2. Do not rely on a password change. An OAuth grant is separate from your password and survives changing it. Revoking is the only action that removes it.
  3. Read your sent direct messages. If it messaged your contacts, tell them directly, through a channel other than X, that anything sent from you was not from you.
  4. Check the rest of the list while you are in there. Most accounts carry old connected apps nobody has audited in years. Remove anything you do not actively use.
  5. Then change the password and check active sessions, in that order, in case the root credential page caught you separately.

Where to report it, and why the registrar is the useful one

Blocking a domain protects the people using your own tools. Getting it taken down protects everyone else, and for that there is a specific order worth knowing, because most people start at the least effective end.

Do not bother chasing the registrant. Public WHOIS for this domain returns "REDACTED FOR PRIVACY" for every personal field, with a contact URI pointing at Tucows' Tiered Access directory, the gated WHOIS system registrars moved to after GDPR. That is legitimate registrar infrastructure, not part of the scam, and it exists so that requesters with a lawful basis can ask for the underlying data. For a domain using a privacy service, that generally means a warrant or a subpoena. It is not a route a member of the public can walk down.

The registrar abuse contact is the route that works. Registrars publish an abuse address precisely so that phishing can be reported, and a report naming a confirmed credential-harvesting page carries real weight because it is a plain breach of the registration agreement. For this domain that address is [email protected], published in the domain's own record. Include the domain, what you observed, when you observed it, and evidence: a screenshot of the fake sign-in page, the authorization URL, and the callback address are enough.

Then the other two, in parallel. The site sits behind Cloudflare, which runs a public abuse portal for phishing reports and passes them to the origin host. And the malicious application itself should be reported to X through their help centre, by app name, since revoking it from your own account does nothing about the next person's. If your own account was the one sending the DMs, X's account-compromised flow is the recovery path.

One more, and it is the one people skip out of embarrassment: tell the person whose account sent you the message, through some channel other than X. They usually do not know. Every hour their account stays authorized is another batch of messages going out under their name.

Ten seconds that settle any consent screen

  1. Compare the ask to the offer. Write the two next to each other. "Book a 15 minute call" against "send and delete direct messages as me, permanently". The gap is the answer.
  2. Expand "2 more". Whatever is hidden behind the collapse is hidden for a reason.
  3. Treat "until you revoke access" as the flag it is. A one-off task does not need permanent access.
  4. Ask who benefits from write access. Reading your profile is normal. Writing messages, posting and uploading media are not needed to put a meeting in a calendar.
  5. When in doubt, cancel and go direct. If the opportunity is real, the person will still be there tomorrow through a channel you chose.

Where a link check still helps when the login page is genuine

It would be dishonest to claim a browser extension reads a consent screen and knows the app is malicious. It does not. The consent page is X's own, and by design it looks exactly like every legitimate authorization you have ever approved.

What is checkable is everything around it. Layer 1 reads the shape of a link in the browser before the page renders. Layer 2 checks the destination server-side against reputation feeds, a brand database of more than 550 names and our blocklist, which is where hosts like this one land: the domain behind this campaign is blocked for SafeBrowz users on every surface, and so is the specific booking page that feeds it, while Calendly itself stays untouched, because blocking a legitimate service because someone abused one page on it would be its own kind of failure. Layer 3 is the AI deep scan, a Premium feature with one free scan a day for everyone else, reading what a page actually serves, which is how a credential form dressed as a social network on a three-week-old domain gets judged on what it is.

Honest scope, and it is narrow in an important way here. If you are handed a link and you check it before following it, this chain breaks at the first hop. If you have already reached a real authorization screen on a real domain, no scanner is going to stop you, and the only thing standing between the account and the attacker is whether you read the permission list. That is why the list above matters more than the product does.

Handed a booking link out of the blue? Flag the destination before you follow it. Flag a link before you open it → Get the free Android app
🛡 LIVE CHECK

Sent a link you were not expecting?

Paste it here instead of following it. Our 3-layer engine (Local + APIs + AI) returns a verdict in about 3 seconds. Free, no signup.

Full scan with deep AI analysis → · No URL is logged to your identity.

Frequently asked questions

Why would booking a meeting need access to my X account?

It would not, and that mismatch is the whole tell. A scheduling page collects a name, an email and a time slot. Nothing about picking a 15 or 30 minute slot requires permission to send direct messages as you or to upload media to your account. When the thing being requested is larger than the thing being offered, the request is the point and the offer is the wrapper.

I tapped Authorize. What do I do right now?

Revoke the app, and do it before changing anything else. On X, open Settings and privacy, then Security and account access, then Apps and sessions, then Connected apps, select the app and choose Revoke app permissions. Changing your password does NOT remove an OAuth grant, and neither does logging out everywhere, because you granted this access deliberately and X has no reason to treat it as suspicious. After revoking, read your sent DMs: if the app messaged your contacts, those people need to be told directly.

Is Calendly itself hacked or unsafe?

No. Calendly is a legitimate scheduling service and the page in this campaign is an ordinary routing form, the kind anyone can create in a couple of minutes with a free account. That is exactly why it was chosen. The link passes every reputation check because the domain genuinely is Calendly, and the malicious step happens one hop later on a different site. Treat a real brand in the address bar as evidence about that page only, never about where it sends you next.

I have a strong password and two-factor authentication. Am I covered?

Not here, and this is the part that catches technical people. Nothing in this attack asks for your password, so a password manager has nothing to warn you about, and no login code is requested, so two-factor never fires. You are on the real x.com, signed in as yourself, clicking a real X button. The access is handed over by consent rather than stolen by deception, which is why the only defence at that moment is reading what the app is asking for.

The message came from someone I actually know. How is that possible?

Because their account was taken over first, and the permissions this campaign asks for are what make that repeatable. An app that can send direct messages as you can work through your contact list, and every message it sends carries the credibility of a real person your contact has spoken to before. That is why these DMs often reference a genuine employer or a plausible opportunity: the sender's profile is real, and only the intent behind the message has changed.

A journalist asked me for an interview. How do I check it is really them?

Go around the message, not through it. Look up the outlet's own website, take the contact details published there, and ask the newsroom whether that person works for them and whether the request is theirs. Do not reply in the thread, do not use a phone number or address supplied in the message, and do not treat an attached invitation, contract or press badge as proof, because those are cheap to fabricate and impersonators send them precisely because they look like evidence. A real booker is unbothered by the detour. Someone who only exists inside that one conversation cannot survive it.

The interview request asked me to pay a fee. Is that ever normal?

No. A legitimate outlet does not charge a guest to appear, and any booking fee, studio contribution, appearance deposit or donation attached to an invitation is the scam itself rather than an unusual policy. WBUR's own public notice about people impersonating its hosts states that the fake invitations "can include a request for payment or fake donation to participate". Treat the money request as the end of the conversation, and report the approach to the real outlet so they can warn others.

Follow on Google