Incorporating Libraries - Applying Successful Coding Practices - Security for Web Developers (2015)

Security for Web Developers (2015)

II Applying Successful Coding Practices

6 Incorporating Libraries

It would be hard to find a web application that doesn’t depend on a library—at least, not one of any consequence. Libraries are the epitome of not redefining the wheel. In fact, like wheels, there are libraries of every shape, size, and color out there. Yes, even color comes into play when you consider that many libraries include themes you can use to dress up your site. Consequently, it’s likely that you’ve already spent a fair amount of time working with libraries in some way. In fact, a number of the book examples in earlier chapters relied on libraries simply because rewriting the code from scratch doesn’t make sense.

This chapter doesn’t try to persuade you about the value of using libraries. You’ve likely already sold yourself on their benefit. However, you might not have considered all the ramifications of using someone else’s code in your application. There are always consequences to using libraries. The goal is to use libraries safely so that you get all the benefits of relying on someone else’s code without creating any major security holes in your application. (Be assured, you do create some security holes, it’s impossible to avoid it.)

Getting the Best Library Speed

You may find sites that tell you not to use libraries at all because they incur such use speed penalties (for example, see http://www.giftofspeed.com/dont-use-javascript-libraries/). The fact is that libraries can slow your site down, especially when you don’t use them wisely. The speed hit can be large enough to make people perform the click that takes them to the next site, which means that your site loses out on providing a service or offering some other resource to the people who visit it.

This book generally uses the uncompressed versions of the available libraries to make it easier for you to work with the examples and perform tasks such as using a debugger to examine the applications with greater ease. However, from a speed perspective, you normally want to use the compressed version of the library. The compressed version contains the same code, but it loads faster and sometimes you get a bit of a boost when making calls as well.

It’s also important to realize that you won’t use all of the library code. Many libraries, such as jQuery UI (http://jqueryui.com/download/), provide a builder that lets you create a personalized version of the library that loads. After you discover which parts of a library you actually will use, use a builder to create a version with just those parts in it. The library will load faster and you also reduce the library’s attack surface, which means an improvement in security as well.

Considering Library Uses

How you use a library directly affects how secure it remains—at least, to an extent. For example, direct involvement of the library with your JavaScript code tends to open more potential security holes than using the library to format the page. Of course, any use of a library could open potential security gaps that will cost your organization time, effort, and resources. The following sections discuss how you might use libraries to perform various tasks and consider how the form of usage could create certain types of security holes.

The best way to work with the examples described in this chapter is to use the downloadable source, rather than type it in by hand. Using the downloadable source reduces potential errors. You can find the source code examples for this chapter in the \S4WD\Chapter06 folder of the downloadable source.

Enhancing CSS with Libraries

CSS is all about formatting page content. Given the current state of CSS, it’s amazing to see the sorts of pizzazz you can add to a site. Web developers use CSS to make a boring page pop out. Of course, there are mundane uses for CSS as well. For example, imagine trying to read multi-columned text without relying on CSS to format the content. What you’d end up with is a mess. Using just HTML tags to format the content would make the pages nearly impossible to use on the wide range of devices that people rely on today.

CSS alone could probably do everything you need to create fantastic pages. However, it’s important to realize that even the best web developer doesn’t have time to create all that CSS code by hand. There are a number of ways in which to pack CSS code into a library, but one of the more interesting is the css() function provided with jQuery UI as found in the Transform.html file.

<!DOCTYPE html>

<html>
<head>
<script
src="http://code.jquery.com/jquery-latest.js">
</script>
<script
src="http://code.jquery.com/ui/1.9.2/jquery-ui.js">
</script>
<script
src="jquery.transform.js">
</script>

<link
rel="stylesheet"
href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<title>jquery.transform.js Demonstration</title>
<style type="text/css">
#TransformMe
{
border: double;
border-color: Blue;
border-width: thick;

position: absolute;
width: 120px;
height: 40px;
top: 90px;
left: 75px;
}

#TransformMe p
{
margin: 0;
padding: 0;
height: 40px;
font-family: "Comic Sans MS", cursive, sans-serif;
font-size: large;
color: Red;
background-color: Yellow;
}

#Rotate
{
position: absolute;
top: 190px;
left: 75px;
}
</style>
<script type="text/javascript">
$(function()
{
$("#Rotate").click(function()
{
$("#TransformMe").css("transform", "rotate(45deg)");
});
})
</script>
</head>

<body>
<h1>jquery.transform.js Demonstration</h1>
<div id="TransformMe">
<p>Some Text</p>
</div>
<div>
<input type="button"
id="Rotate"
value=" Rotate 45 Degrees " />
</div>
</body>
</html>

The actual functionality found in this example relies on the jquery.transform.js script. However, before you get into the scripting, notice that the page does rely on standard CSS to place the content. In most cases, applications you create will rely on a combination of both local and library formatting sources. The content includes a paragraph formatted as a label and a button.

Clicking the button triggers the click event, which executes a single line of code. The CSS for TransformMe is modified to include a transform of 45deg. The text goes from being straight across to having an angle like the one shown in Figure 6-1.

image

Figure 6-1. Using a transform can modify the appearance of text on screen.

The problem with allowing a script to affect page formatting is that you can’t be sure how the page will look once the script completes. The page could contain hidden elements or simply not present information as expected. Hidden elements could contain code to redirect the user to an infected site or perform other deeds that you don’t want associated with your application.

Interacting with HTML using Libraries

Some library functions interact directly with the HTML of your application in two common ways. The first is to interact with an existing element. In this case, content appears within the element based on the library function called used. The second is to create new elements and attach them to the existing document. The new elements can contain any sort of content, including tags that could potentially cause problems for the end user.

A major concern when using a library to interact directly with the HTML on your site is that the library could fill various elements with misleading, incorrect, or outright contaminated data. For example, instead of creating the link you expected, it might actually redirect a user to another site—perhaps one that downloads a virus or other nasty piece of software to the user’s machine. Libraries that work with HTML can cause subtle issues that you might not even know about immediately because everything will appear to work correctly. Unless a user complains about the misdirection (and given how URLs today they probably won’t), you won’t know about the issue until enough machines are infected to cause severe problems.

The adding of new elements to a page is a common practice. The example found in ViewJSON.html adds new elements to the existing document based on the content of a JavaScript Object Notation (JSON) file named Test.json. The following code shows how the example performs this task.

<!DOCTYPE html>

<html>
<head>
<title>Viewing JSON Files</title>
<script
src="http://code.jquery.com/jquery-latest.js">
</script>
<script language="JavaScript">
function ViewData()
{
// Obtain the data from disk.
$.getJSON("Test.json",
function(data)
{
// Create an array to hold the data.
var items = [];

// Parse the data by looking at
// each entry in the Users object.
$.each(data.Users,
function(key, value)
{
items.push("<li>" +
value.Name + "<br />" +
value.Number + "<br />" +
(new Date(
parseInt(value.Birthday.substr(6)))
).toDateString()
+ "</li>");
});

// Place the result in an unordered list.
$('<ul/>', {html: items.join("")}).
appendTo('body');
});
}
</script>
</head>

<body>
<h1>Viewing JSON Files</h1>
<input id="btnView"
type="button"
value="View JSON Data"
onclick="ViewData()" />
</body>
</html>

In this case, the library opens the Test.json file and reads data from it. The code removes the JSON file formatting and adds HTML tag formatting. It then uses the join() function to add the new elements to the page. Figure 6-2 shows the output from this example.

image

Figure 6-2. Injecting data from an external source is always problematic.

Notice that the example avoids the use of the document.write() call, which could expose users to all sorts of unwanted content. Using the join() function instead provides a safer alternative that should keep the page free of security issues.

Extending JavaScript with Libraries

Most people think about the ways in which libraries extend either CSS or HTML. The presentation of information is at the forefront. However, libraries can affect the underlying scripting as well. For example, most people are familiar with how to use alert() to display simple messages. Most libraries contain alternatives that a hacker could use to display other sorts of information on screen or affect the application in other ways. For example, the DialogBox.html file contains an example of creating a custom dialog box like the one shown here.

<!DOCTYPE html>

<html>
<head>
<title>Creating a Simple Dialog Box</title>
<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" />
<style type="text/css">
.Normal
{
font-family: Arial, Helvetica, sans-serif;
color: SaddleBrown;
background-color: Bisque;
}
.Emphasize
{
color: Maroon;
font-style: italic;
font-size: larger;
}
</style>
</head>

<body>
<h1>Creating a Simple Dialog Box</h1>
<div id="DialogContent"
title="Simple Dialog Example"
hidden>
<p class="Normal">
This is some
<span class="Emphasize">interesting</span>
text for the dialog box!
</p>
</div>
<script type="text/javascript">
$("#DialogContent").dialog();
</script>
</body>
</html>

In this case, the example displays the dialog box immediately when you open the application as shown in Figure 6-3. The threat offered by such functionality is that a user could open your application expecting one experience and getting something completely different. Because the dialog box appears as part of the application, the user will provide any sort of information the dialog box requests or do anything it wants the user to do.

image

Figure 6-3. The dialog box functionality of jQuery UI could be used to create a security hole.

A hacker could enable such functionality by using something like script (code) injection. For example, the hacker could hide the code as a comment on a blog page (which is why manual moderation of comments is such a good idea). The underlying attack is one of social engineering—putting the user at ease by presenting the dialog box as part of the application and then using that situation to do something nasty.

Differentiating Between Internally Stored and Externally Stored Libraries

You may get the idea that all JavaScript libraries appear on a third party site. It’s true that many popular JavaScript libraries, such as jQuery, do appear on someone else’s site. However, many organizations have their own personal libraries as well. The factors that affect internally stored libraries are:

• They reside on systems owned and maintained by the organization

• The organization controls the source code and can modify it as needed to address issues that developers encounter or are brought to the organization’s attention by others.

• Outside parties can’t access the library without the organization’s permission.

• The connectivity to the library relies on internal lines, rather than access through the Internet.

Internally stored libraries have many advantages not found in those stored externally on a third party site. For the most part, given the same level of coding, an internally stored library is faster, more reliable, and more secure than an externally stored library. In addition, because the library contains only the code an organization actually needs, it’s quite possible that the internally stored library will use fewer resources because it will be smaller than its generic counterpart will. Of course, these statements make a lot of assumptions about the internally stored library that might not be true. Here are the counterpoints you need to consider:

• Internally stored libraries are expensive to build and maintain, so the organization may not keep them updated as required to keep them secure.

• Few organizations can field a development team equivalent in skills to a third party vendor, so the quality of the library will likely suffer.

• Third party libraries receive testing from a substantial number of testers, so that even small errors come out. Internally stored libraries generally receive a modicum of testing that may not even weed out some major flaws.

The bottom line is that internally stored libraries are successful when they target special functionality not provided by third party counterparts and the team putting them together takes the care required to do the job well. When putting your application design together, you must weigh the benefits that internally stored libraries provide against the risks they present. In addition, you must further define the risks presented by third party libraries.

Defining the Security Threats Posed by Libraries

Any JavaScript code you create is likely to contain some error that a hacker can exploit for various purposes. Libraries aren’t special in this regard. However, because you’re incorporating code that your organization didn’t create into an application your organization did create, there is a chance that code that would normally behave correctly will end up having a security flaw due to assumptions on both sides. With this in mind, the two tools that every developer needs to know about when it comes to libraries are testing tools specifically designed for security needs and a good security expert.

It isn’t ever possible to say that the library you maintain is completely secure. You can say that you’ve written the code to meet security best practices and that a security expert has reviewed the code, but even with the best intentions and robust tools, it simply isn’t possible to guarantee that a library (or any other code for that matter) is secure. This issue comes up relatively often when speaking with nonprogrammers—especially management staff of an organization that wants to use your library for development purposes. It’s important that everyone understand that you have taken every appropriate security measure, but that no one can guarantee any code is completely secure.

Even after testing, you have to realize that there is a potential for security flaws in a library, the application it supports, or as a result of combining the two. With this in mind, here is a list of the most common sorts of threats that you could encounter when working with libraries (with no emphasis on the actual source of the flaw).

• Cross-Site Scripting (XSS): The most common security problem that developers face is XSS. There are three easy ways to get past XSS:

• Never transmit untrusted data in the same HTTP response as HTML or JavaScript. In fact, it’s best if the main HTML document remains static.

You might wonder how your server would even end up sending untrusted data to anyone. It’s easier than you think. The paper at http://www.cs.berkeley.edu/~prateeks/papers/scriptgard-ccs11.pdf describes just how hard it is to ensure data integrity even if you use the right sanitizers. The safe assumption is that any data you didn’t personally create is untrusted.

• When you must transmit untrusted data from the server to the client, make sure you encode it in JSON and that the data has a Content-Type of application/json.

• Once the data is ready for display, use the Node.textContent(), document.createTextNode(), or Element.setAttribute() (second parameter only) calls to ensure the page presents it properly.

• Dangerous Function Calls: Just because JavaScript supports a particular call, doesn’t mean the call is safe. Using setInnerHtml() or .innerHtml = can inject unwanted script code. Rely on the setInnerText() call instead.

• Modifying the Document Directly: Even though you may see the document.write() appear a few times in the book for the sake of expediency, using this call in a production environment is an invitation to disaster. The code could write anything, anywhere. Use calls that add, remove, or update Document Object Model (DOM) elements instead.

• Creating Scripts on the Fly: Any time you turn a string into a script, you’re inviting a hacker to provide the string. Using calls such as eval(), setTimeout() with a string argument, setInterval() with a string argument, or new Function() makes your code significantly less secure.

• Code that Executes, but Causes Security Flaws: Some JavaScript calls give you all sorts of rope to hang yourself with. In order to avoid this situation, use JavaScript strict mode to ensure that only safe calls will actually work.

• Content that Purports to be Something It Isn’t: Hackers love to send you content that isn’t quite what you think it is. The best way to avoid this problem is to follow a Content Security Policy, which means including the appropriate content tags, such as script-src 'self' and object-src 'self'.

Scanning a library using a product such as JSLint (http://www.jslint.com/) can help you ensure the quality of your code. High quality code is less likely to contain errors that will cause security issues. However, it’s important to realize that JSLint (and tools like it) don’t scan specifically for security issues. In fact, you can’t scan for security issues in your code. In order to check for security issues, you must begin by testing your code specifically for security issues. If the code requires a higher level of confidence than testing will provide, then you must also employ the services of a security expert to check to the code for potential problems manually.

Enabling Strict Mode

Newer browsers provide support for ECMAScript 5, which includes the JavaScript strict mode. In order to use this security feature, you need to ensure that your users aren’t hanging on to that fossil of a browser that’s been on their machine from the first time they used it. For example, IE 9 doesn’t support this feature, but IE 10 does. You can find which browsers support strict mode at http://kangax.github.io/compat-table/es5/. It’s essential that you develop an organizational policy that requires users have certain browsers in order to work with the application.

Strict mode makes many obvious and subtle changes to the way JavaScript operates. The important thing is that it makes it easier to debug JavaScript applications because instead of silently failing or acting oddly, your JavaScript application will now raise errors when it encounters a problem. This means that those odd library calls that used to die without doing anything, will now tell you something about the problems. Here are the major problems that strict mode helps you deal with.

• Eliminates the Use of with: Using the with statement can open security problems in your application. The latest versions of JavaScript have deprecated this feature because it’s so dangerous. Strict mode will raise an error whenever you try to use with in your code.

• Prevents Unwanted Variables: A major problem in JavaScript is that you can accidentally create new variables by assigning a value to a variable with a mistyped name. In some cases, this error can create unwanted global variables that can result in security holes. Strict mode forces you to declare every variable before you use it, so it’s not possible to create variables accidentally any longer.

• Disallows Coercion Using this: Some existing code coerces local variables to the global state by assigning a value to them when they’re in the unassigned or null state. For example, you can’t assign a value to a variable within a constructor without first instantiating an object by calling new.

• Precludes Duplicates: It’s quite easy to create duplicates of properties in objects or named arguments in functions. Strict mode throws an error if you try to create a duplication in either situation.

• Notifies of Immutable Value Change Attempts: It isn’t possible to change an immutable value in JavaScript. However, in the past, the attempt would fail silently, so it was possible to assume the code was in one state when it was really in another. Strict mode throws an error after any attempt to change an immutable value.

Strict mode comes with ECMAScript 5 and above. You don’t have to install anything special to get strict mode support. However, you do have to include the "use strict"; string. Older versions of JavaScript ignore the string, so you won’t see any changes in how older code runs. TheStrictMode.html file contains the following example.

<!DOCTYPE html>

<html>
<head>
<title>Working with Strict Mode</title>
<script language="javascript">
function testStrict(Name)
{
"use strict";

try
{
this.Name = Name;
alert(this.Name);
}
catch (e)
{
alert(e);
}
}
</script>
</head>

<body>
<h1>Working with Strict Mode</h1>
<button id="Test" onclick="testStrict('George')">
Test
</button>
</body>
</html>

Without strict mode checking (you can simply comment the statement out to try it) the code displays the value erroneously assigned to this.Name of George. However, with strict mode checking in place, you see the error message shown in Figure 6-4.

image

Figure 6-4. Strict mode checking prevents errant assignments.

Never use strict mode globally. It might seem like a good idea at first, but you’ll quickly find that some library code will fail. The idea behind strict mode is to ensure you have firm control over the code you create. Using validation checks, you can monitor the behavior of libraries that you use.

Developing a Content Security Policy (CSP)

One of the biggest problems that developers face is creating applications that aren’t susceptible to various kinds of script and content injection attacks such as XSS. The problem defies easy resolution because of the way in which browsers work. Browsers effectively trust any content coming from a specific origin, so that the browser trusts anything injected at the same level as the original data. CSP seeks to remedy this problem by creating a whitelisting facility of a sort.

For browsers that support CSP (see the table at http://caniuse.com/contentsecuritypolicy for a listing of compatible browsers), CSP provides the means for keeping browsers from recognizing scripts and contents from unsupported sites. The policy appears as a series of headings that you add to the top of the page. When a browser sees the headings, it uses them to determine which scripts and content is safe to load.

When a browser doesn’t provide support for CSP, it ignores the headings you provide and acts as it normally would. This means that users must rely on browsers that support CSP if you want to use CSP as a means of blocking unwanted content. Otherwise, the browser will work as it always has and continue to load content from unsupported sites.

A header consists of three basic elements: policy name, data type, and data source. Here is an example of a CSP heading that contains just one data type:

Content-Security-Policy: script-src 'self'

In this case, the CSP states that the browser should only execute scripts found embedded within the page. Let’s say that you want to provide support for jQuery as well. In this case, you’d extend the policy as shown here:

Content-Security-Policy: script-src 'self' 'http://code.jquery.com'

You don’t need to provide the specific location of the source code file, just the host site information. Each entry is separated from the next using a space. A CSP can define all sorts of content types. For example, you may decide that you want to support scripts found on the local page, but you don’t want to support objects at all. In this case, you use the following CSP header:

Content-Security-Policy: script-src 'self'; object-src 'none'

Notice that the content types appear separated by a semicolon (;). CSP supports a number of different content type directives. You can find a quick reference guide containing a list of these directives, sample values, and descriptions at http://content-security-policy.com/. The important thing to remember is that using CSP can save you from that subtle hole in your code that a hacker could otherwise exploit.

Incorporating Libraries Safely

Some organizations simply add a library to their toolbox because it provide some functionality that the organization needs without much thought about how that library is put together or even if it’s a good idea to use it. In at least some cases, organizations that don’t put a lot of thought into the use of a library end up regretting it later because the library will contain a lot of security holes, run unreliably or slowly, or actually end up costing the organization more time than if it had simply created its own library in the first place. The following sections how you determine whether incorporating that interesting library you found into your application is actually a good idea.

Embracing the Sandbox Solution

It’s quite likely that even if you check the third party JavaScript and clean the data you use thoroughly that something will still try to sneak by. Remember that it’s easier to overcome the walls you build than to build them in the first place. When it comes to JavaScript security threats, you must consider that hackers will simply come up with new ways of circumventing your security every time you have a new bulletproof strategy in your arsenal.

A potential way around this problem is to rely on sandboxing. Essentially this means that the third party library runs at a lower privilege level than your code does. Using sandboxing doesn’t guarantee that your application will remain safe, but it does reduce the potential for security breaches. You can read about sandboxing techniques at http://www.slideshare.net/phungphu/a-twotier-sandbox-architecture-for-untrusted-javascript. The techniques described in the slideshow are complex, but they do work. As with everything, it comes down to determining what level of risk you’re willing to tolerate when running an application. Chapter 10 discusses the use of sandboxes in detail.

Researching the Library Fully

Whenever you choose to add a library to your application, you’re expressing trust in the creator of that library. Even with the help of a competent security expert, taking a library apart and examining every bit of code it contains (assuming the code is even fully available) will prove more time consuming that creating the library from scratch. Consequently, you must consider whether the library poses few enough risks to be part of an application solution that you create. When researching a library, consider these questions as part of your research:

• Are there any trade press stories that discuss the library in a negative way? (If the library is already known to have unpatched security holes, you may want to reconsider using it for your application.)

• Are other organizations using the library without problem?

• Is the company that created the library proactive in answering questions about library integrity?

• Does the company that created the library provide consistent bug fixes and updates?

• What sorts of questions are people asking as part of the online support provided for the library?

• How long as the library been around? (Libraries with long lives tend to have fewer problems and the longevity speaks of good support on the part of the creator.)

Defining the Precise Library Uses

No one uses every feature provided by every library found in an application. Some research sites state outright that many developers use a library for just one or two of the features it contains. Documenting how you use a particular library helps you mitigate risks associated with using the library by focusing your attention on those areas. More importantly, keeping track of specific usage areas tells you when you must perform an update and how you can decrease the size of a library by removing unused features from it. The more you know about how you use a library to perform specific application tasks, the more you reduce the risk of using it.

Keeping Library Size Small and Content Focused

It’s essential to keep third party libraries small and focused on specific needs whenever possible. This means removing code that you won’t ever use because such code tends to:

• Slow download times

• Increase security issues

• Reduce reliability

• Cause unnecessary updates

Fortunately, the best third party libraries are on your side. They want you to create a custom version of the library to use on your site. For example, when you use jQuery UI, you can create a customized version using the special builder shown in Figure 6-5.

image

Figure 6-5. Using the jQuery UI builder helps you create a customized version of the library.

Using a builder means that the library you create will contain only the library elements you actually need. Of course, the down side is that you must provide hosting for the library, which means you won’t get automatic updates as the creator makes them available. If you use an option like this, it’s essential to check for the need to update your copy of the library on a regular basis.

Performing the Required Testing

Before you put any library into a production environment, you must build a test suite to determine whether the library works as you hope it will. You can start by using a vendor-specific test suite, but it’s important to check using a test suite of your own design, as well, that mimics how your application will use the library. The testing process should include both valid and invalid data input checks. It’s important to ensure that you get the expected output with valid inputs and some sort of exception when using invalid inputs. Chapters 11 and 12 provide details on how to perform various levels of testing on your application and the libraries it uses.

Differentiating Between Libraries and Frameworks

The “Differentiating Between Frameworks and Libraries” sidebar in Chapter 5 gives you an brief overview of how libraries and frameworks differ from a reliability perspective. Of course, there is more to the difference than simply reliability concerns. It’s important to have a better understanding of precisely how the two differ and why you should care.

Frameworks provide templating for a site in a manner that libraries don’t. When using a library, an application is simply relying on another source for code. Framework usage implies another level of participation, where the application now uses external sources for additional support. Because a framework integrates more fully into an application and provides more resources, you must also hold it to a higher standard than when working with a library (although you should hold both to a high standard anyway).

Trying to figure out whether a framework is safe to use can be quite hard. In fact, testing can become nearly impossible. With this in mind, third party security experts are attempting to quantify the safety level of frameworks and templating libraries. One of the better places to look for information is mustache-security (https://code.google.com/p/mustache-security/). This site provides you with seven levels of checks for frameworks as shown in Figure 6-6.

image

Figure 6-6. Sites such as mustache-security provide seven levels of checks for frameworks.

Looking a bit further down the page, you can see that the security news for frameworks isn’t good. Most frameworks today contain serious security problems that you need to consider before using them for application development. Figure 6-7 shows the results for some of the most popular frameworks and templating libraries available today.

image

Figure 6-7. Most frameworks and templating libraries today have a long way to go before they become secure.

The interesting thing about sites like these is that they often provide specific examples of how the framework fails. For example, click the AngularJS link in the table shown in Figure 6-7 and you see specifics on how the framework failed in the security area as shown in Figure 6-8. The information also includes workarounds you can use to help mitigate the problems, which is the main reason you want to spend some time researching the frameworks and ensuring you understand precisely where they fall short.

image

Figure 6-8. Some security sites provide example code demonstrating security issues in frameworks.