2

Two of the top 3 security vulnerabilities in the OWASP Top 10 come from trusting user input (Injection and XSS). To deal with this, Ruby lets you "taint" Strings received from the user as unsafe.

In a type-safe language like Kotlin you can (theoretically) take this one step further with a Tainted class that wraps a String, but is not extended from CharSequence. Then everywhere you write your (for example) HTML output, you have to run all your Tainted objects through an escapeHtml(Tainted t), escapeSql(Tainted t), or escapeUrl(Tainted t), or you get a compile error.

I can make a Tainted class in Kotlin too, but Kotlin's String Templates assume that every class has a toString() method and make no complaint when writing these Tainted objects out in strings, thus defeating most of the purpose of a tainted class.

Is there a way I can generate a compile-time error in Kotlin when I do this:

val t = Tainted("Robert'); DROP TABLE STUDENTS; --")
return "SELECT * FROM STUDENTS WHERE NAME IN ($t);"

If there was a way to exclude a class from working inside a String Template (and StringBuilder) that would do it. Or a compiler setting to raise an error when using a certain class or classes in them? I'm just wondering if anyone has found a way to do this effectively in Kotlin.

Without this, there could still be a benefit of using a Tainted class to "Make Wrong Look Wrong", even if the IDE and compiler can only detect some and not all encoding errors.

12
  • Aren't string sanitation methods designed to prevent runtime problems? Who are you protecting at compile-time... the developer against himself? Commented May 27, 2016 at 20:56
  • @RobertHarvey What is more important to think about when coding a web/database app? I'm my own worst enemy in a lot of situations. Commented May 27, 2016 at 20:57
  • But you're not going to get a bad string until someone taints it. Surely the developer is smart enough to figure out how to make clean strings. Is your assumption here that some developers might be malicious? Commented May 27, 2016 at 20:58
  • @RobertHarvey you wrap the thing that takes parameters off requests so that it returns Tainted objects. Then you store them in the database, read them back, and have to encode them before writing them out again. To audit your code, you only need to look for ".queryParams(" to see that they are all wrapped in Tainted objects. It seems to me like it's worth taking every precaution. If your language has type safety, why not leverage it to do this for you? Commented May 27, 2016 at 21:00
  • 1
    @RobertHarvey I think you may be imagining Tainted to be something more complicated than it is. class Tainted { string _value; } will do the trick; as long as the methods which get user input return a Tainted (and the only way to get a string out of a Tainted is to sanitise it) then you'll get instant feedback from the type checker if you write code that's vulnerable to SQL injection. It's simply a technique to use the type system for bookkeeping, it doesn't need special IDE support. Commented May 27, 2016 at 21:53

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.