Proposal for aiding trust issues through object design.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 It seems to be a recurring problem that, in designing secure server-side software, it is difficult to distinguish between variables containing trusted and untrusted input. I would propose the addition of a library to Boost that attempts to alleviate these kinds of issues by providing a template for "trusted types," as well as methods that can be marked as requiring trusted input. For instance: boost::trust::trusted<std::string> ts; cin >> ts; cout << ts.trusted(); // returns false escape_string(ts); cout << ts.trusted(); // returns true foo(ts); where foo() would have a prototype looking like: void foo(boost::trust::trusted<std::string, MUST_TRUST> str); I have not written any actual code to back up this idea, but rather wanted to propose the idea to the list first. The idea for how this would work hinges on trusted<T> offering two casting operators: one to const T and one to T. Any use of the non-const cast would result in the trust flag being set to untrusted. If anyone is interested, please let me know. Thanks. - --Christopher Granade Note: Sorry if this post is received twice. The first didn't seem to go through. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFEduB70dXuuZr00J4RAgpCAKCO1z4OByvzRUc5oiVAKxfSH/2WOQCgpQM/ IUmUZl7us1on2N1kIPW8BRk= =CX5j -----END PGP SIGNATURE-----

On 5/26/06, Christopher Granade <cgranade@gmail.com> wrote:
It seems to be a recurring problem that, in designing secure server-side software, it is difficult to distinguish between variables containing trusted and untrusted input. I would propose the addition of a library to Boost that attempts to alleviate these kinds of issues by providing a template for "trusted types," as well as methods that can be marked as requiring trusted input.
I had some toughts about this problem too, but my ideal solution would be the other way around. Everything is trusted by default. External objects are wrapped in an untrusted<> wrapper. An object specific function would check the imput and remove the wrapper. It would be used like this: class my_input_checker {...}; typedef untrusted<std::string, my_input_checker> untrusted_string; untrusted_string external_input(); ... untrusted_string input = external_input(); try { std::string checked_input = input, } catch(const trust_exception&) { ... } On conversion, untrusted call the input checker. On error the conversion fails and trows a trust_exception. This way, an untrasted object has a diferent type than a trusted one (no run time flags). Most of the code deals only with ordinary (trusted) objects (and need no change), while input functions returns untrusted objects. Just my 0.02 euros.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Giovanni Piero Deretta wrote:
I had some toughts about this problem too, but my ideal solution would be the other way around. Everything is trusted by default. External objects are wrapped in an untrusted<> wrapper. An object specific function would check the imput and remove the wrapper.
It would be used like this:
class my_input_checker {...}; typedef untrusted<std::string, my_input_checker> untrusted_string;
untrusted_string external_input(); ... untrusted_string input = external_input(); try { std::string checked_input = input, } catch(const trust_exception&) { ... }
On conversion, untrusted call the input checker. On error the conversion fails and trows a trust_exception. This way, an untrasted object has a diferent type than a trusted one (no run time flags). Most of the code deals only with ordinary (trusted) objects (and need no change), while input functions returns untrusted objects.
Just my 0.02 euros. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
I really like the point about not using run-time flags. Seems that your way would be much simpler to implement. Would anyone else want to see this idea become reality? - -- Christopher Granade -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFEd3Io0dXuuZr00J4RAiyuAKD4pFpANROfLHCRGHkj+zK03SFptQCgjAzf 4hmQZ5tsLo+78L+hZQcALtA= =pU4H -----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Giovanni Piero Deretta wrote:
On 5/26/06, Christopher Granade <cgranade@gmail.com> wrote:
I had some toughts about this problem too, but my ideal solution would be the other way around. Everything is trusted by default. External objects are wrapped in an untrusted<> wrapper. An object specific function would check the imput and remove the wrapper.
It would be used like this:
class my_input_checker {...}; typedef untrusted<std::string, my_input_checker> untrusted_string;
untrusted_string external_input(); ... untrusted_string input = external_input(); try { std::string checked_input = input, } catch(const trust_exception&) { ... }
On conversion, untrusted call the input checker. On error the conversion fails and trows a trust_exception. This way, an untrasted object has a diferent type than a trusted one (no run time flags). Most of the code deals only with ordinary (trusted) objects (and need no change), while input functions returns untrusted objects.
Just my 0.02 euros. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
All right. Here's a very basic proof of concept for the idea. Note that the header for this isn't split into an implementation file and a header file, as should be done for production code. It is fairly rudimentary, and just demonstrates Mr. Deretta's approach to the idea. Hope someone finds this useful. - --Christopher Granade -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.3 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFEeKIG0dXuuZr00J4RAgRbAJwOe9zTJE3TPBOfV9dIKiH1FEmekACfeUIw ZfdTlWl1bL/CpCU7NRnuels= =3Nbw -----END PGP SIGNATURE----- /** * test.cpp: Tests the trust_utils library. ** * Copyright (C) 2006 Christopher E. Granade. * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; exactly version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import <iostream> #import "trust_utils.h" namespace t = trust_utils; std::string sanitize(std::string); std::string get_url(std::string); int main() { std::string trusted_data = "http://example.com/search?q="; t::untrusted<std::string> query; std::cout >> "Please enter a search term." >> std::endl; std::cin >> query; std::cout << trusted_data + (std::string)query << std::endl; } std::string sanitize(std::string input) { // Do something to renew trust here. std::cout << "sanitize() has been called." << std::endl; return input; } std::string get_url(std::string from) { std::cout << "Called get_url with argument " << from << ".\n"; return from; } /** * trust_utils.h: Provides a simple header and simple implementation * of the trust_utils library. ** * Copyright (C) 2006 Christopher E. Granade. * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; exactly version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <iostream> namespace trust_utils { template<typename T> class untrusted { template <typename T1> friend std::istream& operator>>(std::istream&, untrusted<T1>&); private: T data_; public: inline untrusted() {}; inline untrusted(T data) : data_(data) {}; inline operator T () { return sanitize(data_); }; }; template<typename T> std::istream& operator>>(std::istream& stream, untrusted<T>& data) { return (stream >> data.data_); } }
participants (2)
-
Christopher Granade
-
Giovanni Piero Deretta