Using APIs with Care - Applying Successful Coding Practices - Security for Web Developers (2015)

Security for Web Developers (2015)

II Applying Successful Coding Practices

7 Using APIs with Care

Application Programming Interfaces (APIs) provide a means of using full-blown applications on someone else’s server to meet your specific needs. Working with an API means sending a request to a black box and receiving a response of some sort back. The request can be as simple as a function call, but often requires that you supply data. The response can be in the form of data, but could also be some other service. For example, there are APIs for performing physical tasks such as opening doors. In fact, APIs can likely meet any generic need you might require. This chapter discusses the security implications of using APIs, including how APIs differ from libraries.

Part of discovering the security threats that APIs represent is viewing coded examples. This chapter uses a simple example as part of the explanation process. Even though you could use the target API for a significant number of application tasks, the point is to create some to use for discussion purposes and then look at how the use of an API could create problems for any application. View the example in this chapter as a point of discussion, rather than an actual programming technique.

Even though this chapter does discuss specific APIs in both coded examples and as examples of where APIs can go wrong, the intent isn’t to single out any particular API. Every API you use could have serious flaws that enable a hacker to gain access to your system or cause other sorts of problems for your application. The specific examples help you understand how all APIs can go wrong in general. In short, you shouldn’t see the specific examples in this chapter as an indication of particular APIs to avoid using.

Of course, the result of all this exploration is to determine how you can use APIs safely as part of your application development strategy. Because APIs are so beneficial, you won’t see them go away anytime soon as a bad idea from a security perspective. In fact, you can count on the use of APIs to expand because developers have constant time crunch issues that APIs solve. As more people use web-based applications and those applications become more complex, you can count on the use of APIs to expand to meet specific needs. As usage increases, so does the appeal for creating exploits by hackers who want to access your data and use it in ways you never intended. In short, if anything, the security footprint of APIs will increase, so your diligence in using them must increase as well.

Differentiating Between APIs and Libraries

Some developers think that all sources of outside code are the same. However, APIs and libraries differ in some significant ways. For example, APIs represent an out-of-process because they run on another server, while libraries represent an in-process call because you include them as part of your application. Just the matter of out-of-process versus in-process significantly changes the way in which you must view security issues. The following sections help define the differences between APIs and libraries better so that you get a better understanding of the security implications of using one over the other.

Some people use library and API interchangeably, but the two have specific meanings in this book. Chapter 6 defines libraries in details, but essentially, a library is external code you incorporate into an application using whatever technique the host language requires. You use libraries directly in your code as part of the application. As a result, a library is always an in-process coding technique, even when the library source resides on a third party server. In order to use the library, the code on the third party server downloads onto your server and becomes part of the application, running in the same process as the application.

This book also differentiates between APIs used to perform tasks and those used as part of an application development effort. For example, the JavaScript Web APIs described at http://www.w3.org/standards/webdesign/script define the JavaScript language elements. This sort of API defines a language used for scripting purposes. Yes, this is a legitimate API, but not in the context used in this book. The book context is more along the lines of a Web service, rather than a language-specific specification.

Considering the Differences in Popularity

Libraries and APIs both provide benefits to the developer by saving development time. In fact, most web-based applications today use a combination of libraries and APIs to perform tasks. However, APIs appear to be gaining in popularity faster than libraries for some good reasons:

• Reduced Resource Usage: APIs run on someone else’s server, so you don’t need to worry about obtaining the required resources. However, the fact that the code runs on someone else’s server also means that you lose control of your data at some point and never see the actual API code so that you can assess the security threats it represents.

• Decreased Coding Requirements: Using an API is often easier and requires less code than using a library. Of course, you also have less control over an API. The tradeoff is flexibility and the price is complexity. Given that developers are increasingly overloaded, the reduced coding requirements of APIs can make them quite attractive. However, the reduced flexibility also represents a potential source of security issues because you can no longer tailor code usage to meet your particular requirements.

• Smaller Learning Curve: It’s usually easier to learn how to use an API than it is a library because the API is generally in a client/server form. The biggest issue is determining how to format the data so that the API understands what you want it to do. It’s in the data formatting that the greatest security issue exists. A hacker could cause malformation of your query that causes the server to crash or force the server to respond in unexpected ways. Because the query source is traced to your application, the host will blame your application, rather than the hacker that caused the problem.

Defining the Differences in Usage

It isn’t possible to use APIs in every case that you use a library (and vice versa). Some situations call for an integrated approach. For example, you can’t easily code a user interface using an API—it really does call for a library. (You can obtain the data for the user interface, as described for the Google API example later, but this is different from actually creating the interface elements.) The following list describes typical uses for APIs and their security implications:

• Data Query: The most common use for APIs is to make a request and obtain data as a result. The request commonly contains the parameters of the requested data. A data source can include databases, sensors, calculations, and analyses. Whenever you deal with data, man-in-the-middle attacks are common. However, a hacker could simply choose to modify the data in order to mislead you or to use the received data as a method for gaining access to your network.

• Supervisory Control and Data Acquisition (SCADA): The Internet of Things (IoT) relies on web interfaces to perform a number of SCADA tasks. For example, with the right thermostat, it’s relatively easy to adjust the temperature of your house using a web application from your smartphone, wherever you might be. A hacker could easily plug into the same interface and lower your house temperature until the pipes freeze or make it so hot that you need to open the doors when you get home. Of course, SCADA encompasses all sorts of things, including industrial controls. In this case, a breach of security not only affects data, but has physical effects as well.

• Monitoring: A middle ground between data query and SCADA is the act of monitoring systems. For example, the police may want to monitor certain street cameras during a protest or other event. APIs make it possible to create applications that can monitor any camera, anywhere, as needed to provide protection for the general populace. A hacker could trick the same API into providing false information.

• Multimedia: An API need not work only with textual or other abstract data. It can also perform tasks related to the other senses, with visual and audio being the most common. The control and manipulation of multimedia creates an environment in which users interact with applications in non-traditional ways and the results are often surprising. By combining multimedia with data science, it’s possible to recognize new patterns and objects in everyday situations, enhancing a user’s ability to perform tasks, such as visualizing scenes in ultraviolet, which might otherwise be impossible. However, it’s important to realize that multimedia is simply another form of data and data of all sorts is easy for hackers to intercept, corrupt, and otherwise manipulate in unwanted ways.

• Location: Even though geolocation is the most common form of location acquisition, query, and manipulation, it’s important to understand that APIs exist to work with all sorts of location information. Location, like multimedia, is a special kind of data. In this case, it provides a two- or three-dimensional point in space relative to a particular target space, such as the earth. For that matter, some APIs add a fourth dimension to the equation, time. Imagine what would happen if hackers chose to modify location data such that two objects, such as cars, attempted to occupy the same space at the same time (resulting in a crash).

Extending JavaScript Using APIs

It’s important to consider security from a real world perspective. The following sections describe some issues in locating appropriate APIs for testing and application development purposes. You then look at an example for the Google Maps API in action. This simple application demonstrates the need to consider issues such as malformed requests, server errors, and errant data return. The example is interesting because it does demonstrate how to create an application that works with the browser canvas to draw part of the user interface based on API return data.

The best way to work with the example described in this section is to use the downloadable source, rather than type it in by hand. Using the downloadable source reduces potential errors. You can find the Google Maps API example in the \S4WD\Chapter07\GoogleAPI folder of the downloadable source.

Locating Appropriate APIs

JavaScript provides an extensible programming environment that supports both APIs and libraries. Developers have taken advantage of both forms of extensibility to create some astounding sharable code that performs tasks that you might not think possible. For example, it’s possible to use a JavaScript application to interact with the vibrate feature of a mobile device to create special effects (check out the technique at https://developer.mozilla.org/en-US/docs/Web/Guide/API/Vibration). With the right resource, you can find an API to perform just about any task you can think of. The following list provides you with some ideas of where to look for that API of your dreams:

• {API}Search (http://apis.io/)

• 40 useful APIs for web designers and developers (http://www.webdesignerdepot.com/2011/07/40-useful-apis-for-web-designers-and-developers/)

• API Directory (http://www.programmableweb.com/apis/directory)

• API For That (http://www.apiforthat.com/)

• APIs Dashboard (http://www.programmableweb.com/apis)

• APIs Data.gov (https://www.data.gov/developers/apis) (click the “browse the current catalog for APIs” link)

• Guide to Web APIs (https://developer.mozilla.org/en-US/docs/Web/Guide/API)

• MashApe (https://www.mashape.com/)

• Public APIs (https://www.publicapis.com/)

• Web API Interfaces (https://developer.mozilla.org/en-US/docs/Web/API)

This is just a sampling of the API search sites online. Most of them provide write-ups on the APIs; some sites also provide reviews. Before you select a particular API, make sure you read as much as you can about it. Perform tests with the API on a test system. Make sure you verify the sorts of data that the API actually transfers between your test system and the host by using a packet sniffer. Even though it may sound a little paranoid to test APIs in this way (see the “Accessing APIs Safely from JavaScript” section of this chapter for additional details) performing the tests helps reduce your risk. Remember that security is always a balance between risk and the benefits you obtain from taking the risk.

Some API providers have so many APIs that they provide their own listing. For example, Google provides a wealth of APIs and you can find them listed on GData API Directory at https://developers.google.com/gdata/docs/directory. It’s important to realize that many host-specific listings contain biased information and reading about the capabilities and deficiencies of the API on another site is always recommended.

Creating a Simple Example

Creating a secure application that relies on APIs is harder than you might think because even the best APIs rely on a certain amount of trust. You trade the risk of trusting the host for the data or other resources the host provides. To see how the security issues come into play, this section works through a simple example that uses the Google Maps API. In order to make the API usable, it also relies on the jQuery (http://jquery.com/) and jQuery UI (http://jqueryui.com/) libraries to display the data and associated user interface. Rarely will you use an API without also relying on libraries to interact with the data in some way.

In order to use this example, you must obtain a developer key. Google provides two kinds of keys: paid and free. You only need the free key for this example. The paid key does provide considerably more flexibility and you’ll likely need it for any full-fledged application you create. However, for experimentation purposes, the free key works just fine. You can obtain this key at https://developers.google.com/maps/licensing. Make sure you understand the terms of service fully before you begin working with the Google Maps API. You can also find some additional assistance in using the Google Maps API with JavaScript at https://developers.google.com/maps/documentation/javascript/tutorial.

It’s best to create the code for this example in several steps. The first is to add the required jQuery references shown here.

<script
src="http://code.jquery.com/jquery-latest.js">
</script>
<script
src="http://code.jquery.com/ui/1.9.2/jquery-ui.js">
</script>
<link
rel="stylesheet"
href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />

Even though the code makes a reference to an external library, the code from the library is included as part of the application as an in-process element. Chapter 6 describes all of the security issues regarding library use. In addition, you also need to add a reference to the Google Maps API as shown here.

<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=Your Key Here&sensor=false">
</script>

This example won’t work at all unless you replace the words, Your Key Here, with the key that you receive from Google. Consequently, this particular step is important because it’s the one step that you must perform even if you’re using the code downloaded from the book’s site.

Even though both the library and the API references rely on the <script> tag, the manner in which they use the tag is different. Notice that the library accesses a file without any additional information. The API requires additional information in the form of a key and a sensor configuration option in this case. As the section progresses, you’ll see other differences.

Now that you have all of the required references in place, it’s time to create a canvas to draw the map. The canvas is simply a <div> as shown here.

</div>
<div id="MapCanvas">
</div>

You must provide style information that gives the <div> size or else the map won’t appear on screen, even when Google sends it to you. The example uses the following style information:

#MapCanvas
{
height: 90%;
width:100%;
}

In addition to the canvas, the example provides two textboxes for input and a button you can use to request a new map. There isn’t anything too complex about the interface, but it gets the job done (the example is preset to show the location of Milwaukee, Wisconsin in the center of the map—you can change the longitude and latitude to any other location you wish).

<div id="Input">
<label for="longitude">
Longitude:
</label>
<input id="longitude"
value="-87.95"
type="text" />
<label for="latitude">
Latitude:
</label>
<input id="latitude"
value="43.04"
type="text" />
<input id="submit"
value="Get Map"
type="button" />
</div>

The code for this example uses many of the jQuery and jQuery UI tricks you’ve seen in other applications. For example, the application creates a spinner for the longitude and latitude controls to make it easier to move the center of the map incrementally. Moving an entire degree at a time wouldn’t make the application very useful, so the two spinners change the inputs by a tenth of a degree at a time (even this setting may be too large and you might want to change it). Notice the use of the step option to perform this task. Of the code that follows, the GetMap() function is the most important because it actually displays the map on screen.

Latitudes range from 90 degrees north to -90 degrees south, so the example reflects this requirement. Likewise, longitudes range from 180 degrees west to -180 degrees east of Greenwich, England. You can read more about latitude and longitude athttp://geography.about.com/cs/latitudelongitude/a/latlong.htm.

$(function()
{
// Track the current latitude using a
// spinner control.
var Latitude = $("#latitude").spinner(
{
min: -90,
max: 90,
step: .1,

change: function(event, ui)
{
if (Latitude.spinner("value") < -90)
Latitude.spinner("value", -90);
if (Latitude.spinner("value") > 90)
Latitude.spinner("value", 90);
}
});

// Track the current longitude using a
// spinner control.
var Longitude = $("#longitude").spinner(
{
min: -180,
max: 180,
step: .1,

change: function(event, ui)
{
if (Longitude.spinner("value") < -180)
Longitude.spinner("value", -180);

if (Longitude.spinner("value") > 180)
Longitude.spinner("value", 180);
}
});

// This function actually displays the map on
// screen.
function GetMap()
{
// Create a list of arguments to send to Google.
var MapOptions =
{
center: new google.maps.LatLng(
Latitude.spinner("value"),
Longitude.spinner("value")),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}

// Provide the location to place the map and the
// map options to Google.
var map = new google.maps.Map(
document.getElementById("MapCanvas"),
MapOptions);
};

// The example provides two methods of getting a
// map: during page loading or by clicking Get Map.
$(window).load(
function()
{
GetMap();
});

$("#submit").click(
function()
{
GetMap();
});
})

The GetMap() function performs the actual task of obtaining the map. To do this, your application must create a list of map options. The example shows a simple, but typical list. The most important of these options is where to center the map. In this case, the map automatically centers itself on Milwaukee, Wisconsin, but you can change the settings to any location you want. The example uses a zoom factor of 8 and you’ll see a road map. The Google Maps API actually provides a number of map types that you can try.

There are two times when GetMap() is called. When the application loads, you see Milwaukee, Wisconsin (unless you change the default settings). After you change the inputs, you can also click Get Map to display a new location. Figure 7-1 shows typical output from this application.

image

Figure 7-1. The example can show any location for which you have a longitude and latitude.

This chapter doesn’t provide a detailed look at the Google Maps API, which is relatively complex. What it does provide is a simple look at something you could easily expand into a full-fledged application later. Many organizations today use maps for all sorts of interesting purposes. The article at http://blog.smartbear.com/software-quality/bid/242126/using-the-google-maps-api-to-add-cool-stuff-to-your-applications provides some additional ideas on how you can use the Google Maps API with your browser-based application.

Defining the Security Threats Posed by APIs

It’s important to know what sorts of API threats you might face as a developer. Even though the following sections may not contain the most recent of API threats, they do represent various kinds of API threats and provide you with the kind of information needed to help research the latest threats to your application. These real world examples make it possible for you to understand what sorts problems you’ll encounter.

Ruining Your Good Name with MailPoet

Blogging represents a major investment of time for many people. I use my blog to communicate with my readers and tell people about my latest self-sufficiency efforts. You can find a blog for just about any purpose and on just about any topic. People place their reputations in their blogs as a way to help the world as a whole. So, when a blogging software plugin, such as MailPoet, has a problem, it can affect the reputations of every blogger who uses it. That’s precisely what happened on July 1st, 2014.

The vulnerability allows the attacker to place any PHP file on the system using a remote upload, which means that your blog may now serve up phishing attacks with the information it used to provide. At first the hack would cause the site to crash in some cases, but this flaw has since been fixed, so unless you’re vigilant, you may not even know you’ve been hacked.

A problem with this particular vulnerability is that the entity that discovered the problem (Sucuri) didn’t apparently give MailPoet enough time to fix and distribute a fix before revealing it, so there is lots of finger pointing going on. This particular plug-in has been downloaded 1.7 million times, but is used on multiple blogs by some individuals, so it significant potential to cause problems. The MailPoet threat is an example of the need to verify API security before you begin development and to perform constant checks as you continue to use the API.

Developing a Picture of the Snappening

SnapChat is a great way to exchange photos with other people in a way that isn’t permanent. The purpose of the service is to allow a freer flow of information in an environment with fewer risks. It actually does work when everyone plays by the rules, but not everyone does (as explained inSecurity Lessons Courtesy of Snapchat).

The API is extremely easy to hack because of a flaw in a third party library. Instead of actually fixing the problem, SnapChat has responded recently by admonishing users not to download third party programs that allow them to overcome the built-in rules. The result of not providing a solid API in this case is the leaking of 90,000 plus pictures that are likely more revealing that anyone cares to know. Talk about a loss of reputation! Of course, the usual amount of extortion will take place and it’s unlikely that anyone will ever be able to track down the monetary implications because no one will be willing to talk about it.

The short take on this particular API hack is that it just doesn’t pay to use some services—no matter how appealing they might be. This particular threat demonstrates the need to check vendor reputation before you begin development using the API. In addition, it shows that you need to research the API before using it because many hackers knew of this flaw before the trade press started making an issue of it.

Losing Your Device with Find My iPhone

The Find My iPhone service is supposed to protect your iPhone should it get lost. You can locate your iPhone, see where it has been, and lock it to keep prying eyes away. However, Apple didn’t secure access to iCloud, the service that supports Find My iPhone, very well. It’s vulnerable to a brute force attack—one in which the attacker keeps trying passwords until one is successful.

Some hackers discovered this flaw and used it to lock people’s iPhones. For a small sum of $100, the victim could get their iPhone unlocked. If the victim resisted, the hackers promised to erase all their data. The only way around the problem without paying is to restore the device to factory settings. Fortunately, this story does have a happy ending, the hackers have been arrested. No one is saying just how many people paid the fee, how many lost their data, and just how many phones were hacked, but to create this much press it has to be more than a few.

This particular threat is an example of the need to test inputs and outputs. By thinking through how the API worked, it’s possible that developers could have figured the brute force approach out sooner than later and avoided potential problems.

Leaking Your Most Important Information with Heartbleed

You depend on Secure Sockets Layer (SSL) to provide secure communication between client and server. Unfortunately, like any other piece of software, SSL can contain vulnerabilities. In this case, the use of a feature called a heartbeat in OpenSSL versions 1.0.1 through 1.0.1f allows an attacker to gain access to user passwords and long term private keys used to encrypt communication.

According to InfoWorld, Heartbleed was to blame for the Community Health Systems breach that released patient records for 4.5 million patients. The price tag for just this one breach could cost up to $150 million. The interesting thing about Heartbleed is that it has serious staying power. According to ComputerWorld, as of June 24, 2014, there were still 300,000 servers that were susceptible to Heartbleed (which is a long time for applying a patch given that the vulnerability was discovered in April). The Heartbleed vulnerability is so serious that it has spawned its own information site, http://heartbleed.com/.

You should see this threat as a wakeup call not to trust any particular API to remain secure. Hackers are constantly testing the waters to see just what they can get by with. In this case, constant testing of the API might have yielded information about the vulnerability before it became a problem. Certainly, relying on just one means of securing information is probably not the smartest thing to do.

Suffering from Shellshock

Some pundits are calling Shellshock worse than Heartbleed. It’s hard to say that one is worse than the other when both are incredibly bad and affect a large number of servers. In this case, a bug in the bash utility used by Linux administrators can be hacked by creating a malformed environment variable and then running a bash script. Access to this functionality can be provided through the Common Gateway Interface (CGI) or PHP.

The biggest limiting factor for this hack is that it isn’t automatically exploitable—there has to be an outside interface to access the server. There are reports that larger organizations, such as Yahoo and WinZIP have been hacked using Shellshock. The potential for Shellshock hacks is huge because the number of affected servers is larger than those affected by Heartbleed. In addition, a viable patch was longer in coming; although, one is in place now.

This is an example of keeping your data localized under lock and key. By providing an outside interface to critical data, organizations open themselves up to data loss. Keeping sensitive data under wraps is the only way to ensure that it actually remains secure. Of course, you need to make some data accessible, but doing so should be the option of last resort and you should make only the required data available.

Accessing APIs Safely from JavaScript

It’s possible to access APIs safely using JavaScript if you perform some testing first. Of course, testing takes time and you may encounter resistance to spending the time to ensure the API works as advertised. All you really need to do is ask about the value of the organization’s data compared to the time required for testing. The answer is usually obvious, the data is always worth the testing time. With this in mind, the following sections describe some measures you can take in using APIs safely.

Verifying API Security

The “Defining the Security Threats Posed by APIs” section of this chapter describes some of the threats that APIs can present to the developer. Unfortunately, the trade press often expose these threats after you implement a solution using the API, making it hard to change the API you’re using without incurring a huge cost. However, verifying that the API is currently clean by looking for stories about it is always a good place to start.

It also pays to look at the vendor’s reputation for security. New vendors are untested and therefore, unreliable. You use them at a much greater risk than a known vendor, one who has had products on the market and tested for some amount of time. Partially offsetting the new versus experienced vendor is the fact that hackers also target vendors with a larger market share in order to improve the odds of getting something truly useful in exchange for their efforts.

The manner in which the API is constructed, the documentation provided, and the amount of input requested for calls all point to the level of security provided. It may be a nuisance to sign up for a service provided by Google, but the fact that you must use a special key to access the API can reduce the APIs attack surface at least a little. In addition, the Google APIs don’t ask you to provide sensitive data; although, an attacker could possibly derive some data by simply looking at your requests. For example, asking for maps at specific longitudes and latitudes could mean a new business venture in the area or some other reason for the increased attention.

The Google API is a good choice for the example in this chapter because Google has a relatively good reputation for security. In addition, it’s easy to verify that you actually are interacting with Google in most cases and that the results you receive are of the right type. Google’s documentation helps you perform the sorts of checks that make it easier to verify that the API is secure.

Testing Inputs and Outputs

A simple way to verify the usefulness and security of an API is simply to test known quantities. Check known inputs and outputs to ensure the API works as advertised. It may surprise you to discover that some APIs really don’t work as advertised. In some cases, the problem isn’t one of actual coding errors, but one of not understanding how the API works.

Of course, many organizations perform an input/output test during the initial design and development phase for an application. However, creating a test harness lets you perform the tests at random. The benefit of this approach is that the tests can help you detect potential data corruption or other potential security problems. Running tests at intervals helps you ensure that the API remains viable. The tests also tend to trash any conclusions eavesdroppers may make about the queries you make against the API.

The Google Maps API example in this chapter should have also included code to verify both the input and output data. These checks were left out in order to make the application easier to understand. However, in a real application, you need to test the data before you submit it and verify that you get the kind of information you expected as a return value. Of course, it’s not possible to check the data specifically because the map will change with each call.

Keeping Data Localized and Secure

The more data you send to an API, the higher the probability that someone will intercept that data. The data need not be intercepted en route to present a problem. If the data ends up residing on the host’s server, then anyone accessing the server can likely access the data as well. The best way to keep a secret is not to tell anyone. Sharing as little data as possible with an API is a good idea.

The use of an encoded key with the Google API is a good security measure because it positively identifies your organization. However, the key is important for another reason. In some cases, other APIs use identifiers that a hacker could track back to your organization. Anyone intercepting the Google key won’t know anything more about your organization than before.

One example of an API that used to require input that a hacker could track back to an organization was Amazon.com. Some APIs used to rely on the associate identifier that an organization also attaches to links for buying products. A hacker could discover this identifier with relative ease and could begin tracking an organization’s API calls as well.

Coding Defensively

When writing your application, always assume the inputs and outputs are wrong, that the user is going to handle everything incorrectly, and that there is a hacker looking over your shoulder. Yes, developers need to develop a sense of true paranoia in order to avoid some of the problems prevalent in applications today. As the book progresses, you see the usefulness of techniques such as API sandboxing in order to determine just how bad, bad can be when it comes to interacting with the API. The important thing is to assume nothing about code—even the code you create.