Your Page Listened for Messages From the Checkout Frame and Took Them From Any Window
The account page embedded a checkout from the payments provider. An iframe on another origin, so the two sides talked with postMessage. The frame said resize, and the page grew it. The frame said done, and the page sh
The account page
embedded a checkout
from the payments provider.
An iframe
on another origin,
so the two sides talked
with postMessage.
The frame said resize,
and the page grew it.
The frame said done,
and the page showed a notice
the frame had sent along.
window.addEventListener("message", e => {
if (e.data.type === "notice") banner.innerHTML = e.data.html;
});
It worked on the first try.
That was the warning.
A message listener
does not know who is talking
unless you ask.
Any window
holding a reference to yours
can post to it.
Your own iframe, yes.
Also a page
that opened yours
with window.open.
Also a page
that framed yours,
if you let it be framed.
The attacker's page
did the first.
It opened the account page
in a new tab,
waited a second,
and posted one message.
Type notice,
and some HTML
with a script hidden
in an image error handler.
The page put it on screen,
inside the logged in session.
The browser tells you
where every message came from.
e.origin.
Check it first,
against the exact origin you expect,
scheme, host and port,
with ===.
Not includes.
Not startsWith.
https://pay.example.com.attacker.net
starts with the right thing.
Then check that e.source
is the frame you created,
and check the shape of the data
before you touch it.
And never put
anything from a message
into innerHTML.
The other direction
has its own trap.
When you send,
the second argument says
which origin may receive it.
"*" means anybody.
If the frame you post to
has been navigated somewhere else,
your message goes there instead.
Name the origin.
A header helps as well.
Cross-Origin-Opener-Policy: same-origin
cuts the link
between your page
and a cross-origin page that opened it,
so that reference
stops reaching you.
Then search your code
for addEventListener("message".
Every one of them
is a door
anyone with a tab
can knock on.
Find out
which of them
ask who is knocking.
– Serguey Asael Shinder
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.