[Fortify]Path Manipulation和XML External Entity Injection一起作怪

再次和Fortify神鬼交鋒(新的Rule Pack上市),Fortify SCA新檢測出Path Manipulation及XML External Entity Injection(Input Validation and Representation, Data Flow),來筆記這次的修正。

先一下看他們的模樣

Path Manipulation: Critical等級

XML External Entity Injection: High等級

 


簡單歸納

歸納出一個現象,只要程式行透過xml檔案內的參數建立或刪除檔案時就會對於注入發出警示!!!

  • 讀取xml檔案的程式行被檢測出High等級的XML External Entity Injection(Input Validation and Representation, Data Flow)。
  • 使用到xml取出檔案路徑來建立檔案的程式行則被檢測Critical等級的Path Manipulation。

 

衝擊與準確度象限

因為包含Critical等級的issue,有注入的風險,不能閉上眼睛。

 


修正方法

增加了許多檔案路徑及檔名的檢查來避免注入(injection),但還是徒勞無功,準備放棄之際,將xmlDocument改用LINQ To XML(XElement),兩個Fortify的issue瞬間消除,決定要轉圈圈灑花來慶祝。

 

要讀取的xml檔案內容,找FILE_SETTING節點下的URL值

  <FILE_SETTING>
    <FILE_NAME>MemberList</FILE_NAME>
    <URL>D:\AP\Airlines\MemberList.txt</URL>
  </FILE_SETTING>

 

舊版xmldocument寫法(被檢測出問題的)

程式中使用xmlDocument讀取xml檔案,並且使用檔案中的參數(攻擊點)來建立檔案。

void GenerateFileLegacy()
{
    System.Xml.XmlDocument xdom = new System.Xml.XmlDocument();
    xdom.Load(@"D:\AP\FileSetting.xml");
    System.Xml.XmlNodeList ds = xdom.DocumentElement.SelectNodes("FILE_SETTING");
    for (int i = 0; i < ds.Count; i++)
    {
        string URL = ds[i]["URL"].InnerText;
        using (FileStream fs = new FileStream(URL, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (StreamWriter srOutFile = new StreamWriter(fs, Encoding.Default))
            {
            }
        }
    }
}

 

使用XElement(一次解決兩個issue)

其實也還是有注入的風險,但fortify似乎by pass了。

void GenerateFile()
{
    XElement xelement = XElement.Load(@"D:\AP\FileSetting.xml");
    var fileSettings = from filexml in xelement.Elements("FILE_SETTING")
                       select filexml;
    foreach (XElement xEle in fileSettings)
    {
        string URL = xEle.Element("URL") == null ? "" : xEle.Element("URL").Value;
        using (FileStream fs = new FileStream(URL, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (StreamWriter srOutFile = new StreamWriter(fs, Encoding.Default))
            {
            }
        }
    }
}

 

0個Critical,0個High

 


小結

雖然這樣改寫可以解決issue,但為了避免可能的注入風險,除了建立檔案白名單外,也可以加上作業系統路徑、檢查附檔名等幾種檔案檢核項目。

private static readonly string[] extensions = { ".pdf", ".txt" ,".xls", ".xlsx", "doc", "docx"};
bool IsValidURI(string URL)
{
    if (URL.Contains(Environment.GetFolderPath(Environment.SpecialFolder.Windows))) return false;
    if (URL.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86))) return false;
    if (!URL.Contains(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)))return false;
    if (!extensions.Any(p => p == Path.GetExtension(URL))) return false;
    return true;
}

 

還要神鬼交鋒很久..

 


參考

Effective Xml Part 1: Choose the right API

XmlDocument 類別

XElement 類別