Instagram's Non-Validation of AJAX calls is a Boon for Bots

bots
Published on November 8, 2016

In early days of web development I was reading a book on web security. The first line of the book was "The client should not be trusted". The client here refers to anything that makes a request to the server, for example a browser. It is the server's responsibility to sanitize everything that comes from the client.

Although a very basic rule, I have seen big players sometimes trusting the client.

Inspecting Instagram

It seems Instagram has developed a query language similar to SQL for its own purposes (popularly called Instagram Private Api). For example a SQL query "SELECT post_id FROM posts LIMIT 0,10" would fetch first 10 posts from a table. Instagram has a query language on similar lines (see the picture above).

Developing a query language is a very cool thing. But Instagram instead of using this query on its server side, sends the query as a parameter in AJAX requests. The AJAX request shown in the picture sends the query to get the next 10 followers of a user.

More importantly Instagram does not validate all AJAX request parameters on the server side. For example it gets 10 entries with each AJAX request dealing with getting the followers of a user. Anyone can get 100 followers just by replacing 10 by 100 in the parameters of the AJAX request.

This is turning out to be boon for Instagram bots. Marketing guys have seen business in Instagram. Services such as increasing the number of followers are very popular. Of course these services don't increase the no of followers by using human hands — they use bots.

A popular trick to increase your no of followers is to follow a lot of people. These people whom you follow — may follow you back. If you send following requests to 10000 people, 800 may follow you back. Not a bad deal if you are using bots to achieve it.

How An Ideal Bot Would Work

Assume the bot has been given the responsibility to increase the no of followers of a user. To make requests the bot will use a headless browser such as PhantomJS (to reduce suspicion). The bot needs a list of users (ids) on Instagram. It starts with a profile that has large no of followers (this starting profile may be added manually). The bot adds a script that hooks into the XMLHttpRequest function of PhantomJS so that whenever an AJAX request is send to get the followers list, it modifies the no of followers to be fetched to a greater number like 10000. The hooking can be done with the help of Javascript's apply() function. On the server side Instagram does not validate that the request is asking for 10000 followers — more than the permissible limit of 10. It simple executes the request and sends 10000 followers as a response. The bot on receiving the response would go to each of the profiles and follow it (to reduce suspicion it may distribute sending the follow requests in a week's time)

If Instagram were to validate that 10000 is not allowed, it might send an error message. The bot would would have no option but to send 1000 AJAX requests (instead of one) to get 10000 followers. Instagram's Intrusion Detection Systems might turn suspicious to see a client sending 1000 similar requests. It may then take appropriate actions. Bot-ism would be prevented

What Needs To Be Done

Of course this thing not a security issue, but it does not look cool coming from Instagram's side. The first thing Instagram needs to do it to remove the query language from the frontend. There is no need to tell people that internally it uses a query language. They are simply inviting hackers. They can use the query language in the server side.

The second thing would be to validate the AJAX requests.

Bots are a pain to web servers, but nevertheless they are important for research purposes. Servers should take all steps possible to cut down bots. Bots on the other hand are aggressive enough to find better ways to automate. All this will be important to take Artifical Intelligence to the next level.

In this Tutorial