2014-11-04 13 views
1

我已經重新編碼,以避免在C#中的字符串嵌入式空字符,...但不知道爲什麼下面的調用了字符串參數與嵌入的空字符沒有警告或異常,以及是否這是一個錯誤的StringBuilder.ToString(),一一般來說對於C#來說不好的做法,或者最糟糕的是.NET中的一個漏洞。C#字符串嵌入空字符:錯誤,不好的做法,或漏洞?

對於背景我有一個通過XPath解析來創建節點並在需要時一個如下屬性內WPF應用程序。 StringBuilder類允許我用空字符替換路徑分隔符,例如:xpathtonode[i] = '\0';

儘管這是允許的,但如果這是一種不好的做法,我希望能夠接收併發出異常或至少發出警告。

xmlpathtonode.ToString()的調用將正確地將字符串返回到空終止字符,除非空字符作爲最後一個字符嵌入時,則空字符將包含在由ToString()返回的字符串中。因此,該字符串的Length屬性會比預期的字符串值長。

如果StringBuilder.ToString()將在字符串末尾識別一個空字符,它排除在外,也不會有以下問題。也許這只是StringBuilder類中的一個bug ...

隨後調用XmlDocument.CreateAttribute(...),或者甚至是調用來排除嵌入的空字符xpathtonode.ToString().Substring(offset,length)將退出執行的線程而沒有錯誤或異常。我的程序和調試器將繼續運行,就好像這個調用從未發生過一樣......

我懷疑這會是一種OS風格的緩衝區溢出漏洞,......但令人毛骨悚然的是讓執行流程中斷並繼續沒有任何指示。

錯誤?不好的做法?漏洞?

+0

不好的做法... – 2014-11-04 00:46:59

+0

@TMcKeown,闡述爲什麼。 – Adrian 2014-11-04 00:48:49

+0

當你說'調用xmlpathtonode.ToString()會正確地返回字符串到空終止字符'你是什麼意思?它應該返回整個事物,包括空字符後面的任何文本。 – 2014-11-04 00:58:39

回答

0

錯誤?不好的做法?漏洞?

具體到.NET的XmlDocument對象,因爲你提到調用CreateAttribute(...)xpathtonode.ToString().Substring(offset,length)導致沒有錯誤或異常退出線程,然後這似乎是一個小bug。由於這個怪癖,將任何代碼中的空字符包含在內是不好的做法。

但是,如果從用戶輸入構建路徑,這也可以歸類爲漏洞,因爲惡意用戶可能包含空字符以更改代碼的執行路徑。這是很好的做法反正消毒任何用戶控制或XPath查詢的外部數據,否則您的代碼將是脆弱的XPath Injection:發生

XPath注入攻擊時,網站會使用用戶提供的信息來構建一個XPath查詢XML數據。通過向網站發送有故意的畸形信息,攻擊者可以找出XML數據的結構或訪問他通常無法訪問的數據。

有幾種方法avoid XPath Injection in .NET

關於通常的空字節和您的StringBuilder示例,看起來這可能是Off-by-one Error的一種類型。如果StringBuilder用用戶輸入執行任何字符串處理,則攻擊者可能會提供一個以空字符結尾的字符串並訪問他們通常無法訪問的字符的值。用戶也可能提供一個以空字符結尾的字符串,並導致程序丟棄字符串中通常會出現的任何內容。這些攻擊將依賴於從初始輸入位置持續存在的空值,因爲流水線可能一直在空字節處終止輸入。這是任何不一致的問題。

例如,如果一個組件在驗證過程中將字符串12345\06789視爲123456789,並且另一個組件將該字符串視爲12345,那麼實際使用該值時會出現此問題。這是幾個PHP null byte related issues的原因,其中PHP將讀取空字節,但用C編寫的任何系統函數都將它們歸類爲終止字符。這使得通過PHP驗證代碼走私各種字符串成爲可能,然後使操作系統能夠執行它並不意味着幫助攻擊者的東西。

但是,由於.NET是託管語言,因此不太可能導致緩衝區溢出漏洞。可能需要進一步研究是否可以通過從用戶輸入中注入空字節來完成其中的任何操作。

+0

這是值得測試我的登錄提示,因爲它們將是名稱或密碼字段中的空字符注入的簡單目標(請參閱[如何模擬鍵盤上的空字符](http://stackoverflow.com/questions/9124786/) how-to-simulate-nul-character-from-keyboard))。 – ergohack 2014-11-05 16:21:24

+0

@JRo:如果您使用截取代理(如Burp Suite),則可以輸入編碼爲'%00'的空值來測試輸入。 – SilverlightFox 2014-11-05 22:55:39

0

不好的做法,因爲\0字符可以通過.NET的各種功能/功能以不同的方式解釋給你奇怪/不可預知的結果,真正的問題是你爲什麼故意使用該字符。

這裏有一個類似的問題/響應:Why is there no Char.Empty like String.Empty?

+0

和你一樣,我公司的經驗豐富的C#程序員也驚訝不已,並表達了un-C#如何終止任何事情。我很困惑,爲什麼.NET如此不協調和功能障礙。 – ergohack 2014-11-04 23:45:56

+0

爲了回答你的問題,我通過XPath進行了解析,以分階段使用它,例如,給定完整的XPath'/site/survey/system[@IP="somehost.net「]/@ name'我需要先在我的XmlDocument中創建'site'節點,如果它尚不存在,那麼'survey'節點等,...用'SelectSingleNode(...)'來檢查節點的存在我需要部分路徑逐步通過每個節點,直到整個路徑存在。 xpath StringBuilder對象允許我逐漸用空字符替換分隔符,並返回所需的部分路徑。但最後,... – ergohack 2014-11-05 00:03:18

0

在您的問題聲明,你說,

StringBuilder類讓我代替路徑分隔符以空字符,如: xpathtonode[i] = '\0';

雖然這是允許的,如果它是一個不好的做法,我希望接收和[原文] 異常或至少一個警告。

U + 0000(ASCII NUL)是一個完全合法的Unicode控制字符和在.NET串的完全合法的字符:淨字符串不是空終止的:它們圍繞攜帶長度說明它們。

您可以使用一個更合適的Unicode/ASCII控制字符此:

  • U + 001C(FS)是文件分隔符
  • U + 001D(GS)是組分隔符。 U + 001E(RS)是記錄分隔符
  • U + 001F(US)是單元分離器

回到過去(歷史課來臨),當男人是男人時,數據被堅持到紙帶或打卡上。

特別是在紙帶上,文件記錄中的字段將與US(單位分隔符)分隔開。可以用GS(組分隔符)分隔字段組(例如,重複字段或一組相關字段)。文件中的單個記錄將與RS(記錄分隔符)和磁帶上的單個文件以FS文件分隔符分隔。

衝卡有點不同,因爲卡是離散的東西。每張唱片通常(但並非總是)在單張打卡上。而「文件」可能是1個或更多打孔卡。

+1

你有一個很好的觀點,即字符串應該支持控制字符。但是,如果空字符與其他控制字符一樣被完全支持爲字符,爲什麼'ToString()'截斷返回的字符串,除了空字符在末尾?中間字符串截斷了視圖中的一個錯誤,或者可能是一個陳舊的結束字符串功能的陳舊點頭?當一個字符串參數包含一個空字符時,函數調用可以毫不客氣地終止呢? – ergohack 2014-11-04 23:33:27