9 ms·
Important security vulnerabilities in OpenVPN
- yuchi 9y agoI’m gonna take the burden (someone would do that eventually anyway) and ask: how many of those issues would have been completely prevented by using a safer language such as Rust? How many would have been mitigated? I’m not a system programmer and the article, while indeed interesting, can be a little obscure.
- alltakendamned 9y agoI really think this is the wrong way to look at issues like this. Software has bugs, some of which are security bugs. Whenever someone goes through the effort of looking at software from a security perspective, issues might get identified and resolved and as such there is an incremental increase in security. Switching languages requires a full rewrite, which is often not only impractical, it will introduce new bugs as the maturity of the software will plummet because of the rewrite. Then the cycle simply starts again. Some languages have better features that may prevent some classes of security bugs, and Rust is just the new kid on the block. As such, new languages are unproven in the security area and there will be security bugs found there as well. Java and .NET don't have the same issues either but somehow nobody will ask about those :) But then again, Rust introduces other bug types for which the future will tell whether they have a security impact or not: https://gankro.github.io/blah/only-in-rust/ https://gankro.github.io/blah/only-in-rust/ My point of this rambling is that yes, C code is really hard to get right from a security perspective. But software like Apache httpd and OpenSSH demonstrates clearly it can be done. And switching languages is not the answer.
- tinco 9y agoHow do Apache and OpenSSH demonstrate that C code can be done right from a security perspective?
- alltakendamned 9y agoBy the lack of any serious vulnerabilities over the past years. If you're willing to give it a go, an Apache bug would've fetched you 200K$ at the latest Pwn2Own.
- tinco 9y agoOver the past years Apache httpd has had 187 vulnerabilities, 24 of which had potential remote code execution consequences. I'm not saying anyone is ever going to find another RCE in Apache. I'll even go as far as to say it's not very likely. But I don't think develop a server and then put it in the world's most hostile environments for 20 years until we're certain it's safe is a particularily efficient development strategy. People should stop building stuff in C, it's that simple.
- omginternets 9y ago>People should stop building stuff in C, it's that simple. I would attenuate this in one sense and amplify it in another: it's (almost always) irresponsible to write network-facing code in C.
- pjmlp 9y agoWhich is why although I dislike some decisions regarding Go's type system, I advocate its use by devops and UNIX userspace apps, the less C the better, regardless if Go has or not generics.
- alltakendamned 9y agoOK, you're not wrong here, but let's qualify your answer a little bit for the people that are less "into this" and to introduce some intellectual honesty in the discussion. Apache has had 187 known vulnerabilities _since 1999_. The full list can be found at http://www.cvedetails.com/product/66/Apache-Http-Server.html?vendor_id=45 http://www.cvedetails.com/product/66/Apache-Http-Server.html... Of the 24 remote code execution bugs you mention, only 4 of them were found in the last 8 years. The one before dates from 2007. Of those 4, only 1 of them was considered critical, and even that one is Windows only. The others don't even breach a CVSS score of 7. So yeah, I stand by my comment that they have a pretty good track records over the past years. And as to stop building stuff in C, I agree that if you start a new project today that depends heavily on network facing code, parsing of untrusted input and does not have massive speed requirements, there are other language choices one could make. But rebuilding Apache in a memory safe language? Oh well, the beauty of open source is that anyone can take a stab at it.
- lmm 9y ago> Switching languages requires a full rewrite Not true when those languages are ABI-compatible. E.g. I believe librsvg is introducing small amounts of Rust that can eventually become a gradual migration. > it will introduce new bugs as the maturity of the software will plummet because of the rewrite. Citation needed. I would expect a rewrite guided by an existing implementation (not the same thing as a rewrite aimed at achieving a from-scratch redesign) to result in fewer bugs as it would effectively be equivalent to a full code review, and that's before we take into account the difference-of-language effects. > As such, new languages are unproven in the security area and there will be security bugs found there as well. No. There are specific reasons C is so awful; it's not a question of maturity. > Java and .NET don't have the same issues either but somehow nobody will ask about those :) People are dumb. There's a popular myth that these languages are inherently slow, which combined with some genuine licensing issues means the OSS community doesn't use them, even though they'd be a perfect fit for OpenVPN-like processes. > But then again, Rust introduces other bug types for which the future will tell whether they have a security impact or not: https://gankro.github.io/blah/only-in-rust/ https://gankro.github.io/blah/only-in-rust/ No, read your link. Those issues happen only in unsafe code, and at absolute worst mean you're as badly off as you would be in C. > software like Apache httpd and OpenSSH demonstrates clearly it can be done Because those programs can go years at a time without a major security vulnerability? Oh wait, no they can't. Switching languages is absolutely the answer, and the sooner we get over ourselves and get on with it the better.
- laumars 9y ago> Citation needed. I would expect a rewrite guided by an existing implementation (not the same thing as a rewrite aimed at achieving a from-scratch redesign) to result in fewer bugs as it would effectively be equivalent to a full code review, and that's before we take into account the difference-of-language effects. Humans are fallible. Rewriting the code introduces the possibility that the human coding it might make a mistake. This is true even when using existing code as a guide.
- lmm 9y agoTrue as far as it goes, but I would still expect the bugs caught by the rewrite to outweigh the newly-introduced ones most of the time.
- duneroadrunner 9y ago> Switching languages requires a full rewrite ... It's not ready for use in the wild, but I'll just mention that some good progress is being made on a "C to SaferCPlusPlus[1]" auto-translation assistant. (SaferCPlusPlus is essentially a memory-safe subset of C++.) At this point it can recognize arrays and "pointers used as array iterators" in C code and replace them with memory-safe substitutes. Hopefully an (incomplete but) usable version will be available before long and we can gauge the interest of developers/maintainers. [1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus https://github.com/duneroadrunner/SaferCPlusPlus
- 19218391 9y agoWe can answer that question when (if?) people actually start writing programs in Rust instead of speculating.
- willvarfar 9y agoMany of these bugs are specific to memory-unsafe languages. Writing in a memory-safe language would prevent many of these vulnerabilities. It would not stop all vulnerabilities.
- eeZah7Ux 9y ago...and even introduce new issues: https://gankro.github.io/blah/only-in-rust/ https://gankro.github.io/blah/only-in-rust/
- sillysaurus3 9y agoOpenSSL's security is hard to beat. Constant code audits plus massive usage equals pretty secure software. The vulns in the blog post are denial of service bugs: memory exhaustion and an assertion crash. While these good to fix, they have little impact on security. You're much more likely to introduce hundreds of bugs attempting to port it to Rust than just maintaining OpenSSL's C code. Of course, you could try porting the codebase line-by-line to Rust. It'd certainly be an interesting challenge. But once you're done, you'll need to convince everybody to abandon a hardened, audited codebase for an untested, unaudited codebase written in an unfamiliar language, with a nascent open source ecosystem (mailing lists, CVE processes, etc).
- willvarfar 9y agoEh hmm OpenSSL is infamously bad at security? There have been numerous critical bugs, and numerous criticism of its codebase, and numerous rewrites and migrations away from it! This is why the wikipedia page for OpenSSL https://en.wikipedia.org/wiki/OpenSSL https://en.wikipedia.org/wiki/OpenSSL lists notable vulnerabilities and even a list of forks away from it!
- sillysaurus3 9y agoWell, yes. And now those bugs are fixed. Meanwhile, it's one of the most popular security libraries on the planet. The fact that everybody uses it means you're unlikely to be burned by any given vulnerability since every vulnerability impacts a huge number of people. From a security perspective, the worst situation to be in is where you're using some obscure library that has a critical flaw that nobody notices because it's obscure. At that point, a reasonably competent pentester will make your app sing and dance, and you won't know until too late. If you stick with OpenSSL, you leverage the massive investment of resources being poured into it.
- deleted 9y ago[deleted]
- omginternets 9y ago
- simias 9y agoAll of them. But the remaining question is: how many more would've been introduced by rewriting OpenSSL and OpenVPN in a safe language? I think in the long run it's probably a good idea to do it, once things have settled a bit and there's a clear "winner" in the safe language front. In the meantime it'll be hard to beat the ubiquity and compatibility of a C library like OpenSSL. OpenVPN on the other hand, as a standalone application, could probably be rewritten right now in Rust, Go or Malbolge if somebody cared enough to do it.
- yuchi 9y agoI expected to be downvoted («the burden») but before you do please keep in mind I’m honestly trying to understand if those issues were preventable by using a different language. Just a honest curious question.
- pjmlp 9y agoUsing a more safer systems programming language like Modula-2 (1978), would prevent in regards to C: - Out-of-bonds array and string access - Implicit type conversions - Accessing null pointers - Using pointers for output parameters - Casting integers to invalid enumeration values - Incompatible casts between data types - Allocating less memory than actually required In Modula-2 anything that requires C like low level tricks requires the explicit use of the pseudo-module SYSTEM. But I can go further to 1961 and ESPOOL and NEWP, Algol dialects for Burroughs B5500 systems programming, which already supported the use of then known as UNSAFE attributes for such low level coding outside Algol strong typing. Although they would still allow for memory leaks or the error of freeing unallocated memory, but they would panic for the later, instead of the UB in C.
- amelius 9y agoWhat would the performance penalty be?
- pjmlp 9y agoDepends on the compiler. What many younger generation seem to miss is that in the 80's C compilers were pretty lame, most junior Assembly programmers could easily out perform them. The current state of C compiler performance is the outcome of almost 40 years of research in compiler optimizations for C, not anything of the language itself. Also for those that prefer "Performance trumps correctness" way of thinking, some compilers offered ways to disable those checks. But for anyone that thinks "Performance trumps correctness" is worthwhile, I advise to read C.A.R Hoare Turing award speech about the responsibility of software engineers, Algol use by the industry and law, done in 1981.
- verytrivial 9y ago.. Or in a language designed for proof of correctness? See e.g. https://mitls.org/ https://mitls.org/ -- I think this is very important work. Imagine only dealing with bugs in the spec? Maybe one day, when all the hearts are finally bled, something like this will become the default unless and until you have a proven^1 unmet performance requirement, and only then after you've spoken to your lawyers. 1. Pun intended.
- ProxCoques 9y agoSo I just installed ovpn on my phone just now. First place I go to test it is HN. And this story is literally top of the list. Sigh.
- jagermo 9y agoSomeone else trying out Protonvpn, I see :)
- Kurtz79 9y agoYou don't need necessarily to be using a specific service. You can configure your own OpenVPN server quite easily, and use the available vanilla client applications to connect to it.
- ccrush 9y agoThe fun part is that a somewhat premium (read: more bandwidth) VPN option will cost around the same as a lower tier VPS. So, if you're willing to put up with the 10-15 commands, editing a couple configuration files, and copying config and cert files over, you can get your own VPN and a Linux server to use.
- Spivak 9y agoRight, but for certain classes of users, VPN as a service offers anonymity and endpoints around the world.
- afghanPower 9y agoYup. Most VPNs with decent bandwith cost $4/month. You can get pretty much the same service for $4/year if you buy a cheap NAT VPS server and spend 10 minutes setting up openvpn.
- whoami_nr 9y agoCould you point me towards a $4/Year VPS ? Would gladly buy it.
- akavel 9y agoI don't understand why comment out ASSERTs; wouldn't they actually potentially protect against some of the listed issues? The article mentions they interfere with libFuzzer; but isn't a fuzzer expected to detect and handle crashes as part of its core functionality?
- yaantc 9y agoYou have two kinds of fuzzers: 1) out of process, like AFL: The application is launched for each test, and there's no problem handling a crash, whatever the cause (asserts are ok). But for each test there's the application start-up (process creation, etc.) overhead. 2) in process, like libFuzzer: The application is launched once only. Then inside the application context the library iterates over the tests. So no application start-up overhead (nice), but a brutal exit is a problem. That's where asserts becomes a problem. I guess that's what's at play here.
- Franciscouzo 9y ago> But for each test there's the application start-up (process creation, etc.) overhead. That's not completely true, for AFL you have __AFL_INIT(), which defers the initialization of AFL until after an expensive initialization of the program to be fuzzed, which greatly improves performance.
- Ded7xSEoPKYNsDd 9y agoWhy not change asserts (they are macros after all) to tell the fuzzing library that it found an error? Finding bugs is the whole point of the exercise, isn't it?
- yaantc 9y agoFrom a quick look at the doc (http://llvm.org/docs/LibFuzzer.html http://llvm.org/docs/LibFuzzer.html) this doesn't seem to be supported. Aborting from an assert deep in the code has some challenges: unwinding the stack is ok, but how one would avoid memory leaks for heap data? It would require trapping all mallocs to track all allocated data and free it. Not impossible but it adds very significant complexity, and that doesn't seem the philosophy of libFuzzer. It seems to me that the goal of libFuzzer is to be very easy to use (just define one function for test harness, compile with CLANG and fuzzying flag, done) and efficient on an already reasonably well behaved library. It makes sense to me: just start with AFL, which has no problems with crashes. When you reach AFL limits and need more efficiency, only then move to libFuzzer (both can shared state / test framework). Then the assumption that the app. is reasonably well behaved makes sense. Caveat: I haven't used libFuzzer yet. For the reason above, I'm just using AFL for now. Maybe one day but I'm not there yet ;)
- simias 9y agoVulnerability #2 is a good example of why OpenSSL is a minefield even for a competent coder. For such a security-critical library it's pretty insane that the API is so unfriendly, bordering on hostile. > The correct way to do this is to call GENERAL_NAMES_free. This is because sk_GENERAL_NAME_free frees only the containing structure, whereas GENERAL_NAMES_free frees the structure AND its items. And later: > Here, the code assumes that a return value that is negative or zero indicates failure, and ‘buf’ is not initialized, and needs not to be freed. But in fact, this is ONLY the case if ASN1_STRING_to_UTF8 returns a negative value. A return value 0 simply means a string of length 0, but memory is nonetheless allocated, so there are memory leaks here as well. It mirrors my experience working with OpenSSL: you have to quadruple check each function invocation with the docs to make sure you got it right. You're never sure at a glance what's an input or an output parameter, what needs to be freed and how you're supposed to free it. What's the return value in case of error? 0? -1? <0? <=0? And then you have the macro soup with their STACK_OF "abstraction" (in the leakiest sense of the word) that just serves to make the code harder to reason about and is a huge pain when you want to create OpenSSL bindings for an other language. Let me be clear: I don't blame the OpenSSL devs in any way. It's free, it's open source, they don't get a ton of money for that. Instead I blame all the big corporations who use OpenSSL "as-is", directly or indirectly, and don't invest some money to improve that mess. Maybe after a couple more Heartbleed-like vulnerabilities they'll take it a little more seriously.
- mikeash 9y ago"The correct way to do this is to call GENERAL_NAMES_free. This is because sk_GENERAL_NAME_free frees only the containing structure, whereas GENERAL_NAMES_free frees the structure AND its items." Holy moly. It took me about five attempts just to spot the difference in the two names. Can it even be fixed at this point, or does it need to start fresh?
- dcousens 9y agoThis mirrored my confusion when `AES_cbc_encrypt` modified my IV data when _decrypting_.
- andy_ppp 9y ago> You're never sure at a glance what's an input or an output parameter, what needs to be freed and how you're supposed to free it. Terrifying; would a more functional style of programming help here?
- deleted 9y ago[deleted]
- shmerl 9y agoA lot of such stuff can be avoided by simply using Rust.
- rsync 9y agoOpenVPN is very complicated and for that reason I use sshuttle[1] which is very simple. It does require that you own an sshd running on an endpoint somewhere (like a VPS or an EC2 instance or your own server somewhere) - but if you can clear that hurdle, you end up with a very elegant and simple solution. [1] https://github.com/sshuttle/sshuttle https://github.com/sshuttle/sshuttle
- westbywest 9y agotinc is also a popular lightweight VPN, although it's targeted for embedded. It does nevertheless support the libreSSL fork mentioned upthread. https://www.tinc-vpn.org/ https://www.tinc-vpn.org/
- sr2 9y ago+1 for tinc
- sigjuice 9y agoThe first line on the sshuttle GitHub page says 'does not require admin'. Why even have installation instructions via 'sudo' then?
- ckuehl 9y agoA benefit of installing using your system package manager is that you can rely on your distro to manage the security of the package. If you just `pip install` it, you need to personally watch for new security bugs and upgrade (or backport them to your current version, which is what e.g. Debian will do for you). You'd also need to do that for all of the dependencies. Up to you if you trust your distro's security team, of course :). I trust mine.
- sigjuice 9y agoI did not say anything about package managers. I trust my distro and its suppplied packages just like you trust yours and aim to use official packages as much as I can. The instructions in README.md say "sudo pip install" and "sudo ./setup.py". To me, that is a bad idea. Things that are manually installed should be kept in completely separate directories. My preference is to install such packages in my home directory, which should in no way require sudo.
- chrisper 9y agoI was thinking of switching to L2TP instead. Would there be any downsides? I tried out this script once and it worked well: https://github.com/hwdsl2/setup-ipsec-vpn https://github.com/hwdsl2/setup-ipsec-vpn
- JustSomeNobody 9y agoI would be interested to hear this as well. I favor L2TP/IPsec as it's built into iOS and MacOS and it was easy to configure my edgerouter-x to be a server for use on the go.
- UnoriginalGuy 9y agoL2TP doesn't traverse NATs and other network firewalls very well. Which isn't relevant if you yourself control all of the hardware between endpoints (e.g. point2point) but if you plan on using it on public networks (e.g. Starbucks WiFi) then expect to run into it being blocked sometimes. OpenVPN was designed for the "Starbucks WiFi" scenario, it can traverse a NAT, and uses standard TLS. It therefore appears like any other HTTPS traffic and will be very infrequently blocked. There's nothing inherently wrong with L2TP/IPSec; it is secure and fast. Just nicer to blend in with other TLS traffic for reliability reasons. For a specific example, GoGo Internet (in-flight WiFi), doesn't allow L2TP/IPsec unless you use UDP encapsulation. OpenVPN works out of the box.
- MichaelGG 9y agoWhere does this idea that OpenVPN is TLS come from? No, it does not appear like HTTPS nor does it use TLS for the traffic. OpenVPN has its completely own encapsulation protocol, and it stuffs a few TLS packets inside that to do key exchange, nothing more. (And it's key exchange is odd as they re-implement TLS PRF ... on top of TLS.) t. Recently implemented an OpenVPN client.
- okasaki 9y agoThe man page says it supports TLS
- dperfect 9y agoSince it's not clear from the blog post or the other HN comments: the vulnerabilities are fixed in OpenVPN 2.4.3 and 2.3.17. OpenVPN users are advised to upgrade[1] "as soon as possible." [1] https://openvpn.net/index.php/open-source/downloads.html https://openvpn.net/index.php/open-source/downloads.html
- microcolonel 9y agoMan, I'm eager for WireGuard to hit 1.0. It's very elegant, and I could build a policy layer on it in a couple days which doesn't suck.
- pferde 9y agoIndeed, wireguard looks like it's going to be the bee's knees. It still has a lot of development ahead of it, though.
- microcolonel 9y agoShouldn't take too long, though. It's still about 10kSLoC and it's been more/less feature frozen for over a year. I get the feeling that it's already probably safer than most deployed VPN systems. Most of the recent work seems to be forward porting, reworking the ratelimiter, and tweaks to the treatment of randomness.
- zx2c4 9y agoIf by 10kLoC you actually mean less than 4kLoC, then I agree with you. :)
- microcolonel 9y agoThere's more than 10k lines of C in the repository, 8200 lines of assembly, and almost three thousand lines of headers. Your kernel module is definitely smaller than the whole repo. I feel like I've just called you fat. ;- )
- LeonM 9y agoIt's good to see that 2 donations, totaling 0.80260293 BTC (~2000 euro) are made to Guido's wallet [0]. Probably not worth his time, but since he states it was "a labor of love" it's still a nice extra! Edit: corrected BTC amount. [0] https://blockchain.info/address/1D5vYkiLwRptKP1LCnt4V1TPUgk7cxvVtg https://blockchain.info/address/1D5vYkiLwRptKP1LCnt4V1TPUgk7...
- bitxbitxbitcoin 9y agoPrivate Internet Access VPN provided $1,000 of that and thanks OP profusely [0]. [0] https://www.privateinternetaccess.com/forum/discussion/24191/private-internet-access-is-not-affected-by-recently-discovered-openvpn-security-vulnerabilities#latest https://www.privateinternetaccess.com/forum/discussion/24191...