範例 2:從來源到接收槽(已修改)

範例 2 是範例 1 程式碼的修改。範例 2 是範例 1 的強化版本,差異是新增名為 getVulnerableSource 的驗證常式,以及名為 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();
  }
}

第一次掃描會產生一個堆疊追蹤,類似於範例 1 的堆疊追蹤。

延伸知識庫來併入驗證和編碼常式,會減少發現項目中的雜訊,且可以確認所有呼叫圖都呼叫驗證和編碼常式。比方說,如果您在上例中從任何對於 java.io.FileInputStream.read(byte[]):int 的呼叫指定資料,則任何從 read 發出的呼叫,只要也呼叫這個驗證常式,掃描就會予以排除。另外,從 read 發出的呼叫,只要未呼叫自訂驗證方法,就會升級至明確的安全發現項目狀態,因為在程式碼中未呼叫已知的驗證方法,有可能導致惡意的攻擊。

驗證常式也可能會驗證 FileInputStreamread 方法的其他變異。這可能會指定為其他來源。此外,您可能也知道這個方法只驗證某些接收槽(或含某些內容的接收槽)。例如,這個常式僅受限在含 Technology.IO 內容的接收槽,例如用來消耗此範例資料的 PrintWriter.write 接收槽。