Tag: web coding

Fortify on Demand Remediation – Header Injection: Cookies

Cookie injection vulnerabilities occur when user input is stored into a cookie. It’s possible for malicious input to include newline characters that would be parsed out as new elements in the cookie. As an example, if I send my user ID as “lisa\r\nadmin: true” … I’ve got a cookie that says the userID is lisa and admin is true.

With Fortify on Demand, you cannot just filter out \r and \n characters – Fortify still says the code is vulnerable. You can, however, filter out anything apart from alpha-numeric characters (and, I assume, any oddball character that has a legit reason to be included in the user input):

$strLogonUserID = filter_var(preg_replace(‘/[^a-z\d_]/iu’, ”, $_POST[‘strUID’]), FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

Fortify on Demand Remediation – JSON Injection

This vulnerability occurs when you write unvalidated input to JSON. A common scenario would be using an Ajax call to pass a string of data to a file and then decoding that string to JSON within the file.

To get around the Foritfy scanning requirements you have to use base64 encoding on the string before sending it through the Ajax call:

var update = $.ajax({
    type: "POST",
    url: "SFPNotesUpdate/../php/validate_notes.php",
    data: { tableData: btoa(JSON.stringify(HotRegisterer.getInstance('myhot').getData())) },
    dataType: 'json'
});

When reading the input to decode the JSON string to an array you have to perform these actions in order:

  • base64_decode the input string
  • sanitize the input string
  • decode the JSON string to an array
$tbl_data = json_decode(filter_var(base64_decode($_POST['tableData']), FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES), true);

Fortify on Demand Remediation – XSS Reflected

This vulnerability occurs when you accept user input and then use that input in output. The solution is to sanitize the input. The filter_var or filter_input functions can be used with a variety of sanitize filters.

As an example, code to accept what should be an integer value from user input:

     $iVariable = $_POST['someUserInput'];

Becomes code that removes all characters except for digits (and + or – signs) from the input:

     $iVariable = filter_input(INPUT_POST, 'someUserInput', FILTER_SANITIZE_NUMBER_INT);

Fortify on Demand Remediation – Introduction

The company for which I work signed a contract with some vendor for cloud-based static code analysis. We ran our biggest project through it and saw just shy of ten thousand vulnerabilities. Now … when an application sits out on the Internet, I get that a million people are going to try to exploit whatever they can in order to compromise your site. When the app is only available internally? I fully support firing anyone who plays hacker against their employer’s tools. When a tool is an automation that no one can access outside of the local host? Lazy, insecure code isn’t anywhere near the same problem it is for user-accessible sites. But the policy is the policy, so any code that gets deployed needs to pass the scan — which means no vulnerabilities identified.

Some vulnerabilities have obvious solutions — SQL injection is one. It’s a commonly known problem — a techy joke is that you’ll name your kid “SomeName’;DROP TABLE STUDENTS; … and most database platforms support parameterized statements to mitigate the vulnerability.

Some vulnerabilities are really a “don’t do that!” problem — as an example, we were updating the server and had a page with info(); on it. Don’t do that! I had some error_log lines that output user info that would be called when the process failed (“Failed to add ecckt $iCircuitID to work order $iWorkOrderID for user $strUserID with $curlError from the web server and $curlRepsonse from the web service”). I liked having the log in place so, when a user rang up with a problem, I had the info available to see what went wrong. The expedient thing to do here, though, was just comment those error_log lines out. I can uncomment the line and have the user try it again. Then checkout back to the commented out iteration of the file when we’re done troubleshooting.

Some, though … static code analysis tools don’t always understand that a problem is sorted when the solution doesn’t match one of their list of ‘approved’ methods. I liken this to early MS MCSE tests — there was a pseudo-GUI that asked you to share out a printer from a server. You had to click the exact right series of places in the pseudo-GUI to answer the question correctly. Shortcut keys were not implemented. Command line solutions were wrong.

So I’ve started documenting the solutions we find that pass the Fortify on Demand scan for everything identified in our scans — hopefully letting the next teams that use the static scanner avoid the trial-and-error we’ve gone through to find an acceptable solution.

JQuery – Finding a set of checkboxes

A corollary to my JavaScript modifying checkbox values when the box is checked or unchecked … I needed a way to reset the form (in my form, the default is for the boxes to be checked and the value to be 1). The following code identifies all checkboxes with a particular class, checks them, and sets the value to 1.

/**
 * This function checks off each checkbox of the input class
 *
 * @param {string} strCheckboxClass     Name of class identifying in-scope checkboxes
 * @return {null} 
 *
 * @example
 *
 *     checkAllDatabases ('MyBoxes');
 */
 function checkAllDatabases(strCheckboxClass){
    arrayCheckboxes = $('.'+strCheckboxClass);
    for(i = 0; i < arrayCheckboxes.length; i++) {
        $( '#'+arrayCheckboxes[i].name).prop( "checked", true );
        $( '#'+arrayCheckboxes[i].name).val(1);
    } 
}