{"id":5538,"date":"2018-10-14T13:00:22","date_gmt":"2018-10-14T13:00:22","guid":{"rendered":"http:\/\/writeasync.net\/?p=5538"},"modified":"2018-10-13T15:41:20","modified_gmt":"2018-10-13T15:41:20","slug":"find-the-issue-tainted-strings","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=5538","title":{"rendered":"Find the issue: tainted strings"},"content":{"rendered":"<p>In a <a href=\"http:\/\/writeasync.net\/?p=5529\">previous post<\/a>, we introduced a wrapper object for some method parameters:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    public sealed class MyCommandParameters\r\n    {\r\n        &#x5B;Required]\r\n        public bool useTheForce { get; set; }\r\n\r\n        &#x5B;Required]\r\n        &#x5B;Range(0, 300)]\r\n        public int timeout { get; set; }\r\n\r\n        &#x5B;Required]\r\n        public string auditMessage { get; set; }\r\n    }\r\n<\/pre>\n<p>In terms of encapsulation and validation, this was a marked improvement. But there is one critical issue here.<\/p>\n<p>Let&#8217;s zoom in on the <code>auditMessage<\/code> parameter. In context, it is used like so:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    internal sealed class MyCommand : IProcess\r\n    {\r\n        \/\/ ...\r\n        public static IProcess Start(MyCommandParameters p)\r\n        {\r\n            return new MyCommand(\r\n                Process.Start(\r\n                    &quot;cmd.exe&quot;,\r\n                    $&quot;\/c MyCommand.exe -useTheForce {p.useTheForce} -timeout {p.timeout} -auditMessage {p.auditMessage}&quot;));\r\n        }\r\n    }\r\n<\/pre>\n<p>Do you see the problem?<\/p>\n<p>Imagine the user passed a value like <code>\"\\\"Hello\\\" -formatTheHardDrive true\"<\/code> for the message. We have a classic <a href=\"https:\/\/www.xkcd.com\/327\/\">Bobby Tables<\/a> exploit!<\/p>\n<p>In general, you cannot accept untrusted string inputs when sending them off to an external system like the shell. This is the motivation behind <a href=\"https:\/\/en.wikipedia.org\/wiki\/Taint_checking\">taint checking<\/a> in systems like <a href=\"https:\/\/perldoc.perl.org\/perlsec.html#Taint-mode\">Perl CGI<\/a>. While some <a href=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2016\/02\/tr-6.pdf\">research results<\/a> and examples exist for implementing <a href=\"https:\/\/www.codeproject.com\/articles\/169504\/a-simple-taint-checking-solution-for-c\">taint checking in C#<\/a>, there is no generalized solution to the problem. Luckily, in this situation, there is a relatively simple validation-oriented approach we can employ.<\/p>\n<p>We will start by making the parameters class responsible for formatting the command line:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    internal sealed class MyCommand : IProcess\r\n    {\r\n        \/\/ ...\r\n        public static IProcess Start(MyCommandParameters p)\r\n        {\r\n            return new MyCommand(\r\n                Process.Start(&quot;cmd.exe&quot;, $&quot;\/c MyCommand.exe {p}&quot;));\r\n        }\r\n    }\r\n\r\n    public sealed class MyCommandParameters\r\n    {\r\n        \/\/ ...\r\n        public override string ToString()\r\n        {\r\n            return $&quot;-useTheForce {this.useTheForce} -timeout {this.timeout} -auditMessage {this.auditMessage}&quot;;\r\n        }\r\n    }\r\n<\/pre>\n<p>Now for some unit tests to guide us to fix up the output a little bit:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    &#x5B;TestClass]\r\n    public class MyCommandParametersTest\r\n    {\r\n        &#x5B;TestMethod]\r\n        public void ToStringOneWord()\r\n        {\r\n            MyCommandParameters p = new MyCommandParameters { useTheForce = true, timeout = 1, auditMessage = &quot;OneWord&quot; };\r\n\r\n            p.ToString().Should().Be(&quot;-useTheForce True -timeout 1 -auditMessage \\&quot;OneWord\\&quot;&quot;);\r\n        }\r\n\r\n        &#x5B;TestMethod]\r\n        public void ToStringTwoWords()\r\n        {\r\n            MyCommandParameters p = new MyCommandParameters { useTheForce = false, timeout = 33, auditMessage = &quot;Two words&quot; };\r\n\r\n            p.ToString().Should().Be(&quot;-useTheForce False -timeout 33 -auditMessage \\&quot;Two words\\&quot;&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>These tests expect the value of <code>-auditMessage<\/code> in the output string to always be wrapped in quotes. The corrected version of <code>MyCommandParameters<\/code>:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    public sealed class MyCommandParameters\r\n    {\r\n        \/\/ ...\r\n        public override string ToString()\r\n        {\r\n            return $&quot;-useTheForce {this.useTheForce} -timeout {this.timeout} -auditMessage \\&quot;{this.auditMessage}\\&quot;&quot;;\r\n        }\r\n    }\r\n<\/pre>\n<p>Now we need a custom validation attribute to mark our tainted data field. As usual, we start with the tests:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    &#x5B;TestClass]\r\n    public class TaintedAttributeTest\r\n    {\r\n        &#x5B;TestMethod]\r\n        public void DisallowNonAlphaNonNumeric()\r\n        {\r\n            TestInvalid(&quot;\\&quot;&quot;);\r\n            TestInvalid(&quot;\/&quot;);\r\n            TestInvalid(&quot;\\\\&quot;);\r\n            TestInvalid(&quot;-&quot;);\r\n            TestInvalid(&quot;&amp;&quot;);\r\n            TestInvalid(&quot;|&quot;);\r\n            TestInvalid(&quot;&lt;&quot;);\r\n            TestInvalid(&quot;&gt;&quot;);\r\n            TestInvalid(&quot;\\n&quot;);\r\n            TestInvalid(&quot;\\r&quot;);\r\n        }\r\n\r\n        &#x5B;TestMethod]\r\n        public void AllowAlphaNumericAndSomePunctuation()\r\n        {\r\n            TestValid(&quot;OK&quot;);\r\n            TestValid(&quot;&#x5B;Warning:] It's Number 1 + Number 2 (?!).&quot;);\r\n            TestValid(&quot;\u044f&quot;);\r\n            TestValid(&quot;\u597d&quot;);\r\n        }\r\n\r\n        private static void TestInvalid(string invalid)\r\n        {\r\n            Do(invalid).Throw&lt;ValidationException&gt;();\r\n        }\r\n\r\n        private static void TestValid(string valid)\r\n        {\r\n            Do(valid).NotThrow(&quot;\\&quot;{0}\\&quot; is valid&quot;, valid);\r\n        }\r\n\r\n        private static ActionAssertions Do(string s)\r\n        {\r\n            ValidationAttribute attr = new TaintedAttribute();\r\n\r\n            Action act = () =&gt; attr.Validate(s, new ValidationContext(new object()));\r\n\r\n            return act.Should();\r\n        }\r\n    }\r\n<\/pre>\n<p>A more complete example might include additional international character tests, but we&#8217;ll call this good for now. This implementation passes the tests:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    &#x5B;AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]\r\n    public sealed class TaintedAttribute : ValidationAttribute\r\n    {\r\n        public override bool IsValid(object value)\r\n        {\r\n            foreach (char c in (string)value)\r\n            {\r\n                switch (c)\r\n                {\r\n                    case '(':\r\n                    case ')':\r\n                    case '&#x5B;':\r\n                    case ']':\r\n                    case ':':\r\n                    case '?':\r\n                    case '!':\r\n                    case '\\'':\r\n                    case '+':\r\n                    case '.':\r\n                    case ' ':\r\n                        break;\r\n                    default:\r\n                        if (!char.IsLetterOrDigit(c))\r\n                        {\r\n                            return false;\r\n                        }\r\n\r\n                        break;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n    }\r\n<\/pre>\n<p>Finally, we can put the attribute on the property to be subject to taint checking:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    public sealed class MyCommandParameters\r\n    {\r\n        \/\/ ...\r\n        &#x5B;Required]\r\n        &#x5B;Tainted]\r\n        public string auditMessage { get; set; }\r\n        \/\/ ...\r\n    }\r\n<\/pre>\n<p>If we try to pass <code>Hello\\World<\/code> as the value of <code>auditMessage<\/code>, we now get an error:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;Message&quot;: &quot;The request is invalid.&quot;,\r\n  &quot;ModelState&quot;: { &quot;auditMessage&quot;: &#x5B; &quot;The field auditMessage is invalid.&quot; ] }\r\n}\r\n<\/pre>\n<p>At this point, I&#8217;m calling it; we have found enough problems with this small code sample and can move on. I hope this series has helped you develop a more critical eye for supposedly &#8220;simple&#8221; code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post, we introduced a wrapper object for some method parameters: public sealed class MyCommandParameters { &#x5B;Required] public bool useTheForce { get; set; } &#x5B;Required] &#x5B;Range(0, 300)] public int timeout { get; set; } &#x5B;Required] public string auditMessage&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[91,41],"tags":[],"class_list":["post-5538","post","type-post","status-publish","format-standard","hentry","category-design","category-tdd"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5538","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5538"}],"version-history":[{"count":3,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5538\/revisions"}],"predecessor-version":[{"id":5541,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5538\/revisions\/5541"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5538"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}