Librairie SandBox développé par Firefox.
Doc Archive du 31/03/202 le 08/08/2020
Code source Archive du 17/07/2020 le 08/08/2020
Théorie Archive du 10/03/2020 le 08/08/2020
Diaporama Archive du 22/07/2020 le 13/07/2021
De ce que j'ai compris, cela force la réalisation d'une copie dans le tas de la donnée à transmettre à la librairie.
Cela est sécuritaire car :
const
dans la librairie, elle vient peut-être d'une donnée où la mémoire est accessible en écriture. ASLR
(Address space layout randomization) ou de déduire le pointeur vers la table virtuelle.La libération de la mémoire du texte renvoyé est à notre charge.
#define RLBOX_SINGLE_THREADED_INVOCATIONS #define RLBOX_USE_STATIC_CALLS() rlbox_noop_sandbox_lookup_symbol #include <iostream> #include <memory> #include <mutex> #include <optional> #include <rlbox.hpp> #include <rlbox_noop_sandbox.hpp> #include <string_view> #include <simdjson.h> // Classe libérant la mémoire quand la donnée n'est plus utilisée. template <typename T> class AutoFree { public: AutoFree(rlbox::tainted<T, rlbox::rlbox_noop_sandbox> taint) : _taint(taint) { } ~AutoFree() { free(_taint.UNSAFE_unverified()); } rlbox::tainted<T, rlbox::rlbox_noop_sandbox>& get() { return _taint; } private: rlbox::tainted<T, rlbox::rlbox_noop_sandbox> _taint; }; // Fonction risquée char* unsecure_function(char* data, int nb) { char* retval = static_cast<char*>(malloc(sizeof(char) * (strlen(data) + 1))); strcpy(retval, data); return retval; } // Fonction sécurisée std::string secure_function(rlbox::rlbox_sandbox<rlbox::rlbox_noop_sandbox>& sandbox, const std::string& unsafe_data) { size_t helloSize = unsafe_data.length() + 1; auto taintedStr = sandbox.malloc_in_sandbox<char>(helloSize); // La librairie n'ayant pas la possibilité d'écrire, on le fait à sa place. std::strncpy( taintedStr.unverified_safe_pointer_because(helloSize, "writing only"), unsafe_data.c_str(), helloSize); // On récupère la valeur de retour de façon sécurisée. AutoFree<char*> retvalTainted( sandbox.invoke_sandbox_function(unsecure_function, taintedStr, 3)); // On récupère la valeur de retour après vérification. auto retval = retvalTainted.get().copy_and_verify_string( [](std::unique_ptr<char[]> ret) -> std::optional<std::string> { size_t len = strlen(ret.get()); if (simdjson::validate_utf8(ret.get(), len)) return std::optional<std::string>(std::string{ret.get(), len}); else return std::nullopt; }); sandbox.free_in_sandbox(taintedStr); return retval.value_or("nullptr"); } int main() { rlbox::rlbox_sandbox<rlbox::rlbox_noop_sandbox> sandbox; sandbox.create_sandbox(); std::cout << secure_function(sandbox, std::string{"\xc3\xb1"}) << std::endl; std::cout << secure_function(sandbox, std::string{"\xc3\x28"}) << std::endl; sandbox.destroy_sandbox(); }