Remote execution vulnerabilities
Added by Noah Lopez over 8 years ago
This is kind of a follow up to an earlier post: http://redmine.webtoolkit.eu/boards/1/topics/11879.
I just want to let people know about a library I wrote to prevent "invalid memory access" bugs in C (https://github.com/duneroadrunner/SaferCPlusPlus). I'm not sure how concerned existing Wt users are with web security, but in general I think the reason C is not a popular language for webapps is a legitimate one, namely that C is the only modern language that is prone to invalid memory access bugs, and therefore, "remote execution" vulnerabilities.
While recently there have been advances in tools (static analyzers in particular) to improve C code quality, ultimately they don't solve the problem and we still live in a world where, for example, critical vulnerabilities are regularly discovered in all the major web browsers implemented in C. The majority of those critical vulnerabilities being C/C specific memory access bugs.
But with C+11, it is possible to replace C+'s "unsafe" elements (pointers, arrays, stl containers, etc.) with compatible, "safe" direct substitutes. Of course there's a run-time performance cost, but it's modest and significantly less than, say, switching to Java.
I use the library in my Wt projects, but ideally I would feel better if the Wt framework itself used the library, or something like it, to eliminate the possibility of remote execution vulnerabilities. The nice thing about this "SaferCPlusPlus" library is that the run-time safety checks can be turned off with a compile-time directive. So you could imagine, for example, a developer enabling the run-time safety checks for testing, and perhaps a "probationary" period of initial deployment, then turning them off after that.
The other nice thing is that when the library's safety checks are "turned off" the "safe" elements revert to their (unsafe) native counterparts so the Wt framework would remain compatible with all the existing Wt code out there. Basically it would be a straightforward way for the Wt framework to ensure memory safety and maintain compatibility with existing interfaces (though not both simultaneously, you have to choose at compile-time) without re-architecting any code.
I just think that using a library like this can dispatch one of the main arguments against using C for webapps, perhaps greatly expanding the potential Wt userbase.
Just my 2 cents.
Replies (5)
RE: Remote execution vulnerabilities - Added by Koen Deforche over 8 years ago
Hey Noah,
We've made advances since also on Wt 4, which is based entirely on C+11 and follows common idioms in C11. This includes the use of pointers that indicate explicit ownership (std::shared_ptr and std::unique_ptr) in the API, and, as it's the idiom, naked pointers for 'non-owning' pointers. We do understand that indeed this is not safe against dangling pointers, and personally I'm no fan, but we feel that we have to align ourselves with what is idiomatic in C+11.
We do in fact offer a 'registered pointer' (which in Wt we ended naming 'observing_ptr') which has the functionality of avoiding dangling pointers just in the same way as you describe, and a user of our library is free to use it whenever he wants to keep hold of a non-owning pointer (roughly for all 'members' inside his own classes referencing widgets or other Wt::WObject's.
Regards,
koen
RE: Remote execution vulnerabilities - Added by Noah Lopez over 8 years ago
Thanks for responding. What I'm dreaming about is an optional compile flag that would produce a "memory safe" version of the Wt framework. Just as an option. The only technical impediment to this would be if Wt's API relied on C's intrinsically unsafe elements (like it does now), like raw pointers, and even std::unique_ptr
and std::shared_ptr
. So I'm recommending/requesting that instead of using raw pointers, std::unique_ptrs and std::shared_ptrs directly, the new Wt API instead use aliases for these elements. So instead of, for example,
WTemplate(const WString& text, WContainerWidget *parent = 0);
it would be
WTemplate(const WString& text, Wt::Pointer<WContainerWidget> parent = 0);
where, by default, "Wt::Pointer<WContainerWidget>
" is just an alias for "WContainerWidget *
". But, at some point in the future, when you compile with the WT_MEMORY_SAFE flag, it will be aliased to "Wt::RegisteredPointer<WContainerWidget>
" or whatever.
Similarly, an API function like this
void bindWidget(const std::string& varName, std::shared_ptr<WWidget> widget)
would become
void bindWidget(const std::string& varName, Wt::WSharedPtr<WWidget> widget)
where, by default, "Wt::WSharedPtr<WWidget>
" is just an alias for std::shared_ptr<WWidget>
, but with the WT_MEMORY_SAFE flag, it might map to a safer substitute like mse::TRefCountingPointer<WWidget>
that, among other things, checks for attempted dereference of null pointer value.
I wouldn't say that these aliases contravene "C idioms". If the alias names are well chosen, "ownership" and intent will be clear. I really can't imagine that any C programmer would take issue with the API using these aliases?
I suppose that in theory JWt should be a "memory safe" option. But i) I much prefer C to Java (if only for RAII), ii) given the history of JVM bugs, in practice I think C could be the better choice from a security perspective, and iii) C would still be generally faster (and more memory efficient) even with the run-time memory checks.
For the desperate, there is kind of an existing solution to add memory safety (including run-time checks) to the Wt framework, and that is to compile with the "address", "memory" and "undefined behavior" sanitizer flags enabled in clang or gcc. The only problems with this solution being that i) upon detecting an error the program terminates (instead of throwing an exception), ii) it's really slow and iii) it apparently doesn't catch all errors.
I just think that these days doesn't security have to be a priority? At least optionally?
RE: Remote execution vulnerabilities - Added by Koen Deforche over 8 years ago
It would be great if we could look in the head of the Wt user, or the prospective future Wt user, then we can simply decide. I just am not confident right now that people are going to not be upset with an alias for std::unique_ptr and std::shared_ptr in their user-interface.
What is however an option is to do the switch at library compile-time, and also let doxygen substitute the preprocessor macro. In this way, the documentation would still read 'std::unique_ptr<>' and all would be nicely standard if the user didn't care about the memory-safe variant. If the user prefers the memory-safe variant he can build Wt with the mse:: equivalents instead? We're applying this trick already in the Wt API with unicode string types here and there for our JWt target.
RE: Remote execution vulnerabilities - Added by Noah Lopez over 8 years ago
Yes that's what I meant, the choice would be made at the time of compiling the Wt framework. I didn't realize that doxygen could do macro expansion, but yes that's perfect. Having the option of a memory-safe variant that's invisible to those that aren't interested.
Initially, I wasn't sure that Wt could be a mainstream solution because of all the round-trip traffic as a result of so much being done on the server-side. But I'm finding that internet connections are good enough these days that I hardly notice any latency. Even on mobile. Are others observing something different? And from a security perspective it's nice to have everything on the server-side because it reduces the amount of client-side javascript that could be manipulated by a malicious actor. And it enables you to, for example, measure the timing of user interface events to ensure that it's an actual human using your webpage. Or maybe even verify that it's a specific human.
I'm just saying that it seems to me that what was a drawback of the Wt architecture (all the round-trip traffic) when internet connections were slower, may now be an advantage over traditional web architectures. Or am I missing something? Scalability issues?
It just seems to me that with the memory-safety issue addressed, Wt could be advertised as an outright better platform than the alternatives. No?
RE: Remote execution vulnerabilities - Added by Wim Dumon over 8 years ago
Hello Noah,
You're right that the round-trip usually doesn't matter. In real-life applications, we typically have one or two widgets where a client-side application would benefit from the server-side implementation, but often we don't get to optimize it because it's still considered good enough by the customers.
I'm biased in my opinion, but yes, Wt can be considered superior the alternatives :-)
Best regards,
Wim.