News for hackers. Stuff that matters.
Re:Format Strings in Rust 1.58 by pron on Friday January 14, 2022 @06:57AM (#29933390)
> The compiler doesn’t know if the string being templated is SQL, HTML, YAML, JSON, or something else, so it doesn’t know how to sanitize the string.

That is the problem, and why security experts wouldn't let us add string interpolation to Java until we had a way to require the format string to say how it will be used and enforce proper validation. [1]

Even if programmers should be more careful, the fact remains that this is the #1 security vulnerability caused by language features. The language should, if possible, make it easier for developers to avoid the mistake rather than make it easier for them to make it.

[1]: https://openjdk.java.net/jeps/8273943

Re:Format Strings in Rust 1.58 by stubish on Friday January 14, 2022 @08:55PM (#29942854)
Looks like Java wants to skip format strings and jump straight to domain specific templating. I'm dubious doing this at the language level is a good idea. Picking a domain I'm familiar with, how do we handle this?

    SQL."SELECT * FROM orders WHERE \{mcol} LIKE '%' || \{qry} || '%'"
How does the the templating engine know that 'mcol' needs to be quoted as an SQL identifier using ", and that qry either needs to be quoted as an SQL string using ' or a replacement made to use a bind variable? And since 'qry' is being used in a LIKE expression, do any % or ? characters in it need to be escaped, or should they be passed through? I guess you need to force hints in the template (force, because we are trying stop people being able to write buggy code)

   SQL."SELECT * FROM orders WHERE \{mcol:sql_id} LIKE '%' || \{qry:sql_likestr} || '%'"
But none of that stops someone just doing this, which is the most common form of the bug:

   "SELECT * FROM orders WHERE " + mcol + " LIKE '%" + qry + "%'"
To stop people throwing arbitrary strings at a database connection, risking SQL injection attacks and other buggy behavior, you just need to stop people throwing strings at a database connection. Instead having the driver only accept an object. Which does not rely on a templating engine at all. std::fmt does not encourage or make it easier to write code with SQL injection bugs, and if you want to stop them, the only way is to stop the driver accepting arbitrary strings and instead force developers to use an API to correctly generate their SQL. Which is exactly what most ORMs do, although they generally allow people to force arbitrary strings in for convenience or non-standard SQL stanzas.
Re:Format Strings in Rust 1.58 by paulgb on Friday January 14, 2022 @07:26AM (#29933633)
Interesting, so to make sure I understand, if I were writing an SQL library I could require (at the type check level) that a query I was passed was constructed with a specific formatter, and that formatter would encode any substrings that I templated into it in a way appropriate for SQL?

I wonder how this would handle something like HTML injection, where the desired encoding can change within the same string depending on whether you’re in an attribute or a text block?

Re:Format Strings in Rust 1.58 by pron on Friday January 14, 2022 @08:07AM (#29933962)
> Interesting, so to make sure I understand, if I were writing an SQL library I could require (at the type check level) that a query I was passed was constructed with a specific formatter, and that formatter would encode any substrings that I templated into it in a way appropriate for SQL?

Yes. That's what Java's upcoming templated strings feature does. The library provides a templating policy as the way to create the appropriate type it requires.

> I wonder how this would handle something like HTML injection, where the desired encoding can change within the same string depending on whether you’re in an attribute or a text block?

The client library decides how to interpret and format the string in its policy.

Re:Format Strings in Rust 1.58 by thinkharderdev on Friday January 14, 2022 @08:03AM (#29933926)
But there is nothing enforcing the use of the correct template policy. I can still use the wrong CONCAT to build a SQL query. It certainly makes sense to make string interpolation extensible but doesn't actually eliminate the potential for doing things in an insecure way.
Re:Format Strings in Rust 1.58 by pron on Friday January 14, 2022 @08:10AM (#29933992)
We can't change the API of an existing library that already accepts strings for compatibility reasons (although we can make the safer API more attractive by making it more pleasant to use), but a new API can certainly enforce use of the correct policy by not accepting string parameters, only types that are constructed with the right policy, as the policy determines the type of the template and so the type system enforces the correct usage.
Re:Format Strings in Rust 1.58 by thinkharderdev on Friday January 14, 2022 @08:24AM (#29934129)
That is exactly my point. The way you can eliminate potential injection attacks is by not having libraries which accepts String and treat it as a sanitized input. But once you do that then there is no real reason to be wary of format strings. You can use format strings to build strings, but anything that needs a string that is sanitized against some potential injection attack only accepts a type that represents that invariant.
Re:Format Strings in Rust 1.58 by pron on Friday January 14, 2022 @08:27AM (#29934166)
> But once you do that then there is no real reason to be wary of format strings.

But then format strings don't help you much as you can't use them to create the sanitised types. You can't sanitise the string after it's been constructed.

Re:Format Strings in Rust 1.58 by thinkharderdev on Friday January 14, 2022 @08:49AM (#29934371)
Right, but there are many, many use cases for creating string in which you don't need some specific sanitization. Most of the time when I am using a format string I am not worried about sanitization.