The HTML5 specification is complicated. I’ve been an author on it, and even I couldn’t tell you all the weird little gotchas it contains. Between that and “idiosyncratic” browser engines, it’s a wonder the world wide web works at all.
Let’s talk about the humble
<meta> element. As its name suggests, it contains metadata about the document. A typical element might look like this:
<meta name="description" content="Search our shop for great deals!">
What can the
content tag contain? Text! Specifically, text where certain characters have to be encoded into their HTML entities. Now, to be fair, neither the W3C specification nor the WHAT-WG spec mention how text should be encoded. They both just say:
The value must be a free-form string that describes the page.
Obviously, you should encode a
" character to
" because otherwise the browser might think that’s the end of the string. But the spec doesn’t mention that when talking about meta elements.
Create a document which has this meta element:
<meta name="description" content="My name is "Terence <em>Eden</em>" what's yours?">
And you’ll see this echoed into the page:
Eden" what's yours?">
Most browsers interpret rogue HTML in the
“Search for the hero inside yourself (ukulele cover)”
The John Lewis shop website had this problem. If you searched for
lorem<em>ipsum you saw this:
The server correctly encodes the text in:
<meta name="description" content="Search results for "lorem<em>ipsum" on John Lewis & Partners. Free delivery on orders over £50" />
But it incorrectly encoded it in the OpenGraph meta element:
The server is smart enough to filter out
Here’s a basic circle injected into the page:
With a well enough crafted SVG, an attacker can perform a complete site takeover or other malicious activity. Because the content is sent in the
GET request, an attacker can send malicious URl which looks like:
John Lewis doesn’t have a security.txt available, and I couldn’t find anything on their website about reporting security issues.
So I sent a Tweet.
@jlandpcustserv how can I report a cybersecurity problem with your website?
Do you have a responsible disclosure policy?
— Terence Eden (@edent) January 5, 2020
When that didn’t get a response – presumably because it wasn’t a complaint about a missing order – I asked my security buddies. They forwarded on a message. That’s great for anyone well-connected, but not a long-term solution.
Eventually, Twitter customer service coughed up the security team’s email, so I sent them a write up on the 9th of January. I got back a generic and slightly dispiriting response:
Where can I exchange all this Karma++ for biscuits? pic.twitter.com/YUZluHC47z
— Terence Eden (@edent) January 10, 2020
A few days later, it was fixed. That’s a pretty good response time! I understand that John Lewis will be working on a responsible disclosure programme – but until then, reporting via Twitter seems to be the best way to go.