Example 2: Modified from source to sink

Example 2 is a modification of the Example 1 code. It enhances Example 1 by adding a validation routine, called getVulnerableSource, and an encoding routine called in writeToVulnerableSink.

import java.io.*;

public class TestCase_IOT_Instance_Val_Encode {
  public static void main(String[] args) {
    try {
      TestCase_IOT_Instance_Val_Encode testCase = new 
        TestCase_IOT_Instance_Val_Encode();
      String file = args[0];
      String source = testCase.getVulnerableSource(file);
      source = testCase.validate(source);
      String encodedStr = testCase.encode(source);
      testCase.writeToVulnerableSink(file, encodedStr);
    } catch (Exception e) {
    }
  }

  public String getVulnerableSource(String file) throws Exception {
    FileInputStream fis = new FileInputStream(file);
    byte[] buf = new byte[100];
    fis.read(buf);
    fis.close();

    String ret = new String(buf);
    return ret;
  }

  public void writeToVulnerableSink(String file, String str) 
      throws FileNotFoundException {
    FileOutputStream fos = new FileOutputStream(file);
    PrintWriter writer = new PrintWriter(fos);
    writer.write(str);
  }

  private String validate(String source) throws Exception {
    if (source.length() > 100) {
      throw new Exception("Length too long: " + source.length());
    }
		return source;
  }

  private String encode(String source) {
    return source.trim();
  }
}

The first scan produces a stack trace similar to the stack trace in Example 1.

Extending the Knowledgebase to include validation and encoding routines reduces noise in the findings and checks that validation and encoding routines are being called for all call graphs. For example, if you specified the data from any call to java.io.FileInputStream.read(byte[]):int in the previous example, the scan eliminates any calls from read that also called this validation routine. Also, calls from read that did not call the custom validation method are promoted to definitive security finding status, since not calling a known validation method in the code can lead to malicious attacks.

The validation routine may also validate the other variations of the read methods of the FileInputStream. These may be specified as additional sources. In addition, you may also know that only certain sinks (or sinks with certain properties) are validated by this method. For example, this routine could be restricted to sinks with the property of Technology.IO, such as the PrintWriter.write sink that is used to consume this example data.