Read an Excerpt
Professional Cocoa Application Security
By Graham J. Lee
John Wiley & SonsCopyright © 2011 John Wiley & Sons, Ltd
All right reserved.
Chapter OneSecure by Design
WHAT'S IN THIS CHAPTER?
* Understanding your application's security needs
* Discovering the threats to your users
* Identifying potential vulnerabilities
As with any other class of bug, addressing a security issue becomes more expensive the longer you wait to fix it. If there's a problem in the design of the application, trying to fix it in a bugfix release will be very costly because you'll need to change multiple classes. You'll also need to understand and account for the myriad uses and configurations your customers have in place, and be ready to support migration of all these to the new, fixed version of the application. Addressing the issue the first time around means not only spending less time on the issue, but also avoiding the additional (direct and indirect) costs of a security vulnerability out in the field and coordinating a fix release. I once worked on a project for which we spent about three weeks addressing an issue that had been caused by a bad choice of file system path in the planning phase, some years earlier.
Of course it's not going to be possible or even desirable to identify and fix every single vulnerability before writing any code. That's a recipe for spending a great deal of money and taking a very long time to get to market, by which time your competitors will have gotten their apps to the customers. There is a principle software engineers have borrowed from economics called the Pareto Principle, also known as the "80/20 rule." The principle says that 80 percent of the observable effects in any situation are often the result of only 20 percent of the causes. It's a good idea to follow the 80/20 rule in software design - addressing only the most important issues so that the product is of a high enough quality to ship. Which of course leads us to the question, "Which are the important issues?"
ABOUT COCOA SECURITY
Users of your application do not think about what technology was used to create it - whether it was written in Cocoa, Carbon, or Java. What they care about is using the app on their iPhones or their Macs to get their work done. Similarly, their concerns regarding security come not from Cocoa-specific features or issues, but from how the application's security helps or hinders them in doing their work (or, in the case of a game, in having their fun). Your model of the important security considerations in your app will therefore be largely technology-agnostic, although there are vulnerabilities specific to Objective-C and Cocoa, as discussed in Chapter 9, "Writing Secure Application Code."
The particular capabilities and APIs available in Cocoa and Cocoa Touch applications become more relevant when you determine how some of the threats you identify might be exploited by an attacker. Cocoa applications on the Mac are part of a multi-user system, as explained in Chapter 2, "Managing Multiple Users," so understanding how the different users can interact through interprocess communication or by sharing files on the file system will help you decide whether particular interactions could lead to one user's threatening the security of another. Prioritizing security issues will always be based on an understanding of what your users are trying to do and how that fits in with their processes and with the environment.
You must also have Cocoa-specific features and technology in mind when deciding how to mitigate the threats that attackers may be posing to your application and its users. Users will expect your app to behave in the same way as others on the Mac or iPhone platform, which can be easily achieved if you adopt the frameworks Apple provides for the purpose. As an example, if your application stores a user's password, he will expect it to use the keychain to do so, because then he can change the settings for that password in the same way as for all his other applications. Keychain Services are described in Chapter 5, "Storing Confidential Information with the Keychain."
We must now leave Cocoa behind temporarily for the rest of this chapter, as we discuss the principles of application security and discover the threats your users will face as they use your application. These are threats that will be present however you choose to write the app.
PROFILING YOUR APPLICATION'S SECURITY RISKS
To understand an application's security profile is to understand what risks exist in using that application. That means understanding what your users want to do, what obstacles they might face in getting it done, and the likelihood and severity of those obstacles. Obstacles could come in the form of people attacking the system in some way to extract something of value; honest people could also make mistakes interacting with the application. Either way, a risk is posed only if the application presents the opportunity for the obstacle to upset the user's work. Figure 1-1 shows how these components go together to form a vulnerability: a possibility that users can't get their work done safely in the application.
By extension, secure application development is meant to mitigate either the likelihood or impact of those obstacles; you want to reduce to an acceptable level the risk involved in using your app. You can mitigate risk by preventing an attack from occurring, limiting an attack's impact, or detecting and responding to an attack that is already in progress or complete.
So what presents the greatest risk to your customers? Answering that question is the focus of the rest of this chapter.
Remember that while the discussion is about planning, design, and implementation as if they were separate phases, it's very useful to treat security as an iterative process. Rather than writing a nice security document while designing your app and leaving it to gather metaphorical dust on the hard drive, reevaluate the security model whenever you do a bugfix release or add a new feature. Verify that the issues you prioritized the last time around are still relevant as customers find new uses for your application, or as new classes of vulnerability are discovered and reported by the security community. Have another look whenever a competitor releases a security fix - did you already address that issue, or is your application vulnerable? Automated tests, discussed further in Chapter 9, can be applied just as readily to security practices as to functional testing. You can encapsulate your security assumptions in unit tests or regression tests and discover whether the assumptions continue to hold as the application evolves. Your understanding of the security issues your app faces is therefore critical if you are to have any confidence in the security of your application. This chapter will discuss the creation of a threat model, a description of the hostile aspects of the environment your app is in, and of how well the app can protect itself and its users. Maintaining this threat model in electronic form is a must to make it easy to update, and it's a good idea to keep it in the same version control system as your source code so that the state of any version or branch of the application is easy to find. Consider using a database application such as Bento so that the different attackers, threats, and vulnerabilities can be indexed and cross-referenced.
DEFINING THE SECURITY ENVIRONMENT
Identifying the Application's users
You should already have some idea of who will be using your app, since you have a customer for your application in mind and have been designing the user interaction for the benefit of that customer. So who is the user? Think about whether you have different classes of users in mind. If so, which is the most important? What will the users mainly be doing with your application? It is important to understand the users' expectations and needs so that you can think realistically about how they will prioritize different risks, how they will react to security issues, and how well they understand the security implications of working with your app. Knowing how your users are working with your application also leads to a better understanding of the risks they could potentially expose themselves to. Which features of the application will they turn on? Will they leave the preferences window alone, or play with every control available? The answers to these questions will help you concentrate your effort on securing the default and most likely configurations of your app.
You should also think about how technically competent your user is, in relation both to the use cases of your application and to computers (and networks, if relevant) in general. How much information is it appropriate to give the user about what your application is doing, and how much can be treated as "magic" that happens behind the scenes? Should a decision need to be made about a security-related question, is it appropriate to make the decision on the user's behalf or ask that user about it? Or should the decision be made automatically based on a configurable default? If the application does it automatically, should the user be notified or can it be hidden? Users will appreciate an application that does not ask them any more questions than it needs to, and will be frustrated by one that asks them questions they do not understand. It is not acceptable to wash your hands of security concerns by saying, "I asked the user what to do, and he chose the insecure option." Aim to provide a great user experience by taking responsibility for the security decisions - after all, you're the one who has read this book (and if your competitors haven't, then you get the jump on them).
Closely related to this collection of questions is the question of how likely you think your target user is to make mistakes while using your application. Will this user carefully consider the meaning of any question you might ask, or just hit whichever button is farthest to the right of the dialog? This depends quite strongly on the environment in which your application is used. If your users sit at desks in offices and rely on the application to do their day jobs, then it's quite likely that they'll concentrate on what's going on in the application and pay attention to everything that happens. On the other hand, if you're writing an iPhone utility, the user may be in a noisy, distracting environment when using the application. If the users are outside in bright sunlight you can't even rely on their being able to see the display well, let alone concentrate on it. Their interaction may be limited to launching the app and clicking a couple of buttons before putting the device away again, without worrying about the details.
In that environment users may unwittingly expose themselves to risks by failing to understand or consider at all the consequences of their interaction with the application. In such cases you should be designing the workflow to reduce exposure to risk by minimizing the number of decisions users have to make regarding security, and by making it easier to choose the lower-risk paths through the app than those paths with higher risk.
The users of the application may also turn out to be misusers - people who can access the application to perform unintended tasks. There is the possibility that a user could accidentally cause a security incident; is there also the chance of a user's going rogue and deliberately attacking other users? An often-cited example is that of an employee who, dissatisfied with the behavior of the company, uses its internal applications to cause it, or specific employees, damage. Such inside attacks can be more damaging than external hacker attacks, as the user already (legitimately) has greater access to the company's facilities and assets. For each of the users you have listed, you need to think about whether this user could become a misuser, and if appropriate to list him or her among the misusers, as described in the following section.
To represent the information you have gathered about your users in a useful and succinct form, create a description of each type you identify. A common technique in user experience and marketing circles, which can help you think about who these users are, is to create a profile of a typical individual in each class of user. These profiles are known as personae; for each persona choose a name and even find a photo to put a face to that name. Assign them brief biographies and quotes about why they are using your application and what security concerns they have. Provide each persona with a one- or two-sentence answer to each of the questions asked earlier in this section (along with any others you think could be important for your app). This will help you to reason out the needs and wants of the users by letting you put yourself in their shoes. If you are using a database to prepare your threat model, then each of these descriptions would be a single row in a table. See the following example, "ThyTunes: User List," for two sample personae relating to the ThyTunes application described earlier.
Identifying the Application's Misusers
Understanding who your users are has helped you see how they think about security, what their concerns are, and how willing and prepared they are to contribute to the security of your application. You can consider the misusers of the application in the same way. Misusers are those people who would - intentionally or otherwise - compromise the security of your application and your users; they are attacking the application. When you discover and list the attackers, it's best to include everyone you can think of. Leave discounting certain attackers until you've gotten enough candidates to usefully rank them in order of importance. Considering an unimportant attacker will waste some time, but failing to account for a likely case will undoubtedly cost time, money, and customer goodwill. Remember, too, that the attackers don't have to play by your rules, so don't discount a potential misuser because you find a certain type of exploitation distasteful. An important class of attack might fall through the cracks if you are unwilling to face the idea that the attacker exists. If your app will be used by a charity or religious group that could have enemies for ideological reasons, you need to consider the threat those enemies will pose.
You should collect two important categories of information in order to build up a profile of the attackers: who they are and what their motivation is in attacking your application and its users.
As with the users, create a persona for each class of attacker you have identified, with a mini-biography addressing each of the points described above. Two such personae are shown in the following "ThyTunes: Misusers" example.
Put the attacker's goal and motivations for achieving that goal in his or her own words - computer security can seem at times like a very abstract universe, so having a name and a face for your attacker will make the threats seem more real. Keep the attackers and the users together in the threat model - in this context, they are both classes of people who could misuse your app, for whatever reason.
Who are the attackers? Referring to the information you have already gathered about your users makes it easier to reason about who might be targeting them. If your application tracks online banking transactions and you expect a number of elderly customers, then there's a reasonable chance that an attack might come from a family member who wants to see how much money is in an account (or even change the amount). If your application deals with medical information there are a host of people who could potentially want unauthorized access.
Excerpted from Professional Cocoa Application Security by Graham J. Lee Copyright © 2011 by John Wiley & Sons, Ltd. Excerpted by permission.
All rights reserved. No part of this excerpt may be reproduced or reprinted without permission in writing from the publisher.
Excerpts are provided by Dial-A-Book Inc. solely for the personal use of visitors to this web site.