Enjoy Sharing Technology!

Software,Develope,Devops, Security,TroubleShooting

Sunday, November 14, 2021

fortify scan: Cross-site scripting (XSS)

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.

An attacker can use XSS to send a malicious script to an unsuspecting user. The end user’s browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information retained by the browser and used with that site. These scripts can even rewrite the content of the HTML page. 



These 3 types of XSS are defined as follows:

Stored XSS 

Stored XSS generally occurs when user input is stored on the target server, such as in a database, in a message forum, visitor log, comment field, etc. And then a victim is able to retrieve the stored data from the web application without that data being made safe to render in the browser. With the advent of HTML5, and other browser technologies, we can envision the attack payload being permanently stored in the victim’s browser, such as an HTML5 database, and never being sent to the server at all.

Reflected XSS 

Reflected XSS occurs when user input is immediately returned by a web application in an error message, search result, or any other response that includes some or all of the input provided by the user as part of the request, without that data being made safe to render in the browser, and without permanently storing the user provided data. In some cases, the user provided data may never even leave the browser (see DOM Based XSS next).

DOM Based XSS 

As defined by Amit Klein, who published the first article about this issue [1], DOM Based XSS is a form of XSS where the entire tainted data flow from source to sink takes place in the browser, i.e., the source of the data is in the DOM, the sink is also in the DOM, and the data flow never leaves the browser. For example, the source (where malicious data is read) could be the URL of the page (e.g., document.location.href), or it could be an element of the HTML, and the sink is a sensitive method call that causes the execution of the malicious data (e.g., document.write).”



Explanation:

Cross-site scripting (XSS) vulnerabilities occur when:

1. Data enters a web application through an untrusted source. In the case of persistent (also known as stored) XSS, the untrusted source is typically a database or other back-end data store, while in the case of reflected XSS it is typically a web request.

2. The data is included in dynamic content that is sent to a web user without validation.

The malicious content sent to the web browser often takes the form of a segment of JavaScript, but can also include HTML, Flash or any other type of code that the browser executes. The variety of attacks based on XSS is almost limitless, but they commonly include transmitting private data like cookies or other session information to the attacker, redirecting the victim to web content controlled by the attacker, or performing other malicious operations on the user's machine under the guise of the vulnerable site.

Example 1: The following ASP.NET Web Form queries a database for an employee with a given employee ID and prints the name corresponding with the ID.

<script runat="server">

...

string query = "select * from emp where id=" + eid;

sda = new SqlDataAdapter(query, conn);

DataTable dt = new DataTable();

sda.Fill(dt);

string name = dt.Rows[0]["Name"];

...

EmployeeName.Text = name;

</script>

Where EmployeeName is a form control defined as follows:

<form runat="server">

   ...

   <asp:Label id="EmployeeName" runat="server">

   ...

</form>

Example 2: The following ASP.NET code segment is functionally equivalent to Example 1, but implements all of the form elements programmatically.

protected System.Web.UI.WebControls.Label EmployeeName;

...

string query = "select * from emp where id=" + eid;

sda = new SqlDataAdapter(query, conn);

DataTable dt = new DataTable();

sda.Fill(dt);

string name = dt.Rows[0]["Name"];

...

EmployeeName.Text = name;

These code examples function correctly when the values of name are well-behaved, but they do nothing to prevent exploits if they are not. This code can appear less dangerous because the value of name is read from a database, whose contents are apparently managed by the application. However, if the value of name originates from user-supplied data, then the database can be a conduit for malicious content. Without proper input validation on all data stored in the database, an attacker may execute malicious commands in the user's web browser. This type of exploit, known as Persistent (or Stored) XSS, is particularly insidious because the indirection caused by the data store makes it more difficult to identify the threat and increases the possibility that the attack will affect multiple users. XSS got its start in this form with web sites that offered a "guestbook" to visitors. Attackers would include JavaScript in their guestbook entries, and all subsequent visitors to the guestbook page would execute the malicious code.

Example 3: The following ASP.NET Web Form reads an employee ID number from an HTTP request and displays it to the user.

<script runat="server">

...

EmployeeID.Text = Login.Text;

...

</script>

Where Login and EmployeeID are form controls defined as follows:

<form runat="server">

   <asp:TextBox runat="server" id="Login"/>

   ...

   <asp:Label runat="server" id="EmployeeID"/>

</form>

Example 4: The following ASP.NET code segment shows the programmatic way to implement Example 3.

protected System.Web.UI.WebControls.TextBox Login;

protected System.Web.UI.WebControls.Label EmployeeID;

...

EmployeeID.Text = Login.Text;

As in Example 1 and Example 2, these examples operate correctly if Login contains only standard alphanumeric text. If Login has a value that includes metacharacters or source code, then the code will be executed by the web browser as it displays the HTTP response.

Initially this might not appear to be much of a vulnerability. After all, why would someone enter a URL which causes malicious code to run on their own computer?  The real danger is that an attacker will create the malicious URL, then use email or social engineering tricks in order to lure victims into clicking a link. When the victims click the link, they unwittingly reflect the malicious content through the vulnerable web application and back to their own computers. This mechanism of exploiting vulnerable web applications is known as Reflected XSS.

As the examples demonstrate, XSS vulnerabilities are caused by code that includes unvalidated data in an HTTP response. There are three vectors by which an XSS attack can reach a victim:

- As in Example 1 and Example 2, the application stores dangerous data in a database or other trusted data store. The dangerous data is subsequently read back into the application and included in dynamic content. Persistent XSS exploits occur when an attacker injects dangerous content into a data store that is later read and included in dynamic content. From an attacker's perspective, the optimal place to inject malicious content is in an area that is displayed to either many users or particularly interesting users. Interesting users typically have elevated privileges in the application or interact with sensitive data that is valuable to the attacker. If one of these users executes malicious content, the attacker may be able to perform privileged operations on behalf of the user or gain access to sensitive data belonging to the user.

- As in Example 3 and Example 4, data is read directly from the HTTP request and reflected back in the HTTP response. Reflected XSS exploits occur when an attacker causes a user to supply dangerous content to a vulnerable web application, which is then reflected back to the user and executed by the web browser. The most common mechanism for delivering malicious content is to include it as a parameter in a URL that is posted publicly or emailed directly to victims. URLs constructed in this manner constitute the core of many phishing schemes, whereby an attacker convinces victims to visit a URL that refers to a vulnerable site. After the site reflects the attacker's content back to the user, the content is executed and proceeds to transfer private information, such as cookies that may include session information, from the user's machine to the attacker or perform other nefarious activities.

- A source outside the application stores dangerous data in a database or other data store, and the dangerous data is subsequently read back into the application as trusted data and included in dynamic content.

Recommendations:

The solution to XSS is to ensure that validation occurs in the correct places and checks are made for the correct properties.

Because XSS vulnerabilities occur when an application includes malicious data in its output, one logical approach is to validate data immediately before it leaves the application. However, because web applications often have complex and intricate code for generating dynamic content, this method is prone to errors of omission (missing validation). An effective way to mitigate this risk is to also perform input validation for XSS.

Web applications must validate their input to prevent other vulnerabilities, such as SQL injection, so augmenting an application's existing input validation mechanism to include checks for XSS is generally relatively easy. Despite its value, input validation for XSS does not take the place of rigorous output validation. An application might accept input through a shared data store or other trusted source, and that data store might accept input from a source that does not perform adequate input validation. Therefore, the application cannot implicitly rely on the safety of this or any other data. This means that the best way to prevent XSS vulnerabilities is to validate everything that enters the application and leaves the application destined for the user.

The most secure approach to validation for XSS is to create an allow list of safe characters that are permitted to appear in HTTP content and accept input composed exclusively of characters in the approved set. For example, a valid username might only include alphanumeric characters or a phone number might only include digits 0-9. However, this solution is often infeasible in web applications because many characters that have special meaning to the browser must be considered valid input after they are encoded, such as a web design bulletin board that must accept HTML fragments from its users.

A more flexible, but less secure approach is to implement a deny list, which selectively rejects or escapes potentially dangerous characters before using the input. To form such a list, you first need to understand the set of characters that hold special meaning for web browsers. Although the HTML standard defines what characters have special meaning, many web browsers try to correct common mistakes in HTML and might treat other characters as special in certain contexts, which is why we do not encourage the use of deny lists as a means to prevent XSS. The CERT(R) Coordination Center at the Software Engineering Institute at Carnegie Mellon University provides the following details about special characters in various contexts :

In the content of a block-level element (in the middle of a paragraph of text):

- "<" is special because it introduces a tag.

- "&" is special because it introduces a character entity.

- ">" is special because some browsers treat it as special, on the assumption that the author of the page intended to include an opening "<", but omitted it in error.

The following principles apply to attribute values:

- In attribute values enclosed with double quotes, the double quotes are special because they mark the end of the attribute value.

- In attribute values enclosed with single quote, the single quotes are special because they mark the end of the attribute value.

- In attribute values without any quotes, white-space characters, such as space and tab, are special.

- "&" is special when used with certain attributes, because it introduces a character entity.

In URLs, for example, a search engine might provide a link within the results page that the user can click to re-run the search. This can be implemented by encoding the search query inside the URL, which introduces additional special characters:

- Space, tab, and new line are special because they mark the end of the URL.

- "&" is special because it either introduces a character entity or separates CGI parameters.

- Non-ASCII characters (that is, everything greater than 127 in the ISO-8859-1 encoding) are not allowed in URLs, so they are considered to be special in this context.

- The "%" symbol must be filtered from input anywhere parameters encoded with HTTP escape sequences are decoded by server-side code. For example, "%" must be filtered if input such as "%68%65%6C%6C%6F" becomes "hello" when it appears on the web page in question.

Within the body of a <SCRIPT> </SCRIPT>:

- Semicolons, parentheses, curly braces, and new line characters should be filtered out in situations where text could be inserted directly into a pre-existing script tag.

Server-side scripts:

- Server-side scripts that convert any exclamation characters (!) in input to double-quote characters (") on output might require additional filtering.

Other possibilities:

- If an attacker submits a request in UTF-7, the special character '<' appears as '+ADw-' and might bypass filtering. If the output is included in a page that does not explicitly specify an encoding format, then some browsers try to intelligently identify the encoding based on the content (in this case, UTF-7).

After you identify the correct points in an application to perform validation for XSS attacks and what special characters the validation should consider, the next challenge is to identify how your validation handles special characters. If special characters are not considered valid input to the application, then you can reject any input that contains special characters as invalid. A second option in this situation is to remove special characters with filtering. However, filtering has the side effect of changing any visual representation of the filtered content and might be unacceptable in circumstances where the integrity of the input must be preserved for display.

If input containing special characters must be accepted and displayed accurately, validation must encode any special characters to remove their significance. A complete list of ISO 8859-1 encoded values for special characters is provided as part of the official HTML specification [2].

Many application servers attempt to limit an application's exposure to cross-site scripting vulnerabilities by providing implementations for the functions responsible for setting certain specific HTTP response content that perform validation for the characters essential to a cross-site scripting attack. Do not rely on the server running your application to make it secure. When an application is developed there are no guarantees about what application servers it will run on during its lifetime. As standards and known exploits evolve, there are no guarantees that application servers will also stay in sync.

Tips:

1. The Fortify Secure Coding Rulepacks warn about SQL Injection and Access Control: Database issues when untrusted data is written to a database and also treat the database as a source of untrusted data, which can lead to XSS vulnerabilities. If the database is a trusted resource in your environment, use custom filters to filter out dataflow issues that include the DATABASE taint flag or originate from database sources. Nonetheless, it is often still a good idea to validate everything read from the database.

2. Even though URL encoding untrusted data protects against many XSS attacks, some browsers (specifically, Internet Explorer 6 and 7 and possibly others) automatically decode content at certain locations within the Document Object Model (DOM) prior to passing it to the JavaScript interpreter. To reflect this danger, the rulepacks no longer treat URL encoding routines as sufficient to protect against cross-site scripting. Data values that are URL encoded and subsequently output will cause Fortify to report Cross-Site Scripting: Poor Validation vulnerabilities.

Share:

Friday, November 12, 2021

fortify scan:Weak Encryption: Insecure Mode of Operation

 Abstract:

Do not use cryptographic encryption algorithms with an insecure mode of operation.

Explanation:

The mode of operation of a block cipher is an algorithm that describes how to repeatedly apply a cipher's single-block operation to securely transform amounts of data larger than a block. Some modes of operation include Electronic Codebook (ECB), Cipher Block Chaining (CBC), Cipher Feedback (CFB), and Counter (CTR).

ECB mode is inherently weak, as it produces the same ciphertext for identical blocks of plain text. CBC mode is vulnerable to padding oracle attacks. CTR mode is the superior choice because it does not have these weaknesses.

Example 1: The following code uses the AES cipher with ECB mode:

(C#/VB.NET/ASP.NET)

  ...

  var objAesCryptoService = new AesCryptoServiceProvider();

  objAesCryptoService.Mode = CipherMode.ECB;

  objAesCryptoService.Padding = PaddingMode.PKCS7;

  objAesCryptoService.Key = securityKeyArray;

  var objCrytpoTransform = objAesCryptoService.CreateEncryptor();

  ...

(C/C++):

  ...EVP_EncryptInit_ex(&ctx, EVP_aes_256_ecb(), NULL, key, iv);

(JAVA/JSP):

...

SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");

cipher.init(Cipher.ENCRYPT_MODE, key);

...

Recommendations:

Avoid using ECB and CBC modes of operation when encrypting data larger than a block. CBC mode is somewhat inefficient and poses a serious risk if used with SSL [1]. Instead, use CCM (Counter with CBC-MAC) mode or, if performance is a concern, GCM (Galois/Counter Mode) mode where they are available.

Example 2: The following code uses the AES cipher with GCM mode:

  ..

  var cipher = new AesGcm(securityKeyArray)

  ...

 

Share:

fortify scan: Path Manipulation

A Path Manipulation attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder. By manipulating variables that reference files with “dot-dot-slash (../)” sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file system including application source code or configuration and critical system files. It should be noted that access to files is limited by system operational access control (such as in the case of locked or in-use files on the Microsoft Windows operating system).

this attack is also known as “dot-dot-slash”, “directory traversal”, “directory climbing” and “backtracking”.

Explanation:

Path manipulation errors occur when the following two conditions are met:

1. An attacker can specify a path used in an operation on the file system.

2. By specifying the resource, the attacker gains a capability that would not otherwise be permitted.

For example, the program might give the attacker the ability to overwrite the specified file or run with a configuration controlled by the attacker.

Example 1: The following code uses input from an HTTP request to create a file name. The programmer has not considered the possibility that an attacker may provide a file name like "..\\..\\Windows\\System32\\krnl386.exe", which will cause the application to delete an important Windows system file.

String rName = Request.Item("reportName");

...

File.delete("C:\\users\\reports\\" + rName);

Example 2: The following code uses input from a configuration file to determine which file to open and echo back to the user. If the program runs with adequate privileges and malicious users can change the configuration file, they can use the program to read any file on the system that ends with the extension ".txt".

sr = new StreamReader(resmngr.GetString("sub")+".txt");

while ((line = sr.ReadLine()) != null) {

Console.WriteLine(line);

}

Recommendations:

The best way to prevent path manipulation is with a level of indirection: create a list of legitimate values from which the user must select. With this approach, the user-provided input is never used directly to specify the resource name.

In some situations this approach is impractical because the set of legitimate resource names is too large or too hard to maintain. Programmers often resort to implementing a deny list in these situations. A deny list is used to selectively reject or escape potentially dangerous characters before using the input. However, any such list of unsafe characters is likely to be incomplete and will almost certainly become out of date. A better approach is to create a list of characters that are permitted to appear in the resource name and accept input composed exclusively of characters in the approved set.

Tips:

1. If the program is performing custom input validation you are satisfied with, use the Fortify Custom Rules Editor to create a cleanse rule for the validation routine.

2. Implementation of an effective deny list is notoriously difficult. One should be skeptical if validation logic requires implementing a deny list. Consider different types of input encoding and different sets of metacharacters that might have special meaning when interpreted by different operating systems, databases, or other resources. Determine whether or not the deny list can be updated easily, correctly, and completely if these requirements ever change.

3. A number of modern web frameworks provide mechanisms to perform user input validation (including ASP.NET Request Validation and WCF). To highlight the unvalidated sources of input, Fortify Secure Coding Rulepacks dynamically re-prioritize the issues Fortify Static Code Analyzer reports by lowering their probability of exploit and providing pointers to the supporting evidence whenever the framework validation mechanism is in use. With ASP.NET Request Validation, we also provide evidence for when validation is explicitly disabled. We refer to this feature as Context-Sensitive Ranking. To further assist the Fortify user with the auditing process, the Fortify Software Security Research group makes available the Data Validation project template that groups the issues into folders based on the validation mechanism applied to their source of input.


Share:

fortify scan: XPath Injection

Similar to SQL Injection, XPath Injection attacks occur when a web site uses user-supplied information to construct an XPath query for XML data. By sending intentionally malformed information into the web site, an attacker can find out how the XML data is structured, or access data that they may not normally have access to. They may even be able to elevate their privileges on the web site if the XML data is being used for authentication (such as an XML based user file).

Querying XML is done with XPath, a type of simple descriptive statement that allows the XML query to locate a piece of information. Like SQL, you can specify certain attributes to find, and patterns to match. When using XML for a web site it is common to accept some form of input on the query string to identify the content to locate and display on the page. This input must be sanitized to verify that it doesn’t mess up the XPath query and return the wrong data.

XPath is a standard language; its notation/syntax is always implementation independent, which means the attack may be automated. There are no different dialects as it takes place in requests to the SQL databases.

Because there is no level access control it’s possible to get the entire document. We won’t encounter any limitations as we may know from SQL injection attacks.

Explanation:

XPath injection occurs when:

1. Data enters a program from an untrusted source.

2. The data used to dynamically construct an XPath query.

Example 1: The following code dynamically constructs and executes an XPath query that retrieves an email address for a given account ID. The account ID is read from an HTTP request, and is therefore untrusted.

...

string acctID = Request["acctID"];

string query = null;

if(acctID != null) {

       StringBuffer sb = new StringBuffer("/accounts/account[acctID='");

       sb.append(acctID);

       sb.append("']/email/text()");

       query = sb.toString();

}

XPathDocument docNav = new XPathDocument(myXml);

XPathNavigator nav = docNav.CreateNavigator();

nav.Evaluate(query);

...

Under normal conditions, such as searching for an email address that belongs to the account number 1, the query that this code executes will look like the following:

/accounts/account[acctID='1']/email/text()

However, because the query is constructed dynamically by concatenating a constant base query string and a user input string, the query only behaves correctly if acctID does not contain a single-quote character. If an attacker enters the string 1' or '1' = '1 for acctID, then the query becomes the following:

/accounts/account[acctID='1' or '1' = '1']/email/text()

The addition of the 1' or '1' = '1 condition causes the where clause to always evaluate to true, so the query becomes logically equivalent to the much simpler query:

//email/text()

This simplification of the query allows the attacker to bypass the requirement that the query must only return items owned by the authenticated user. The query now returns all email addresses stored in the document, regardless of their specified owner.


Recommendations:

The root cause of XPath injection vulnerability is the ability of an attacker to change context in the XPath query, causing a value that the programmer intended to be interpreted as data to be interpreted as a command instead. When an XPath query is constructed, the programmer knows what should be interpreted as part of the command and what should be interpreted as data.

To prevent an attacker from violating the programmer's expectations, use an allow list to ensure that user-controlled values used in an XPath query are composed from only the expected set of characters and do not contain any XPath metacharacters given the context in which they are used. If a user-controlled value requires that it contain XPath metacharacters, use an appropriate encoding mechanism to remove their significance within the XPath query.

Example 2

...

string acctID = Request["acctID"];

string query = null;

if(acctID != null) {

       try {

              iAcctID = Int32.Parse(acctID);

       }

       catch (FormatException e) {

              throw new InvalidParameterException();

       }

       StringBuffer sb = new StringBuffer("/accounts/account[acctID='");

       sb.append(acctID.toString());

       sb.append("']/email/text()");

       query = sb.toString();

}

XPathDocument docNav = new XPathDocument(myXml);

XPathNavigator nav = docNav.CreateNavigator();

nav.Evaluate(query);

Tips:

1. A number of modern web frameworks provide mechanisms to perform user input validation (including ASP.NET Request Validation and WCF). To highlight the unvalidated sources of input, Fortify Secure Coding Rulepacks dynamically re-prioritize the issues Fortify Static Code Analyzer reports by lowering their probability of exploit and providing pointers to the supporting evidence whenever the framework validation mechanism is in use. With ASP.NET Request Validation, we also provide evidence for when validation is explicitly disabled. We refer to this feature as Context-Sensitive Ranking. To further assist the Fortify user with the auditing process, the Fortify Software Security Research group makes available the Data Validation project template that groups the issues into folders based on the validation mechanism applied to their source of input.

Share:

Appscan: Unencrypted Login Request

Appscan Unencrypted Login Request

   The decrypted login request for the Appscan vulnerability is summarized as follows:

1.1, attack principle

When unencrypted sensitive information (such as login credentials, user name, password, email address, social security number, etc.) is sent to the server, any information transmitted to the server in plain text may be stolen. Attackers can use this information to initiate further steps. At the same time, this is also required by several privacy laws (such as the Sarbanes-Oxley Act, Health Insurance Portability and Accountability Act (HIPAA), Financial Privacy: The Gramm-Leach Bliley Act), and sensitive information such as user credentials must be The encryption method is passed to the Web site.

1.2, defense suggestions

Encrypted transmission of sensitive information involved in the request process, such as changing the product HTTP access mode to HTTPS secure access mode; at the same time, perform security configuration in the conf file erver.xml of the Apache-Tomcat application server, in the product WEB.XML file Add restriction statements, etc. In addition to SSL encryption methods, other encrypted transmission methods that meet the requirements of the group encryption algorithm are also recognized: http://eip-owsg.paic.com.cn/isms/Admin/DownLoad.aspx?id=a2c04af6- a487-4899-998f-418c89c96318.docx.pdf

1.3, exceptions

  Pure intranet system does not need to fix this vulnerability.

1.4, the actual repair plan

   1. Change http request to https request method;

  2. Sensitive information (such as login credentials, user name, password, email address, social security number, etc.) is encrypted before transmission.

Share:

fortify scan: Unsafe Deserialization

Data which is untrusted cannot be trusted to be well formed. Malformed data or unexpected data could be used to abuse application logic, deny service, or execute arbitrary code, when deserialized.



Abstract:

Deserializing user-controlled object streams at runtime can allow attackers to execute arbitrary code on the server, abuse application logic, and/or lead to denial of service.

Explanation:

Java serialization turns object graphs into byte streams that contain the objects themselves and the necessary metadata to reconstruct them from the byte stream. Developers can create custom code to aid in the process of deserializing Java objects, where they can replace the deserialized objects with different objects, or proxies. The customized deserialization process takes place during objects reconstruction, before the objects are returned to the application and cast into expected types. By the time developers try to enforce an expected type, code may have already been executed.

Custom deserialization routines are defined in the serializable classes which need to be present in the runtime classpath and cannot be injected by the attacker so the exploitability of these attacks depends on the classes available in the application environment. Unfortunately, common third party classes or even JDK classes can be abused to exhaust JVM resources, deploy malicious files, or run arbitrary code.

Example 1: An application deserializing untrusted object streams can lead to application compromise.

InputStream is = request.getInputStream();

ObjectInputStream ois = new ObjectInputStream(is);

MyObject obj = (MyObject) ois.readObject();

Recommendations:

If possible, do not deserialize untrusted data without validating the contents of the object stream. In order to validate classes being deserialized, the look-ahead deserialization pattern should be used.

The object stream will first contain the class description metadata and then the serialized bytes of their member fields. The Java serialization process enables developers to read the class description and decide whether to proceed with the deserialization of the object or abort it. In order to do so, it is necessary to subclass java.io.ObjectInputStream and provide a custom implementation of the resolveClass(ObjectStreamClass desc) method where class validation and verification should take place.

There are existing implementations of the look-ahead pattern that can be easily used, such as the Apache Commons IO (org.apache.commons.io.serialization.ValidatingObjectInputStream). Always use a strict allow list approach to only deserialize expected types. A deny list approach is not recommended since attackers may use many available gadgets to bypass the deny list. Also, keep in mind that although some classes to achieve code execution are publicly known, there may be others that are unknown or undisclosed, so an allow list approach will always be preferred. Any class allowed in the allow list should be audited to make sure it is safe to deserialize.

When deserialization takes place in a library or framework (for example, when using JMX, RMI, JMS, HTTP Invokers), the preceding recommendation is not useful since it is beyond the developer's control. In those cases, you may want to make sure that these protocols meet the following requirements:

- Not exposed publicly.

- Use authentication.

- Use integrity checks.

- Use encryption.

In addition, Fortify Runtime provides security controls to be enforced every time the application performs a deserialization from an ObjectInputStream, protecting both application code but also library and framework code from this type of attack.

Tips:

1. Due to existing flaw in ObjectInputStream implementation and the difficulties of implementing a deny list for basic classes that may be used to perform Denial Of Service (DoS) attacks, this issue will be reported even if a look-ahead ObjectInputStream is implemented but its severity will be lowered to Medium.


Share:

fortify scan: Unsafe Reflection

An attacker may be able to create unexpected control flow paths through the application, potentially bypassing security checks. Exploitation of this weakness can result in a limited form of code injection.

Explanation:

If an attacker can supply values that the application then uses to determine which class to instantiate or which method to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner. Even the ability to control the arguments passed to a given method or constructor may give a wily attacker the edge necessary to mount a successful attack.

This situation becomes a doomsday scenario if the attacker may upload files into a location that appears on the application's classpath or add new entries to the application's classpath. Under either of these conditions, the attacker may use reflection to introduce new, presumably malicious, behavior into the application.

Example: A common reason that programmers use the reflection API is to implement their own command dispatcher. The following example shows a command dispatcher that does not use reflection:

String ctl = request.getParameter("ctl");

Worker ao = null;

if (ctl.equals("Add")) {

  ao = new AddCommand();

} else if (ctl.equals("Modify")) {

  ao = new ModifyCommand();

} else {

  throw new UnknownActionError();

}

ao.doAction(request);

A programmer might refactor this code to use reflection as follows:

    String ctl = request.getParameter("ctl");

    Class cmdClass = Class.forName(ctl + "Command");

    Worker ao = (Worker) cmdClass.newInstance();

    ao.doAction(request);

The refactoring initially appears to offer a number of advantages. There are fewer lines of code, the if/else blocks have been entirely eliminated, and it is now possible to add new command types without modifying the command dispatcher.

However, the refactoring allows an attacker to instantiate any object that implements the Worker interface. If the command dispatcher is still responsible for access control, then whenever programmers create a new class that implements the Worker interface, they must remember to modify the dispatcher's access control code. If they fail to modify the access control code, then some Worker classes will not have any access control.

One way to address this access control problem is to make the Worker object responsible for performing the access control check. An example of the re-refactored code is as follows:

String ctl = request.getParameter("ctl");

Class cmdClass = Class.forName(ctl + "Command");

Worker ao = (Worker) cmdClass.newInstance();

ao.checkAccessControl(request);

ao.doAction(request);

Although this is an improvement, it encourages a decentralized approach to access control, which makes it easier for programmers to make access control mistakes.

This code also highlights another security problem with using reflection to build a command dispatcher. An attacker may invoke the default constructor for any kind of object. In fact, the attacker is not even constrained to objects that implement the Worker interface; the default constructor for any object in the system can be invoked. If the object does not implement the Worker interface, a ClassCastException will be thrown before the assignment to ao, but if the constructor performs operations that work in the attacker's favor, the damage will have already been done. Although this scenario is relatively benign in simple applications, in larger applications where complexity grows exponentially it is not unreasonable to assume that an attacker could find a constructor to leverage as part of an attack.

Access checks may also be compromised further down the code execution chain, if certain Java APIs that perform tasks using the immediate caller's class loader check, are invoked on untrusted objects returned by reflection calls. These Java APIs bypass the SecurityManager check that ensures all callers in the execution chain have the requisite security permissions. Care should be taken to ensure these APIs are not invoked on the untrusted objects returned by reflection as they can bypass security access checks and leave the system vulnerable to remote attacks. For more information on these Java APIs please refer to Guideline 9 of The Secure Coding Guidelines for the Java Programming Language.

Recommendations:

The best way to prevent unsafe reflection is with a level of indirection: create a list of legitimate names that users are allowed to specify, and only allow users to select from the list. With this approach, input provided by users is never used directly to specify a name that is passed to the reflection API.

Reflection can also be used to create a custom data-driven architecture, whereby a configuration file determines the types and combinations of objects that are used by the application. This style of programming introduces the following security concerns:

- The configuration file that controls the program is an essential part of the program's source code and must be protected and reviewed accordingly.

- Because the configuration file is unique to the application, unique work must be performed to evaluate the security of the design.

-Because the semantics of the application are now governed by a configuration file with a custom format, custom rules are required for obtaining optimal static analysis results.

For these reasons, avoid using this style of design unless your team can devote a large amount of effort to security evaluation.

Tips:

1. Beware of attempts to validate user input before using it as part of a call to a reflection method. Because the application is likely to evolve faster than the operating system, the file system, or other system components, the work required to validate user input must evolve much more rapidly than the input validation required for sending user data to other system components. Even if the validation is currently correct, it might not be correct in the future.

2. A number of modern web frameworks provide mechanisms to perform user input validation (including Struts and Spring MVC). To highlight the unvalidated sources of input, Fortify Secure Coding Rulepacks dynamically re-prioritize the issues Fortify Static Code Analyzer reports by lowering their probability of exploit and providing pointers to the supporting evidence whenever the framework validation mechanism is in use. We refer to this feature as Context-Sensitive Ranking. To further assist the Fortify user with the auditing process, the Fortify Software Security Research group makes available the Data Validation project template that groups the issues into folders based on the validation mechanism applied to their source of input.


Share:

Search This Blog

Weekly Pageviews

Translate