Upgrade to Pro — share decks privately, control downloads, hide ads and more …

String is not a sufficient type: how using your type system can help you make better software

String is not a sufficient type: how using your type system can help you make better software

We deal with types, explicitly or implicitly—depending on our language of choice—every day. We often use them without even thinking about them, or we consider them an annoyance when we’re just trying to get something done. This brief talk presents an accessible metaphor to help explain that type systems are here to help us, and it makes a case for using more—not fewer—types in everyday programming in order to create more stable, more secure software.

A video of this talk is available: https://vimeo.com/148532355

And speakers’ notes, etc are on my blog: https://www.dzombak.com/talks/2015-12-10-String-is-not-a-sufficient-type--how-using-your-type-system-can-help-you-make-better-software.html

Chris Dzombak

December 10, 2015
Tweet

More Decks by Chris Dzombak

Other Decks in Programming

Transcript

  1. String
    is not a sufficient type
    (how using your type system can help you
    make better software)

    View Slide

  2. About Me
    → Chris Dzombak
    → iOS Frameworks Team
    [email protected]
    → @dzombak on Slack
    → @cdzombak on Twitter

    View Slide

  3. Relax.

    View Slide

  4. Let’s talk about String.

    View Slide

  5. → user input
    → human language words
    → output for the UI
    → SQL statements
    → keypaths for Cocoa KVO/KVC
    → …

    View Slide

  6. → …
    → XPath queries for XML
    → shell commands
    → HTML
    → regular expressions
    → and more!

    View Slide

  7. String is totally
    insufficient to represent
    all these different things

    View Slide

  8. Documentation

    View Slide

  9. SQL Injection
    SELECT * FROM items
    WHERE owner = 'hacker'
    AND itemname = 'name';
    DELETE FROM items;
    --'

    View Slide

  10. Shell Injection
    run("gpg" , "−−trust−model always −o
    \"#{File.expand_path(dst.path)}\" −e −r \"#{@recipient}\"
    \"#{File .expand_path(src .path)}\"")
    Code sample from the 2010 DC online voting pilot1.
    1 https://jhalderm.com/pub/papers/dcvoting-fc12.pdf
    https://freedom-to-tinker.com/blog/jhalderm/hacking-dc-internet-voting-pilot

    View Slide

  11. Messy UI failure modes

    View Slide

  12. XSS

    View Slide

  13. What if we used different String types for…
    → user input
    → HTML output
    → SQL statements
    → shell commands
    → etc…

    View Slide

  14. let username = inputUsername()
    let sql: SQLString = "SELECT FROM `users` WHERE `name` = '" + username + "';"
    database.execute(sql)

    View Slide

  15. let username = inputUsername()
    let sql: SQLString = "SELECT FROM `users` WHERE `name` = '" + username + "';"
    > error: ^^^
    > error: cannot combine `username` of type UserInputString with type SQLString

    View Slide

  16. I’m not crazy.

    View Slide

  17. 43,560

    View Slide

  18. 43,560
    43,560 ft²

    View Slide

  19. Units in math are just like
    your type system.

    View Slide

  20. Units in math are just like your type system.

    View Slide

  21. Exactly like in high school physics, we
    should attach meangingful information to
    our strings.

    View Slide

  22. Exactly like in high school physics, we
    should attach meangingful information to
    our strings.
    Then, our compiler or runtime will make
    many common mistakes impossible.

    View Slide

  23. What would it take to
    really do this?

    View Slide

  24. Standard library
    → String
    → UserInputString
    → PathString and URLString
    → (or maybe filesystem paths and URLs should
    be represented by separate, more capable
    objects entirely)

    View Slide

  25. Native UI library
    → UserFacingString
    → A function accepting Strings, numbers, null
    references; filtering them; and outputting a “sane”
    string

    View Slide

  26. Web templating library
    → HTMLEscapedString
    → A function accepting other Strings and escaping
    them for output

    View Slide

  27. Database library
    → SQLStatement, SQLEscapedString
    → SQLStatement may only be constructed from
    programmer-controlled origins
    → Only SQLEscapedString may be combined into
    SQLStatement, in predefined safe ways
    → A function accepting Strings and escaping them
    for SQL

    View Slide

  28. Cocoa KVC/KVO
    → KeyPath
    → addObserver:forKeyPath:… et al. accept KeyPath
    → Build KeyPath from string literals, with validation
    → Build KeyPath from runtime reflection
    → KeyPath instances can only be manipulated in
    constrained, valid ways

    View Slide

  29. This sounds hard !

    View Slide

  30. This sounds hard !

    View Slide

  31. Using plain old String everywhere in your
    program is like a professional physicist
    foregoing units in their calculations.

    View Slide

  32. This is work we’re doing already.

    View Slide

  33. This is work we’re doing already.
    Except when we forget.

    View Slide

  34. This is work we’re doing already.
    → ESAPI.encoder()
    → mysql_real_escape_string
    (yes, I know it’s deprecated)
    → Escaping shell metacharacters2
    → label.text = name.length ? name : ""
    2 http://stackoverflow.com/a/20053121

    View Slide

  35. Implementation?

    View Slide

  36. Implementation?
    ¯\_(ϑ)_/¯

    View Slide

  37. Conclusions
    Type systems exist and we should let them
    help us. ✅

    View Slide

  38. Conclusions
    A few new types would help eliminate
    whole classes of vulnerabilities and other
    bugs. ✅

    View Slide

  39. Conclusions
    This wouldn’t be hard or annoying; this is
    work we’re already doing. ✅

    View Slide

  40. Discussion

    View Slide

  41. View Slide