Discussion:
[rust-dev] On the use of unsafe
Tony Arcieri
2014-09-21 06:29:21 UTC
Permalink
Traditionally in Rust, "unsafe" has centered around memory safety. The
reference manual describes it as such:

http://doc.rust-lang.org/rust.html#unsafety

At Strange Loop, during Chris Morgan's talk, someone asked about using the
type system to present SQL injection after he described using the type
system to handle escaping.

He suggested using unsafe to call out when a SQL query is being made with a
raw string.

On the one hand I really liked the clarity of calling out passing a raw
string to a SQL driver as being inherently unsafe, but on the other hand it
seems to be semantically different from Rust's traditional sense of what's
unsafe.

Is it ok to extend unsafe to things which are unsafe from a security
standpoint, or is this conflating concerns?

Should there be a standard way to express things which are potentially
unsafe from a security standpoint but not necessarily from a memory safety
standpoint?

I think something like that would be pretty cool. "insecure" ? ;)
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/74d97b62/attachment.html>
Daniel Micay
2014-09-21 06:34:38 UTC
Permalink
Post by Tony Arcieri
Traditionally in Rust, "unsafe" has centered around memory safety. The
http://doc.rust-lang.org/rust.html#unsafety
At Strange Loop, during Chris Morgan's talk, someone asked about using
the type system to present SQL injection after he described using the
type system to handle escaping.
He suggested using unsafe to call out when a SQL query is being made
with a raw string.
On the one hand I really liked the clarity of calling out passing a raw
string to a SQL driver as being inherently unsafe, but on the other hand
it seems to be semantically different from Rust's traditional sense of
what's unsafe.
Is it ok to extend unsafe to things which are unsafe from a security
standpoint, or is this conflating concerns?
Should there be a standard way to express things which are potentially
unsafe from a security standpoint but not necessarily from a memory
safety standpoint?
I think something like that would be pretty cool. "insecure" ? ;)
--
Tony Arcieri
It's not intended to be used for anything other than memory safety. The
requirements are the same across all libraries / applications. It's not
possible to represent the semantics of 'insecure' in the language as
that's very poorly defined and varies across domains and libraries.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/b15e3e25/attachment.sig>
Tony Arcieri
2014-09-21 06:39:26 UTC
Permalink
It's not possible to represent the semantics of 'insecure' in the
language as
that's very poorly defined and varies across domains and libraries.
I'd define it as "think before you use this"
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/5d342397/attachment.html>
Tony Arcieri
2014-09-21 06:41:16 UTC
Permalink
I'd also note: having a way of calling out these sorts of cases explicitly
is enormously beneficial to code reviewers. It provides an easily greppable
way to find where to focus their attention. I assume it would be beneficial
for static analysis tools as well.
Post by Tony Arcieri
It's not possible to represent the semantics of 'insecure' in the
language as
that's very poorly defined and varies across domains and libraries.
I'd define it as "think before you use this"
--
Tony Arcieri
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/abdad23f/attachment.html>
Tony Arcieri
2014-09-21 06:47:32 UTC
Permalink
Also, here's a paper that provides a formalized definition of security
domains using dependent types:

https://research.microsoft.com/en-us/um/people/nswamy/papers/gradual-typing-embedded-securely-in-javascript-draft.pdf

Would love to see Rust get dependent types eventually... but hey, I get it,
gotta ship 1.0 before anyone gets a pony? ;)
Post by Tony Arcieri
I'd also note: having a way of calling out these sorts of cases explicitly
is enormously beneficial to code reviewers. It provides an easily greppable
way to find where to focus their attention. I assume it would be beneficial
for static analysis tools as well.
Post by Tony Arcieri
It's not possible to represent the semantics of 'insecure' in the
language as
that's very poorly defined and varies across domains and libraries.
I'd define it as "think before you use this"
--
Tony Arcieri
--
Tony Arcieri
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/1e917100/attachment.html>
Simon Sapin
2014-09-21 09:57:33 UTC
Permalink
Post by Daniel Micay
It's not intended to be used for anything other than memory safety.
It?s also used to maintain invariants, such as the bytes inside a String
being valid UTF-8: String::push_bytes() is unsafe, but
String::push_str() is not.
--
Simon Sapin
Daniel Micay
2014-09-21 20:12:16 UTC
Permalink
Post by Simon Sapin
Post by Daniel Micay
It's not intended to be used for anything other than memory safety.
It?s also used to maintain invariants, such as the bytes inside a String
being valid UTF-8: String::push_bytes() is unsafe, but
String::push_str() is not.
No, it's not used to maintain invariants unrelated to memory safety.

Strings assume the contents are UTF-8 and violating that invariant would
violate memory safety.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/dd373208/attachment.sig>
Evan G
2014-09-21 20:27:15 UTC
Permalink
Personally, I feel "safety" generalizes pretty well to "any concept
that should be called out explicitly as unsafe"--not just memory
safety.
Post by Daniel Micay
Post by Simon Sapin
Post by Daniel Micay
It's not intended to be used for anything other than memory safety.
It?s also used to maintain invariants, such as the bytes inside a String
being valid UTF-8: String::push_bytes() is unsafe, but
String::push_str() is not.
No, it's not used to maintain invariants unrelated to memory safety.
Strings assume the contents are UTF-8 and violating that invariant would
violate memory safety.
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
richo
2014-09-21 23:33:22 UTC
Permalink
Post by Evan G
Personally, I feel "safety" generalizes pretty well to "any concept
that should be called out explicitly as unsafe"--not just memory
safety.
You can feel that all you want, but memory safety is reasonably
straightforward to define in a general context, whereas eg, unsafe string
interpolation of strings for a SQL query is not really the domain of the
compiler itself (rather, a problem for the type system).

See Go's html library for a bunch of hilarity when this goes sideways,
particularly some of the debate around comment handling.
Cameron Zwarich
2014-09-21 23:37:50 UTC
Permalink
Post by Evan G
Personally, I feel "safety" generalizes pretty well to "any concept
that should be called out explicitly as unsafe"--not just memory
safety.
The difference is that the current uses of `unsafe` are guarding things that cause a program to not have a defined meaning (ignoring the fact that Rust has no real semantics yet, so arguably no program has a defined meaning), whereas these other uses are for programs that have a defined meaning, just not the one that was intended.

Cameron
Daniel Micay
2014-09-21 23:40:31 UTC
Permalink
Post by Evan G
Personally, I feel "safety" generalizes pretty well to "any concept
that should be called out explicitly as unsafe"--not just memory
safety.
That's not how Rust defines `unsafe`. It's open to misuse, and the
compiler will happily point out that it's not being used correctly via
the unnecessary unsafe lint.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/c037929c/attachment.sig>
Manish Goregaokar
2014-09-22 02:50:40 UTC
Permalink
Post by Daniel Micay
That's not how Rust defines `unsafe`. It's open to misuse, and the
compiler will happily point out that it's not being used correctly via
the unnecessary unsafe lint.
If that's the case, do you think there's some worth in allowing the
programmer to define arbitrary generic safety types?

E.g have an `#[unsafe(strings)]` attribute that can be placed on methods
that break String guarantees (and placed on blocks where we wish to allow
such calls). `#[unsafe(sql)]` for SQL methods that are injection-prone. If
something like this slide
<https://www.youtube.com/watch?feature=player_detailpage&v=jVoFws7rp88#t=1664>
was ever implemented, methods that allow unsafe (XSS-prone) vulnerabilities
can have `#[unsafe(xss)]`.

Rust does a bunch of compile time checking to achieve memory safety. It
also provides a syntax extension/lint system that allows for programmers to
define further compile time checks, which open up the gate for many more
possible safety guarantees (instead of relying on separate static analysis
tools), and not just memory safety. Perhaps we should start recognizing and
leveraging that ability more :)

-Manish Goregaokar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/6c0df851/attachment.html>
Matthieu Monrocq
2014-09-22 16:40:06 UTC
Permalink
It's completely unnecessary actually.

If a method requires a XSS-safe string, then it should take the
XssSafeString parameter, which would implement Deref<String> and would be
built from a String by a method performing the necessary escaping.

If a method requires a SQL-safe string... ah no, don't do that, use
bind-parameters and you are guaranteed to be sql-injection safe.

In each case, the attributes so defined can be perfectly replaced with
appropriate types... so why not use types ?



On Mon, Sep 22, 2014 at 4:50 AM, Manish Goregaokar <manishsmail at gmail.com>
Post by Daniel Micay
That's not how Rust defines `unsafe`. It's open to misuse, and the
Post by Daniel Micay
compiler will happily point out that it's not being used correctly via
the unnecessary unsafe lint.
If that's the case, do you think there's some worth in allowing the
programmer to define arbitrary generic safety types?
E.g have an `#[unsafe(strings)]` attribute that can be placed on methods
that break String guarantees (and placed on blocks where we wish to allow
such calls). `#[unsafe(sql)]` for SQL methods that are injection-prone. If
something like this slide
<https://www.youtube.com/watch?feature=player_detailpage&v=jVoFws7rp88#t=1664>
was ever implemented, methods that allow unsafe (XSS-prone) vulnerabilities
can have `#[unsafe(xss)]`.
Rust does a bunch of compile time checking to achieve memory safety. It
also provides a syntax extension/lint system that allows for programmers to
define further compile time checks, which open up the gate for many more
possible safety guarantees (instead of relying on separate static analysis
tools), and not just memory safety. Perhaps we should start recognizing and
leveraging that ability more :)
-Manish Goregaokar
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/1e0632a9/attachment.html>
Manish Goregaokar
2014-09-22 17:16:32 UTC
Permalink
This had to do with XSS-proofing templates, which is a bit different and
requires compile time magic. I've seen people concatenate strings while
using prepared PDO queries in PHP -- nonnegotiable safety built in to the
library is much better. This can't be handled with a type system.

-Manish Goregaokar

On Mon, Sep 22, 2014 at 10:10 PM, Matthieu Monrocq <
Post by Matthieu Monrocq
It's completely unnecessary actually.
If a method requires a XSS-safe string, then it should take the
XssSafeString parameter, which would implement Deref<String> and would be
built from a String by a method performing the necessary escaping.
If a method requires a SQL-safe string... ah no, don't do that, use
bind-parameters and you are guaranteed to be sql-injection safe.
In each case, the attributes so defined can be perfectly replaced with
appropriate types... so why not use types ?
On Mon, Sep 22, 2014 at 4:50 AM, Manish Goregaokar <manishsmail at gmail.com>
Post by Daniel Micay
That's not how Rust defines `unsafe`. It's open to misuse, and the
Post by Daniel Micay
compiler will happily point out that it's not being used correctly via
the unnecessary unsafe lint.
If that's the case, do you think there's some worth in allowing the
programmer to define arbitrary generic safety types?
E.g have an `#[unsafe(strings)]` attribute that can be placed on methods
that break String guarantees (and placed on blocks where we wish to allow
such calls). `#[unsafe(sql)]` for SQL methods that are injection-prone. If
something like this slide
<https://www.youtube.com/watch?feature=player_detailpage&v=jVoFws7rp88#t=1664>
was ever implemented, methods that allow unsafe (XSS-prone) vulnerabilities
can have `#[unsafe(xss)]`.
Rust does a bunch of compile time checking to achieve memory safety. It
also provides a syntax extension/lint system that allows for programmers to
define further compile time checks, which open up the gate for many more
possible safety guarantees (instead of relying on separate static analysis
tools), and not just memory safety. Perhaps we should start recognizing and
leveraging that ability more :)
-Manish Goregaokar
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/c45fb58e/attachment.html>
Tony Arcieri
2014-09-22 17:39:54 UTC
Permalink
On Mon, Sep 22, 2014 at 9:40 AM, Matthieu Monrocq <
Post by Matthieu Monrocq
If a method requires a XSS-safe string, then it should take the
XssSafeString parameter, which would implement Deref<String> and would be
built from a String by a method performing the necessary escaping.
This relies on all paths to XssSafeString being "safe" ones, which may be
the case, but all it takes is a single chink in the armor for things to go
amiss. I'd also note that "SafeString" is a terrible name and has lead to a
lot of confusion in e.g. Ember.js. I'd suggest using "RawString" or
"RawQuery", which is a lot more indicative of its actual contents.

Having some sort of real taint analysis (or something akin to TS*'s Un
type) to solve problems like this generically (i.e. tainted strings should
not be used directly in any sort of templating would be a lot more
interesting. Maybe in Rust 9.0 ;)
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/0a3d520d/attachment.html>
Chris Morgan
2014-09-22 19:21:29 UTC
Permalink
Post by Matthieu Monrocq
It's completely unnecessary actually.
Would that it were. There was a time when I believed it was, but it's not.
Post by Matthieu Monrocq
If a method requires a XSS-safe string, then it should take the
XssSafeString parameter, which would implement Deref<String> and would be
built from a String by a method performing the necessary escaping.
This sort of thing is the idea?building it all into the type system is the
goal. The question was to do with getting around that, doing something that
would *not* be safe. You can build as great a library with the type system
as you like, but eventually someone will want?nay, need?an escape hatch.
Perhaps they are dealing with a legacy system that, alas, requires broken
behavior; or perhaps a performance issue with the normal way of doing it
needs to be circumvented. This part, breaking the rules in a reasonable
manner yet without it being so normal that everyone does it (*cough* PHP
*cough*), is the part that was being discussed at that point.

I consider `unsafe` to be entirely justified here because we're dealing
with data being able to break the invariants of the type. If, for an
arbitrary example, we have an HTML chunk we are going to emit and wish to
insert something known to be legal HTML as we emit it, there are shortcuts
that can be taken. But if it was not in fact legal HTML, the invariants of
the type are broken and the interpretation of the data no longer certain.
Thus it should be marked image, just like the UTF-8 constraint of strings.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/ecae72db/attachment.html>
Daniel Micay
2014-09-22 19:32:04 UTC
Permalink
Post by Chris Morgan
Post by Matthieu Monrocq
It's completely unnecessary actually.
Would that it were. There was a time when I believed it was, but it's not.
Post by Matthieu Monrocq
If a method requires a XSS-safe string, then it should take the
XssSafeString parameter, which would implement Deref<String> and would
be built from a String by a method performing the necessary escaping.
This sort of thing is the idea?building it all into the type system is
the goal. The question was to do with getting around that, doing
something that would *not* be safe. You can build as great a library
with the type system as you like, but eventually someone will want?nay,
need?an escape hatch. Perhaps they are dealing with a legacy system
that, alas, requires broken behavior; or perhaps a performance issue
with the normal way of doing it needs to be circumvented. This part,
breaking the rules in a reasonable manner yet without it being so normal
that everyone does it (*cough* PHP *cough*), is the part that was being
discussed at that point.
I consider `unsafe` to be entirely justified here because we're dealing
with data being able to break the invariants of the type. If, for an
arbitrary example, we have an HTML chunk we are going to emit and wish
to insert something known to be legal HTML as we emit it, there are
shortcuts that can be taken. But if it was not in fact legal HTML, the
invariants of the type are broken and the interpretation of the data no
longer certain. Thus it should be marked image, just like the UTF-8
constraint of strings.
Rust doesn't use `unsafe` to uphold the UTF-8 invariant of strings. It
uses `unsafe` as a memory safety boundary, and in this case breaking the
invariant would be memory unsafe.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/99b4ef3c/attachment.sig>
Tony Arcieri
2014-09-22 21:12:14 UTC
Permalink
On Mon, Sep 22, 2014 at 12:32 PM, Daniel Micay <danielmicay at gmail.com>
Post by Daniel Micay
Rust doesn't use `unsafe` to uphold the UTF-8 invariant of strings. It
uses `unsafe` as a memory safety boundary, and in this case breaking the
invariant would be memory unsafe.
I just want to say that I completely agree with you that "unsafe" is the
wrong tool for the job here.

However there is still a problem I feel is potentially solved via type
systems, not necessarily Rust's, only if Rust chooses to rise to the
challenge.

After 1.0 might be a good time to start considering these problems. I know
you already have enough work on your plate as-is.
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/1f45ec37/attachment.html>
Daniel Micay
2014-09-22 21:15:36 UTC
Permalink
Post by Tony Arcieri
On Mon, Sep 22, 2014 at 12:32 PM, Daniel Micay <danielmicay at gmail.com
Rust doesn't use `unsafe` to uphold the UTF-8 invariant of strings. It
uses `unsafe` as a memory safety boundary, and in this case breaking the
invariant would be memory unsafe.
I just want to say that I completely agree with you that "unsafe" is the
wrong tool for the job here.
However there is still a problem I feel is potentially solved via type
systems, not necessarily Rust's, only if Rust chooses to rise to the
challenge.
After 1.0 might be a good time to start considering these problems. I
know you already have enough work on your plate as-is.
I think it can be solved by using visibility, along with providing a way
to override the visibility rules and call private functions. That means
replacing the current usage of visibility for memory safety with unsafe
fields though, but I think that's important to make the memory safety
boundary work properly anyway.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/3dc1a74b/attachment.sig>
Tony Arcieri
2014-09-22 21:31:51 UTC
Permalink
Post by Daniel Micay
I think it can be solved by using visibility, along with providing a way
to override the visibility rules and call private functions. That means
replacing the current usage of visibility for memory safety with unsafe
fields though, but I think that's important to make the memory safety
boundary work properly anyway.
Just to clarify what I see going on here and how other (type) systems have
solved this:

For things like XSS and SQLi, the problem is untrusted off-the-wire data
being used in what is more or less a "secure" context.

Some might refer to this sort of untrusted off-the-wire data as "tainted"
and try to use some sort of taint analysis to solve the problem. The TS*
dependent type system refers to it as "Un" (i.e. untrusted) and relies on
its dependent type system to prove Un data isn't used in a secure context.
Very fancy and possibly overkill, but that said, a pretty awesome solution
to the problem.

There is a *generic* problem here of using such untrusted data in any sort
of templating or metalinguistic context. The general problem is OWASP #1:
failure to sanitize input, affecting vulnerabilities like XSS, SQLi, and
LDAP injection.

I am absolutely certain this affects systems like Servo as well ;)

Preventing untrusted data from penetrating the secure contexts of the
program using the type system has the potential to mitigate the most common
security vulnerabilities if done correctly.
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/43e184b3/attachment.html>
Manish Goregaokar
2014-09-22 22:45:30 UTC
Permalink
As Chris mentioned, it's not about using the type system to create safety.
We're assuming that exists, the idea is to gate unchecked access to the
data (which *is* required for libraries created for generic use) with the
`unsafe` keyword. However, many seem to be of the opinion that `unsafe` is
just for memory safety, in which case it would be nice to have a wider
range of `unsafe` attributes (or something) which allow us to gate methods
that are prone to SQL injection (etc etc).

-Manish Goregaokar
Post by Tony Arcieri
Post by Daniel Micay
I think it can be solved by using visibility, along with providing a way
to override the visibility rules and call private functions. That means
replacing the current usage of visibility for memory safety with unsafe
fields though, but I think that's important to make the memory safety
boundary work properly anyway.
Just to clarify what I see going on here and how other (type) systems have
For things like XSS and SQLi, the problem is untrusted off-the-wire data
being used in what is more or less a "secure" context.
Some might refer to this sort of untrusted off-the-wire data as "tainted"
and try to use some sort of taint analysis to solve the problem. The TS*
dependent type system refers to it as "Un" (i.e. untrusted) and relies on
its dependent type system to prove Un data isn't used in a secure context.
Very fancy and possibly overkill, but that said, a pretty awesome solution
to the problem.
There is a *generic* problem here of using such untrusted data in any sort
failure to sanitize input, affecting vulnerabilities like XSS, SQLi, and
LDAP injection.
I am absolutely certain this affects systems like Servo as well ;)
Preventing untrusted data from penetrating the secure contexts of the
program using the type system has the potential to mitigate the most common
security vulnerabilities if done correctly.
--
Tony Arcieri
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140923/7482a743/attachment.html>
Tony Arcieri
2014-09-22 22:52:33 UTC
Permalink
On Mon, Sep 22, 2014 at 3:45 PM, Manish Goregaokar <manishsmail at gmail.com>
Post by Manish Goregaokar
As Chris mentioned, it's not about using the type system to create safety.
We're assuming that exists
The sort of safety I'm describing does not exist in Rust whatsoever AFAIK.
The very specific approach I'm referring to depends on dependent types,
which Rust does not implement, and I would suggest you look to for future,
post-1.0 food for thought:

https://research.microsoft.com/en-us/um/people/nswamy/papers/gradual-typing-embedded-securely-in-javascript-draft.pdf

the idea is to gate unchecked access to the data (which *is* required for
Post by Manish Goregaokar
libraries created for generic use) with the `unsafe` keyword.
Many, including myself, have expressed the opinion that "unsafe" is
ill-suited to this sort of safety-by-taint analysis and security contexts.
In my OP, I suggested it was colluding concerns. This, again, goes back to
Chris Morgan's Strange Loop talk. I may be misinterpreting what he was
suggesting too, it'd be great to hear from him directly!

I think there needs to be a different security context for these sorts of
problems.
Post by Manish Goregaokar
However, many seem to be of the opinion that `unsafe` is just for memory
safety, in which case it would be nice to have a wider range of `unsafe`
attributes (or something) which allow us to gate methods that are prone to
SQL injection (etc etc).
Yes, however the cases of SQLi, XSS, and LDAP injection all depend on using
untrusted data in trusted contexts, which is a fundamentally different
problem from what Rust is trying to solve with "unsafe", and the solutions
the type system should pursue to solve these problems are different.

All that said, even in the absence of a dependent type system, I think Rust
can *being* to call these cases out in advance, if only for the benefit of
human code review, but with the goal of the eventual inclusion of something
in the type system to formally verify these sorts of guarantees.

The specific use case is quite clear to me: inclusion of tainted data in
secure strings. There are many systems today in which this would be an
error.

I can totally understand omitting these sorts of things until there is a
formal correctness check in the complier. At the same time, these are the
sorts of cases I feel need to be called out while they're fresh in people's
minds.
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/8dae3902/attachment.html>
Daniel Micay
2014-09-22 23:31:17 UTC
Permalink
Post by Manish Goregaokar
As Chris mentioned, it's not about using the type system to create
safety. We're assuming that exists, the idea is to gate unchecked access
to the data (which /is/ required for libraries created for generic use)
with the `unsafe` keyword. However, many seem to be of the opinion that
`unsafe` is just for memory safety, in which case it would be nice to
have a wider range of `unsafe` attributes (or something) which allow us
to gate methods that are prone to SQL injection (etc etc).
-Manish Goregaokar
It's not an opinion, it's how it's defined in the documentation (see the
Rust manual) and the compiler warns about unnecessary usage of `unsafe`
- which could be finished if there were `unsafe` fields.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/6b0bea20/attachment.sig>
Manish Goregaokar
2014-09-23 01:02:00 UTC
Permalink
I'm not talking about unsafe fields. (maybe I gave that impression? Sorry.)

That's how it is defined in the manual, sure, but the language is changing
:) Anyway, as mentioned before we don't need to use `unsafe` for non-memory
safety guarantees, if we define anothe attribute that genericises it.

-Manish Goregaokar
Post by Daniel Micay
Post by Manish Goregaokar
As Chris mentioned, it's not about using the type system to create
safety. We're assuming that exists, the idea is to gate unchecked access
to the data (which /is/ required for libraries created for generic use)
with the `unsafe` keyword. However, many seem to be of the opinion that
`unsafe` is just for memory safety, in which case it would be nice to
have a wider range of `unsafe` attributes (or something) which allow us
to gate methods that are prone to SQL injection (etc etc).
-Manish Goregaokar
It's not an opinion, it's how it's defined in the documentation (see the
Rust manual) and the compiler warns about unnecessary usage of `unsafe`
- which could be finished if there were `unsafe` fields.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140923/3c4bc89f/attachment.html>
Florian Weimer
2014-10-03 10:56:36 UTC
Permalink
Post by Matthieu Monrocq
If a method requires a SQL-safe string... ah no, don't do that, use
bind-parameters and you are guaranteed to be sql-injection safe.
Sometimes, SQL queries (with parameter placeholders) are loaded from
configuration files, and such operations look unsafe from the point of
view of most (reasonable) type systems.
Kevin Cantu
2014-10-04 01:27:00 UTC
Permalink
It seems natural to conflate memory (to which "unsafe" refers to uses
of) and types.

It might make sense to extend the terminology to types: perhaps
"bottom" could express a similar thing: that beyond which the compiler
is uncertain.

However, if we tried to extend this terminology directly into
higher-level statements like "secure" vs. "insecure", unless there's
actually a way to define requirements and get a compiler to prove a
program with a bunch of SQL queries is secure, I'm not comfortable
giving devs. a tool with which to lie to themselves. :D


Kevin
Post by Florian Weimer
Post by Matthieu Monrocq
If a method requires a SQL-safe string... ah no, don't do that, use
bind-parameters and you are guaranteed to be sql-injection safe.
Sometimes, SQL queries (with parameter placeholders) are loaded from
configuration files, and such operations look unsafe from the point of
view of most (reasonable) type systems.
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
Cameron Zwarich
2014-09-21 07:02:23 UTC
Permalink
He suggested using unsafe to call out when a SQL query is being made with a raw string.
On the one hand I really liked the clarity of calling out passing a raw string to a SQL driver as being inherently unsafe, but on the other hand it seems to be semantically different from Rust's traditional sense of what's unsafe.
Is it ok to extend unsafe to things which are unsafe from a security standpoint, or is this conflating concerns?
Should there be a standard way to express things which are potentially unsafe from a security standpoint but not necessarily from a memory safety standpoint?
The usual solution to this particular problem in typed languages is to make a new type wrapping sanitized strings, use some feature of the language (e.g. abstract types or module privacy) to restrict the creation of instances of this new type, and expose functions that produce an instance of this type by sanitization. I think that this is a better use of the language than using ?unsafe? in a confusing and unidiomatic way.

Rust doesn?t really provide any specific features for security beyond memory safety, but it should be possible to extend the language to support things like information-flow security, etc.

Cameron
Tony Arcieri
2014-09-21 07:06:51 UTC
Permalink
On Sun, Sep 21, 2014 at 2:02 AM, Cameron Zwarich <zwarich at mozilla.com>
Post by Cameron Zwarich
The usual solution to this particular problem in typed languages is to
make a new type wrapping sanitized strings, use some feature of the
language (e.g. abstract types or module privacy) to restrict the creation
of instances of this new type, and expose functions that produce an
instance of this type by sanitization. I think that this is a better use of
the language than using ?unsafe? in a confusing and unidiomatic way.
Definitely, a SQL driver should operate on a RawQuery or what have you.

Rust doesn?t really provide any specific features for security beyond
Post by Cameron Zwarich
memory safety, but it should be possible to extend the language to support
things like information-flow security, etc.
Yeah, the paper I linked describes using dependent types to do what is
effectively taint checking by proof
--
Tony Arcieri
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140921/d6825749/attachment.html>
Loading...