Parameter Tampering Attack on Twitter Web Intents

Twitter’s Web Intents allow visitors of a website to interact with content on Twitter without having to leave the website. This is done by means of a popup for desktop users, and native app handlers for iOS and Android users. This is the same platform powering the “tweet” and “follow” buttons you may see on webpages across the Internet.

I identified a parameter tampering vulnerability that in total affected all four web intent types. These vulnerabilities allowed an attacker to stage a Web Intent dialog with tampered parameters, which could then lead to a visitor following a Twitter user they didn’t intend to follow.

All four intent types were vulnerable: Following a user, liking a tweet, retweeting, and tweeting or replying to a tweet.


Regex Security Issues in Ruby

I see this kind of problem everywhere in the Ruby ecosystem, despite it being an old one.

Consider the regular expression /^https?:\/\/[\S]+$/:

So far so good. However, consider this:

This matches our regex because /^ matches the beginning of a line and $/ matches the end of one. This poses a very common misunderstanding of how Ruby regexes work. The impact of this varies from annoying unexpected input to cross-site scripting to remote code execution; it all depends on what is done with the input.

To properly match the beginning and end of a string, \A and \z should be used respectively.

Feature Flags with Rollout

Role-based authorization is a common requirement in modern web applications. In the Rails ecosystem, there are several great open source libraries that provide this (see devise’s roles, cancan, and rolify).

Feature flagging is a little bit different than roles. Features can be flipped on and off regardless of a users’ state. This means that if we want to test a feature for 50% of users, we shouldn’t need to move those users into a different role. We should just be able to declare that this feature is now flipped on for 50% of all users. The difference is subtle but important.

When BitLove approached this problem several years ago, there weren’t any good open source solutions for this. As a result we decided to roll our own and called it rollout. James Golick pioneered this project before I had joined the team, and it has since gained a large amount of popularity. It has even been ported into other languages (see proclaim, PHP rollout, and shoutout).


Ruby’s OptionParser Is All You Need

This may be the last article on building command line apps with Ruby you’ll ever have to read.

Okay, not literally! But I think you’ll know enough to accomplish quite a lot by the time you’re done reading this.

There are a lot of Ruby gems that help you build command line apps. Thor, Escort, CRI, GLI, Methadone, and executable, just to name some of the libraries out there. While results have varied, I’ve personally had my share of hangups with these gems:

  • I get the whole kitchen sink. ASCII tables and ncurses support? I don’t need those things.
  • Bugs. Real, show stopping bugs. Several of these libraries have a few dozen open Github issues that show no promise of getting fixed any time soon. Call me cynical, but if I’m going to tie this gem into my app as a dependency, I want to have faith it’s going to be maintained.

While building my latest command line app, I eventually gave up and decided to just roll my own with Ruby’s standard libraries. The results were surprising.

It turns out Ruby’s OptionParser library offers everything you need. It’s just not very well documented. For those of you that aren’t familiar with the library, OptionParser parses out option arguments from ARGV (text such as “–option value”). You can also set defaults and define help text. What you’re left with after you call the parse! method is an ARGV array of commands the user passed (i.e. “test units”).


Server Performance Monitoring as an API

I recently setup Cacti to gain more insight on some server performance issues we were facing at work. Previously we had been using NewRelic, but found it to be expensive and limited in the stats it gathered and presented. If you’ve never heard of Cacti, it’s a fantastic in-house solution for network graphing. The graphs are generated using RRDTool, and front-end web interface allows you to set up automated polling of servers using a number of different methods. It’s quite a bit of more work to setup than using a managed solution, but you can tailor the polling to what you’re interested in and gather more in-depth stats.

The most popular method of polling is using the Simple Network Management Protocol, or SNMP. It’s very standards-driven, which is great for network engineers because it means that any device running SNMP can report stats on the same stuff. It’s not so great for developers though, because working with it often involves consulting a type of database known as a management information base, and addressing the stats you’re interested in by OID. You have to know the exact OID you’re interested in (or use a tool like SNMP Walker to “walk” the MIB tree), and some systems differ slightly in the OIDs they implement. I can’t say that SNMP is bad. I’m not a network engineer, so I don’t think I have a place to criticize it. SNMP provides a standardized interface to talk to network devices and can even be used to configure devices remotely. It’s really powerful. However, if you’re like me and you’re interested in just gathering performance stats on some servers, it can take a lot of work to setup.

I thought it would be really cool if there were an API for server performance monitoring. Something that you could just run– securely of course– and would then tell you about the performance of whatever it was running on over HTTP. Then you could have consumers do different things like setup alerts, draw graphs, automatically scale a cluster, etc.I couldn’t find anything quite like what I had in mind, so I decided to start developing something myself. You can find the project here. I’ve named it sys.json, and at this point it’s a proof of concept more than anything. I’ve got it running on my own personal server and it has reported reliably so far. However it isn’t fully tested, nor is the codebase very mature yet, so I cannot recommend that you rely on it for anything mission critical.