"[...] we will begin to also require disclosure of intermediate certificates that are capable of issuing websites (TLS/SSL) or email (S/MIME) certificates even when they are technically constrained."
tl;dr all interCAs have to be reported (right? or am I missing something?)
I haven’t researched this fully yet, but I believe that this is a nuance of x509 and certificate purposes.
If the intermediate is granted the permission “issue website/email cert” at the lowest x509 level, then it apparently (TIL) used to be possible to layer in higher-level constraints in order to disable that so as not to disclose it — but when these rules take effect, that kind of exception will no longer be accepted, since intermediates that won’t be issuing web/email certificates shouldn’t be issued with x509 properties that say “I can issue web/email certificates” anyways.
Previously, Mozilla's requirement to be informed of intermediate CAs explicitly did not include "technically constrained" CAs.
"Technically constrained" refers to properties of the signed CA certificate which would cause a correct PKIX implementation to either reject the certificate (because they know they don't understand something important about it) or obey some restriction when trusting it, a constraint on how it can be used.
In particular constraints are used to say things like "This intermediate must only issue for names ending in .famous.example" or "This intermediate may not issue for names ending in .different.example".
In practice we also use the X.509 Extended Key Usage fields of CA certificates as constraints, even though probably we shouldn't that's settled practice and can't realistically be fixed now. So, if the intermediate's certificate has an EKU saying its key has "Any Use" the interpretation today is that it can be used to sign other certificates with any use.
After the policy change, most intermediate CAs will need to be disclosed. But, an intermediate that can't be used to issue working certificates in the Web PKI or for S/MIME could still exist under these rules. For example if you have ended up with some legacy system that needs a CA primarily used in the Web PKI but you're doing SpecialThing with it, in principle a subCA under that CA constrained by an EKU saying only SpecialThing usage is allowed, would still not need to be disclosed since it can't cause harm: A "real" SpecialThing certificate isn't a TLS certificate, and bad guys who subvert the SpecialThing intermediate can't issue working TLS certificates either.
Mozilla primarily cares about Firefox users, so, they don't need to care that in theory your badly designed TLS client might not check EKUs, Firefox does.
As part of this effort, Mozilla requires disclosure of all intermediate CA certificates in the WebPKI. They bundle that list in Firefox, so that even if a server is misconfigured and sends the wrong certificate chain (but a valid leaf certificate), they can successfully establish a TLS connection. It's pretty cool, and less confusing than the caching approach of other browsers, which leads to non-deterministic behavior.
Using the list they publish [1] I built a Go package that provides the same feature, as both a x509.CertPool or a tls.VerifyConnection callback, to allow clients to connect to misconfigured servers: https://pkg.go.dev/filippo.io/intermediates
The pool is regenerated [2] by a GitHub Action [3] every night, and embedded into the package so it requires no network connection. If tests fail on the new pool, it doesn't get committed. It's actually kinda interesting watching the intermediates come and go [4], and it's very satisfying to have a self-maintaining package.
I would have liked the world where AIA chasing happened in servers.
Today several browsers which don't have Mozilla's list of intermediates instead (if they don't have a satisfactory chain offered to them) do AIA chasing, meaning that the browser consults the Authority Information Access fields in the X.509 certificate, finds a URL in there and fetches that URL hoping to get a certificate it trusts, often it iterates several times before giving up or reaching a dead end. AIA chasing in browsers is a (small) privacy risk and a (non-trivial) performance cost, plus it can just fail if you don't have as much Internet access, perhaps because you need to talk to a server, whose certificate you are trying to validate, before getting access; or of course it can just fail because temporarily some server is down somewhere.
If server software did AIA chasing (e.g. nginx, or your SMTP server) it would see during startup that you configured a bare certificate, and do the same AIA chasing that browsers do today but only once for the lifetime of the service and with the privilege of being a server (likely better Internet access, and more likely somebody technical sees the error output if there are problems) and it could have retry/fallback behaviour and if it doesn't work well the server can tell its administrator to fix the problem, whereas the browser doesn't have a way to contact that admin.
But Mozilla's choice here was pragmatic. We get the world we deserve.
Your suggestion would definitely be more efficient. I’d split the difference and just say the server could just abort startup if it can’t validate its own cert. Letting servers indiscriminately connect to the internet isn’t great security practice, something that was substantially reinforced with the recent log4j issue.
What I propose (AIA chasing in servers) can be dropped into existing servers and it won't make anything worse, in most cases it will make things better.
What you propose either can't be dropped in (so it's an interesting experiment for a new web server, are you writing one? No? Then it's of no value) or if it's dropped in it breaks working systems, making you a nuisance.
If you have a time machine so you can go back to the mid-1990s and ensure all web servers work your way your idea is better or at least good. But you don't have a time machine, we must work with what exists today.
> even if a server is misconfigured and sends the wrong certificate chain (but a valid leaf certificate), they can successfully establish a TLS connection. It's pretty cool
I don’t really get why we want this. What is wrong with insisting that servers have their cert chains configured properly? This feels like one of those early web problems caused by implementations being too permissive with invalid input. Set your server up properly (it isn’t hard) and your TLS will work.
Mozilla's decision avoids tumbling all the way down the slope in a must-win race to the bottom to reduce user pushback for mis-configured sites.
Previously the situation was many sites seem to work fine in (for example) Edge, but don't work all the time in Firefox. What do you do if you're the average user? Do you track down every site owner whose site malfunctions, drive over and insist they fix it? No. You delete Firefox and switch to Edge.
Nothing is "wrong" with your perfect world outcome, Mozilla's change doesn't prevent it - it just won't happen anyway.
I hear you, but I also am encouraged that, for example, in 2017-ish, Chrome was able to turn on enforcement of deprecating CommonName in favor of SAN for single-name serverauth certs. They flipped a switch and a lot of sites broke, then fixed themselves. There was no mass exodus. You could argue that this was because of Chrome's dominance and I'd agree to an extent, but I like the fact that the solution was not just "have browsers pretend this is ok." And that was for a change that really did not matter from a security standpoint, it was just catching up to an RFC change.
> They flipped a switch and a lot of sites broke, then fixed themselves.
No. This isn't a thing that happened.
Certificates which lack SANs matching a DNS name claimed as Common Name had been non-compliant since PKIX last century. So in the subsequent decade plus the big problem was identifying CAs which were flouting these rules and then getting them to understand what they'd done wrong and stop doing it. That's something which CA/B (the CA/B BRs forbade this from the outset) and m.d.s.policy were getting good traction on by 2013 or so, but Certificate Transparency (initially seeded by Google's "Googlebot" robots before the Chrome mandate) represents a sea change beyond that because now finding non-compliant certificates was a trivial SQL query. And that took such non-compliant certificates from "rare but you will find them if you look hard" to "extinct" very quickly indeed.
Even when there were still a few technically non-compliant certificates out there, they wouldn't break Chrome, the usual non-compliance went like this:
Say you own a site with an IDN https://xn--d1abbgf6aiiy.xn--p1ai/ and so the DNS entry for that is xn--d1abbgf6aiiy.xn--p1ai - your SAN DnsName will say xn--d1abbgf6aiiy.xn--p1ai because that's how SANs work, but you persuade the issuing CA to write президент.рф in the Common Name instead of xn--d1abbgf6aiiy.xn--p1ai because it looks nicer.
[ NB Hacker News won't show the IDN to most (any?) of you but imagine you're a Russian and your web browser shows this URL in Cyrillic not as Punycode ]
This is non-compliant with PKIX, because this Common Name doesn't match any of the SANs. It can't because it's Unicode and none of the SANs can express Unicode [IpAddress SANs are numbers, and DnsName SANs are restricted to a simple alphabet suitable for writing names of hosts in DNS]. But it doesn't cause any problems for Chrome because the SANs match the real DNS names of the server, the Common Name is just decorative garbage that doesn't match anything.
Oh, I beg to differ. I saw many examples of this for certs my company had issued from a digicert private CA. Maybe this didn’t happen with certs from public web pki but I can assure you it did for private certs, for which browser support is still an important issue.
But I’ll admit this is moving the goalposts on you and your point is made. I still would prefer the more hard-ass approach but the reality is that consumer products are going to prefer ease of use over correctness, so what are you going to do.
> They bundle that list in Firefox, so that even if a server is misconfigured and sends the wrong certificate chain (but a valid leaf certificate), they can successfully establish a TLS connection. It's pretty cool, and less confusing than the caching approach of other browsers, which leads to non-deterministic behavior.
This seems like it could lead to even more confusion... now the site works on Mozilla but not other browsers. If the person setting up the server happens to use Mozilla to test, they won't realize they misconfigured it. Meanwhile, everyone using different browsers if failing to load their site.
I would prefer a loud failure than a semi-failure.
The last time I reported a Letsencrypt CA misconfiguration to a major open source software ops team that was resulting in SSL errors in some of their clients, they decided they knew better than I did how to operate TLS on the web and refused my report about sending the wrong intermediate, because they were expert users.
As far as I know, they’re still inaccessible to this day in any browser that doesn’t do what Firefox does, that’s running on any slightly older unpatched OS, and they still think it’s everyone else’s fault that they’re receiving errors.
SSL is too complex to successfully validate all possible errors locally over time without reports of semi-failures, and human superiority at dismissing semi-failures as non-issues remains unchallenged. So while I appreciate the spirit of the argument, I don’t think it works out that way in practice, and I can’t really find fault with the Firefox team for deciding (TIL) to ship a better intermediate navigator for doing so. The alternative is directing user complaints to often-uncaring operators.
> This seems like it could lead to even more confusion...
They say making predictions about the future is difficult, but you're predicting something about the past. Where was the "even more confusion" in the long period where Mozilla shipped this feature?
In this world, Mozilla's Firefox browser has to cope with the stupid but true fact that millions of servers are mis-configured, and being "loud" about that just ensures users will switch to a different browser.
> being "loud" about that just ensures users will switch to a different browser.
Do other browsers already have this feature? If not, I am not sure why someone would switch to another browser when they would have the same issue with that one.
Browsers have a variety of strategies to determine whether what they're shown is trustworthy. Two of the most common are:
AIA Chasing. The browser examines the AIA section of the certificate it has been shown, and discovers a URL for another certificate, it fetches this URL, and parses the X.509 certificate it received, this may be enough to establish trust, but otherwise the browser might iterate, examining AIA again, fetching, and so on perhaps for some finite number of attempts before giving up.
Intermediate caches. The browser remembers any CA certificates it saw recently, regardless of context, and it tries those when the chain presented is inadequate to see if they can "fill the gap" to a trusted root. For example maybe you visit Hacker News, it has a DigiCert intermediate, your browser remembers that, then you visit Jim's Trout Forum, Jim forgot to provide a full chain, but his is also a DigiCert certificate, the browser can see this is the missing piece.
Both these strategies have problems, and this is why Mozilla moved from a cache strategy to carrying the entire set of intermediates. If you choose no strategy, you won't be able to reach maybe 10% of web sites securely because they don't offer you enough information to trust their certificate. Feel free to make it your life's mission to yell at all the site owners.
> The pool is regenerated [2] by a GitHub Action [3] every night, and embedded into the package so it requires no network connection.
Once someone pulls the code and compiles it into a binary, how does the list of certs get updated? Do you have have a tzcode and tzdata split à la the IANA/Olson timezone database?
Does anyone in here know what the fundamental driver for this is? Is there a specific risk being addressed or is this just trying to create a more uniform governance model for intermediates? The third party aspect definitely sounds like it’s reacting to something.
BTW the linked mailing list is interesting reading if you’re into this stuff.
Mozilla has invested tons of resources in improving web security, sometimes even when it hurts them.
A good examples is the anti-tracking stuff that break some badly coded (sometimes intentionally!) pages. Users may have left FF for chrome thinking it was not compatible with their favourite sites.
Anyway, if you are a web developer please test your code with FF and anti-tracking enabled (Mozilla has some good documentation on this). If you are a user make sure to contact site owners and complain instead of just going to a less privacy preserving browser.
(Not saying mozilla is perfect, they also try to do some shady stuff sometimes. But right now at least their privacy/security teams are doing some really nice things)
Edit: going back to your original question, yes there have been incidents. And some outright abuse.
Audit isn't automated, it's often done by local "professional services" firms (often from the Big Four) on site and is the least useful tool we have but is better than nothing. However Mozilla's processing of audit documents created by that audit is (somewhat) automated.
Here's an example task we can give to a machine: We want audit letters to be for the correct period of time, and mention all the correct CAs. So, look through the letter and find the dates, and the identifiers for the CAs, and check they match what's expected. If they don't flag for the CA to get us a suitable letter.
This catches the case where the CA sent us the 2019 letter again or a letter doesn't mention all their intermediates. We don't need to care why that happened at this stage, we just want to ensure it can't happen.
Humans are mostly not evil, but they are lazy, incompetent, and sometimes greedy. Automated checking covers those problems pretty well. Auditors are often reluctant to lie for you, but they're usually willing to omit facts you'd prefer weren't mentioned. Audit of AB1235 shows big problems? Just write that audit of AA1234 and AB1234 were fine and omit all mention of AB1235 from the letter. The automated check will pull that up, why isn't AB1235 mentioned?
Thank you for the explanation. So an automated audit isn't really an automated audit, it's a manual audit for which the audit report is checked automatically.
I think the problem is you've parsed the sentence wrong. The phrase Mozilla uses is "Automated Audit Letter Validation" and you've said to yourself, oh, there's an "Automated Audit" and this is validation of letters connected with that. Nope. There are "Audit Letters" - letters reporting the outcome of each audit - and they need to be Validated, now Mozilla has Automated part of that work.
Judging from other reactions I think the vast majority of people parsed this correctly in context, though it's possible I'm wrong. Occasionally poor editing will result in text that most native speakers parse wrongly, these are named "Crash Blossoms" from the naming example headline, "Violinist linked to JAL crash blossoms". A violinist (metaphorically) blossomed, and the headline is explaining which one by telling us it's the one "linked to JAL crash". This bug (statements which have ambiguous parsing) is probably unavoidable in natural languages, although similar bugs in programming languages are arguably a design mistake.
26 comments
[ 2.0 ms ] story [ 63.9 ms ] threadtl;dr all interCAs have to be reported (right? or am I missing something?)
If the intermediate is granted the permission “issue website/email cert” at the lowest x509 level, then it apparently (TIL) used to be possible to layer in higher-level constraints in order to disable that so as not to disclose it — but when these rules take effect, that kind of exception will no longer be accepted, since intermediates that won’t be issuing web/email certificates shouldn’t be issued with x509 properties that say “I can issue web/email certificates” anyways.
"Technically constrained" refers to properties of the signed CA certificate which would cause a correct PKIX implementation to either reject the certificate (because they know they don't understand something important about it) or obey some restriction when trusting it, a constraint on how it can be used.
In particular constraints are used to say things like "This intermediate must only issue for names ending in .famous.example" or "This intermediate may not issue for names ending in .different.example".
In practice we also use the X.509 Extended Key Usage fields of CA certificates as constraints, even though probably we shouldn't that's settled practice and can't realistically be fixed now. So, if the intermediate's certificate has an EKU saying its key has "Any Use" the interpretation today is that it can be used to sign other certificates with any use.
After the policy change, most intermediate CAs will need to be disclosed. But, an intermediate that can't be used to issue working certificates in the Web PKI or for S/MIME could still exist under these rules. For example if you have ended up with some legacy system that needs a CA primarily used in the Web PKI but you're doing SpecialThing with it, in principle a subCA under that CA constrained by an EKU saying only SpecialThing usage is allowed, would still not need to be disclosed since it can't cause harm: A "real" SpecialThing certificate isn't a TLS certificate, and bad guys who subvert the SpecialThing intermediate can't issue working TLS certificates either.
Mozilla primarily cares about Firefox users, so, they don't need to care that in theory your badly designed TLS client might not check EKUs, Firefox does.
Using the list they publish [1] I built a Go package that provides the same feature, as both a x509.CertPool or a tls.VerifyConnection callback, to allow clients to connect to misconfigured servers: https://pkg.go.dev/filippo.io/intermediates
The pool is regenerated [2] by a GitHub Action [3] every night, and embedded into the package so it requires no network connection. If tests fail on the new pool, it doesn't get committed. It's actually kinda interesting watching the intermediates come and go [4], and it's very satisfying to have a self-maintaining package.
[1] https://ccadb-public.secure.force.com/mozilla/MozillaInterme...
[2] https://github.com/FiloSottile/intermediates/blob/7dfa9179/g...
[3] https://github.com/FiloSottile/intermediates/blob/7dfa91796/...
[4] https://github.com/FiloSottile/intermediates/commits/main
Today several browsers which don't have Mozilla's list of intermediates instead (if they don't have a satisfactory chain offered to them) do AIA chasing, meaning that the browser consults the Authority Information Access fields in the X.509 certificate, finds a URL in there and fetches that URL hoping to get a certificate it trusts, often it iterates several times before giving up or reaching a dead end. AIA chasing in browsers is a (small) privacy risk and a (non-trivial) performance cost, plus it can just fail if you don't have as much Internet access, perhaps because you need to talk to a server, whose certificate you are trying to validate, before getting access; or of course it can just fail because temporarily some server is down somewhere.
If server software did AIA chasing (e.g. nginx, or your SMTP server) it would see during startup that you configured a bare certificate, and do the same AIA chasing that browsers do today but only once for the lifetime of the service and with the privilege of being a server (likely better Internet access, and more likely somebody technical sees the error output if there are problems) and it could have retry/fallback behaviour and if it doesn't work well the server can tell its administrator to fix the problem, whereas the browser doesn't have a way to contact that admin.
But Mozilla's choice here was pragmatic. We get the world we deserve.
That means that you have a (silent) dependency that you are absolutely unaware of. When this fails, your service is down.
Far better to have it setup so the service fails if the certificate is not configured with the whole chain.
What you propose either can't be dropped in (so it's an interesting experiment for a new web server, are you writing one? No? Then it's of no value) or if it's dropped in it breaks working systems, making you a nuisance.
If you have a time machine so you can go back to the mid-1990s and ensure all web servers work your way your idea is better or at least good. But you don't have a time machine, we must work with what exists today.
I don’t really get why we want this. What is wrong with insisting that servers have their cert chains configured properly? This feels like one of those early web problems caused by implementations being too permissive with invalid input. Set your server up properly (it isn’t hard) and your TLS will work.
Previously the situation was many sites seem to work fine in (for example) Edge, but don't work all the time in Firefox. What do you do if you're the average user? Do you track down every site owner whose site malfunctions, drive over and insist they fix it? No. You delete Firefox and switch to Edge.
Nothing is "wrong" with your perfect world outcome, Mozilla's change doesn't prevent it - it just won't happen anyway.
No. This isn't a thing that happened.
Certificates which lack SANs matching a DNS name claimed as Common Name had been non-compliant since PKIX last century. So in the subsequent decade plus the big problem was identifying CAs which were flouting these rules and then getting them to understand what they'd done wrong and stop doing it. That's something which CA/B (the CA/B BRs forbade this from the outset) and m.d.s.policy were getting good traction on by 2013 or so, but Certificate Transparency (initially seeded by Google's "Googlebot" robots before the Chrome mandate) represents a sea change beyond that because now finding non-compliant certificates was a trivial SQL query. And that took such non-compliant certificates from "rare but you will find them if you look hard" to "extinct" very quickly indeed.
Even when there were still a few technically non-compliant certificates out there, they wouldn't break Chrome, the usual non-compliance went like this:
Say you own a site with an IDN https://xn--d1abbgf6aiiy.xn--p1ai/ and so the DNS entry for that is xn--d1abbgf6aiiy.xn--p1ai - your SAN DnsName will say xn--d1abbgf6aiiy.xn--p1ai because that's how SANs work, but you persuade the issuing CA to write президент.рф in the Common Name instead of xn--d1abbgf6aiiy.xn--p1ai because it looks nicer.
[ NB Hacker News won't show the IDN to most (any?) of you but imagine you're a Russian and your web browser shows this URL in Cyrillic not as Punycode ]
This is non-compliant with PKIX, because this Common Name doesn't match any of the SANs. It can't because it's Unicode and none of the SANs can express Unicode [IpAddress SANs are numbers, and DnsName SANs are restricted to a simple alphabet suitable for writing names of hosts in DNS]. But it doesn't cause any problems for Chrome because the SANs match the real DNS names of the server, the Common Name is just decorative garbage that doesn't match anything.
Oh, I beg to differ. I saw many examples of this for certs my company had issued from a digicert private CA. Maybe this didn’t happen with certs from public web pki but I can assure you it did for private certs, for which browser support is still an important issue.
But I’ll admit this is moving the goalposts on you and your point is made. I still would prefer the more hard-ass approach but the reality is that consumer products are going to prefer ease of use over correctness, so what are you going to do.
This seems like it could lead to even more confusion... now the site works on Mozilla but not other browsers. If the person setting up the server happens to use Mozilla to test, they won't realize they misconfigured it. Meanwhile, everyone using different browsers if failing to load their site.
I would prefer a loud failure than a semi-failure.
As far as I know, they’re still inaccessible to this day in any browser that doesn’t do what Firefox does, that’s running on any slightly older unpatched OS, and they still think it’s everyone else’s fault that they’re receiving errors.
SSL is too complex to successfully validate all possible errors locally over time without reports of semi-failures, and human superiority at dismissing semi-failures as non-issues remains unchallenged. So while I appreciate the spirit of the argument, I don’t think it works out that way in practice, and I can’t really find fault with the Firefox team for deciding (TIL) to ship a better intermediate navigator for doing so. The alternative is directing user complaints to often-uncaring operators.
They say making predictions about the future is difficult, but you're predicting something about the past. Where was the "even more confusion" in the long period where Mozilla shipped this feature?
In this world, Mozilla's Firefox browser has to cope with the stupid but true fact that millions of servers are mis-configured, and being "loud" about that just ensures users will switch to a different browser.
Do other browsers already have this feature? If not, I am not sure why someone would switch to another browser when they would have the same issue with that one.
AIA Chasing. The browser examines the AIA section of the certificate it has been shown, and discovers a URL for another certificate, it fetches this URL, and parses the X.509 certificate it received, this may be enough to establish trust, but otherwise the browser might iterate, examining AIA again, fetching, and so on perhaps for some finite number of attempts before giving up.
Intermediate caches. The browser remembers any CA certificates it saw recently, regardless of context, and it tries those when the chain presented is inadequate to see if they can "fill the gap" to a trusted root. For example maybe you visit Hacker News, it has a DigiCert intermediate, your browser remembers that, then you visit Jim's Trout Forum, Jim forgot to provide a full chain, but his is also a DigiCert certificate, the browser can see this is the missing piece.
Both these strategies have problems, and this is why Mozilla moved from a cache strategy to carrying the entire set of intermediates. If you choose no strategy, you won't be able to reach maybe 10% of web sites securely because they don't offer you enough information to trust their certificate. Feel free to make it your life's mission to yell at all the site owners.
Once someone pulls the code and compiles it into a binary, how does the list of certs get updated? Do you have have a tzcode and tzdata split à la the IANA/Olson timezone database?
BTW the linked mailing list is interesting reading if you’re into this stuff.
A good examples is the anti-tracking stuff that break some badly coded (sometimes intentionally!) pages. Users may have left FF for chrome thinking it was not compatible with their favourite sites.
Anyway, if you are a web developer please test your code with FF and anti-tracking enabled (Mozilla has some good documentation on this). If you are a user make sure to contact site owners and complain instead of just going to a less privacy preserving browser.
(Not saying mozilla is perfect, they also try to do some shady stuff sometimes. But right now at least their privacy/security teams are doing some really nice things)
Edit: going back to your original question, yes there have been incidents. And some outright abuse.
Here's an example task we can give to a machine: We want audit letters to be for the correct period of time, and mention all the correct CAs. So, look through the letter and find the dates, and the identifiers for the CAs, and check they match what's expected. If they don't flag for the CA to get us a suitable letter.
This catches the case where the CA sent us the 2019 letter again or a letter doesn't mention all their intermediates. We don't need to care why that happened at this stage, we just want to ensure it can't happen.
Humans are mostly not evil, but they are lazy, incompetent, and sometimes greedy. Automated checking covers those problems pretty well. Auditors are often reluctant to lie for you, but they're usually willing to omit facts you'd prefer weren't mentioned. Audit of AB1235 shows big problems? Just write that audit of AA1234 and AB1234 were fine and omit all mention of AB1235 from the letter. The automated check will pull that up, why isn't AB1235 mentioned?
Judging from other reactions I think the vast majority of people parsed this correctly in context, though it's possible I'm wrong. Occasionally poor editing will result in text that most native speakers parse wrongly, these are named "Crash Blossoms" from the naming example headline, "Violinist linked to JAL crash blossoms". A violinist (metaphorically) blossomed, and the headline is explaining which one by telling us it's the one "linked to JAL crash". This bug (statements which have ambiguous parsing) is probably unavoidable in natural languages, although similar bugs in programming languages are arguably a design mistake.