嵌入空字符的C#字符串:错误,不良做法或漏洞?

时间:2014-11-04 00:37:57

标签: c# wpf string security

我已经重新编码以避免在C#字符串中嵌入空字符,但是想知道为什么以下调用没有为带有嵌入空字符的字符串参数提供警告或异常,以及这是否是{{{ 1}},对于C#来说是一种不好的做法,或者最糟糕的是.NET中的漏洞。

对于后台我有一个WPF应用程序,它通过XPath进行解析,以便在需要时在XmlDocument中创建节点和属性。 StringBuilder类允许我用空字符替换路径分隔符,例如:StringBuilder.ToString()

虽然这是允许的,但如果这是一个不好的做法,我希望收到和例外或至少是警告。

xpathtonode[i] = '\0';的调用会正确地将字符串返回到空终止字符,除非将空字符作为最后一个字符嵌入,则空字符将包含在{{1}返回的字符串中}}。因此,字符串的xmlpathtonode.ToString()属性将比预期的字符串值长。

如果ToString()会识别字符串末尾的空字符并将其排除,则不会出现以下问题。也许这只是StringBuilder类中的一个错误......

Length的后续调用,甚至是对排除嵌入空字符StringBuilder.ToString()的调用都将退出执行线程而不会出现错误或异常。我的程序和调试器将继续运行,好像呼叫从未发生过一样,......

我怀疑这是一个操作系统风格的缓冲区溢出漏洞,...但是让执行流程中断并继续没有任何指示令人毛骨悚然。

错误?糟糕的做法?漏洞?

3 个答案:

答案 0 :(得分:0)

糟糕的做法是因为\0字符可以通过.NET的各种特性/功能进行不同的解释,从而给您带来奇怪/不可预测的结果,真正的问题是为什么您会故意使用该字符。

以下是类似的问题/回复:Why is there no Char.Empty like String.Empty?

答案 1 :(得分:0)

在你的问题陈述中,你说,

  

StringBuilder类让我用空字符替换路径分隔符,例如:   xpathtonode[i] = '\0';

     

虽然这是允许的,如果这是一个不好的做法,我希望收到和[原文如此]   例外或至少是警告。

U + 0000(Ascii NUL)是一个完全合法的Unicode控制字符,在.Net字符串中是完全合法的字符:.Net字符串不是nul-terminated:它们带有长度说明符

您可以使用更合适的Unicode / ASCII控制字符:

  • U + 001C(FS文件分隔符
  • U + 001D(GS组分隔符
  • U + 001E(RS记录分隔符
  • U + 001F(US单位分隔符

回到过去(历史课程即将到来),当男人是男人时,数据被持续到纸带或打卡。

特别是,在纸带上,文件记录中的字段将使用单位分隔符US分隔。字段组(例如,重复字段或一组相关字段)可以用GS(组分隔符)分隔。文件中的单个记录将以RS(记录分隔符)和磁带上的单个文件分隔,文件分隔符为FS

由于卡片是离散的东西,因此Punch卡有点不同。每张唱片通常(但不总是!)在一张打卡上。而“文件”可能是一盒或多盒穿孔卡。

答案 2 :(得分:0)

  

错误?糟糕的做法?漏洞?

特定于.NET的XmlDocument对象,因为你提到调用CreateAttribute(...)xpathtonode.ToString().Substring(offset,length)会导致线程退出而没有错误或异常,那么这似乎是一个小虫子。由于这个怪癖,在任何代码中包含空字符都是不好的做法。

但是,如果您正在构建来自用户输入的路径,这也可以被归类为漏洞,因为恶意用户可能包含有意更改代码执行路径的空字符。无论如何,在XPath查询中清理任何用户控制的或外部数据都是一种很好的做法,否则您的代码将容易受到XPath Injection的攻击:

  

当网站使用用户提供的信息构建XML数据的XPath查询时,就会发生XPath注入攻击。通过向网站发送故意格式错误的信息,攻击者可以了解XML数据的结构,或访问他通常无法访问的数据。

avoid XPath Injection in .NET有几种方法。

关于一般的空字节,以及StringBuilder示例,它可能是Off-by-one Error的一种类型。如果StringBuilder使用用户输入进行任何字符串处理,则攻击者可能会提供空终止字符串并访问他们通常无法访问的字符值。用户也可能提供空终止字符串并使程序丢弃字符串中通常遵循的任何内容。这些攻击将依赖于从初始输入位置持久存储的空值,因为管道可以始终在空字节处终止输入。这是任何不一致的问题。

例如,如果一个组件在验证期间将字符串12345\06789视为123456789,而另一个组件在实际使用该值时将该字符串视为12345,则这是一个问题。这是PHP将读取空字节的几个PHP null byte related issues的原因,但是用C编写的任何系统函数都将它们归类为终止字符。这使得可以通过PHP验证代码走私各种字符串,然后使操作系统能够执行它并不意味着帮助攻击者。

但是,由于.NET是托管语言,因此不太可能导致缓冲区溢出漏洞。如果可以通过从用户输入注入空字节来进行任何这些操作,那么值得进一步研究。