示例 2:从源修改为接收器

示例 2 是示例 1 代码的修改版。它通过添加名为 getVulnerableSource 的验证例程和名为 writeToVulnerableSink 的编码例程来增强示例 1。

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();
  }
}

第一个扫描生成的堆栈跟踪类似于示例 1 中的堆栈跟踪。

知识库扩展为包含验证和编码例程将减少结果中的干扰,并确保为所有调用图都调用了验证和编码例程。例如,如果在先前示例中指定了来自对 java.io.FileInputStream.read(byte[]):int 的任何调用的数据,那么该扫描会从 read 中消除也调用了此验证例程的任何调用。而且,来自 read 的并未调用定制验证方法的调用将提升到明确安全性结果状态,因为在代码中不调用已知的验证方法可能会导致恶意攻击。

验证例程还可以验证 readFileInputStream 方法的其他变量。这些可以指定为其他源。此外,您还可以了解只有特定的接收器(或带有特定属性的接收器)可通过此方法验证。例如,该例程可限制属性为 Technology.IO 的接收器,如 PrintWriter.write 接收器,用于消耗该示例数据。