Hacker News new | past | comments | ask | show | jobs | submit login

I would find this argument more compelling if it were supported by examples. Although it’s easy to imagine this sort of dynamic unfolding, offhand I can’t think of any good examples of it happening with internet protocols in quite this way.

On the other hand, I can immediately think of an example to the contrary: I would at least partly attribute the failure of XHTML to the fact that conforming renderers were forbidden to be liberal in what they accept, and viewers of XHTML pages would often be faced with an error message in place of the page they wanted to see, as a consequence of some minor mistake.




HTML is a great example in my opinion. XHTML failed because it was trying to close the barn door after the horse had bolted a decade ago.

XHTML was a reaction to an existing issue: that HTML is absolutely hellish to parse to the point that in the 90s half the web officially endorsed either IE or Netscape to be used for that particular website. Not to speak of anyone actually trying to do something clever with the contents of web pages.

Had XHTML worked it'd have been a huge quality of life improvement. The problem was that it was too late and that it was introduced into an ecosystem not prepared for it because everyone had long built on the assumption that you can just haphazardly generate chunks of HTML and insert them into the middle of other chunks of HTML.

Also, XHTML's error messages would probably be appreciated more today. Today we appreciate that allowing an HN poster to just drop random tags into a post is a terrible idea, so the fact that if on XHTML an user just leaves an unclosed tag the entire page fails to render, it's a good thing. It's a sign that you're doing handling of user data terribly wrong and it needs fixing post-haste. But back when XHTML showed up security was such an afterthought that barely anyone cared, and they just wanted things to work, dammit.

In the end we solved it first by a bigger push on standardization because people finally got sick of it, and later by Chrome just eating the browser market.


XHTML failed for exactly one reason – Internet Explorer, with overwhelming market share, did not support it. If you served it as text/html then it would parse it, but not apply any of the XHTML parsing rules, it would just treat it as weird HTML.

The history of the web is littered with copious examples of what the article talks about. Here’s one example: HTTP has a Content-Type header that indicates the media type being transferred. Sometimes, web developers would screw up and serve things with the wrong media type. For instance, serving CSS files as text/plain instead of text/css.

Now, if no action were taken by browser vendors, the resolution would be simple: the developer would see that the styling on their site was completely broken, and fix it. But Internet Explorer decided to be “liberal in what it accepted”, and instead of respecting the Content-Type header, they used content sniffing to guess. This meant that when a web developer screwed up, and they only tested on the 90%+ market share Internet Explorer, they would think everything was fine but it would be broken in every browser but Internet Explorer.

After a while, so many sites were broken in Firefox that Firefox had to follow the non-standard behaviour as well. Leaving other minority browsers broken. At this point, the behaviour a browser needs to implement to render a website successfully is not what is written in the specifications, but copying unpredictable guessing from proprietary code. You can see how that’s harmful to interoperability, right? Even though interoperability is the entire purpose of Postel’s Law?

It gets worse though, because this content sniffing was happening all over, not just to CSS. So if a website said that something was a PNG image, if that image’s metadata contained the wrong sequence of bytes, it would get interpreted as an HTML document. This is important because PNGs don’t contain any kind of scripting, while HTML documents do.

So this opened up an attack vector: make a polyglot file that contains malicious JavaScript, and upload it as an image to a website. Then link to that image, and Internet Explorer users will execute the JavaScript in the security context of that website, resulting in a successful XSS attack. Even though the website served it as an image, not HTML, Internet Explorer would “be liberal” and do its best to interpret it as badly-broken HTML.

At some point, Internet Explorer came up with an authoritative: true parameter that opted out of this behaviour. Sometimes. Then they tried again with X-Content-Type-Options: nosniff. Meanwhile, web developers who just wanted to serve user-provided images without opening themselves up to attack vectors needed to follow all these twists and turns instead of just reading the spec. Ever wonder why opening an image URL on so many sites triggers a download? It’s because for many years it was the only safe way to avoid an image being interpreted as HTML.

This has happened over and over and over and over again on the web. Did you know that Netscape Navigator would interpret Unicode characters that merely look like angle brackets as if they were actually angle brackets? Consider the impact on security that one had. Remember the “samy is my hero” MySpace worm? That was down to browsers “helpfully” ignoring newlines in the javascript pseudo-protocol.

Postel’s law has been downright poisonous for security and interoperability. We would all be much better off with strict parsers.


> Now, if no action were taken by browser vendors, the resolution would be simple: the developer would see that the styling on their site was completely broken, and fix it

This assumes the developer sees the output. I remember having a dozen browser builds in the 90s and still getting error reports from users with stuff I never heard of. And back then we didn’t have VMs so I had to keep a bunch of pcs, Macs, etc to test things out.

I think the reason browsers were so lax/supportive is that there were many browsers, servers, etc.

It would be so easy if you could just dev and test your site. But that didn’t work and in fact was kind of a bad approach as you ended up with really tightly wound to a single browser and “works for me” mentality that made users with different configs not use your site, or for intranet made people hate the author for forcing a config and devving in a dumb way (looking at you person who still makes me run ie11 to submit “telework agreements” at my org, you never should have built this to work with ie11 so many years ago).

It seemed like successful sites had to triangulate what the de facto standards are and code in a way that made testing really tough.


> This assumes the developer sees the output.

That’s why doing the opposite of Postel’s Law is so effective. If your protocol or file format mandates fatal errors instead of being lenient in what you accept, you surface the error immediately during development and stop it from getting into production.

How many HTML or CSS parse errors do you think make it into production?

How many Python, Ruby, Java, Go, or PHP parse errors do you think make it into production?

> It seemed like successful sites had to triangulate what the de facto standards are and code in a way that made testing really tough.

Yes, and this is the consequence of Postel’s Law that the article is arguing against.


Surfacing the error immediately means customers not buying your stuff. Or people not seeing your site.

Personally, I’d rather have some functionality than none.

When you have a really diverse audience with high stakes, being accommodating is valuable. When I have control over the pipeline then I can afford to be strict in surfacing and correcting errors. But when I have 10,000 different users who will not report errors and just move on, I need something else.


> Surfacing the error immediately means customers not buying your stuff. Or people not seeing your site.

No, immediately means when the code is written, not some arbitrary time later in production.

When somebody writes Python, Ruby, Java, Go, or PHP with a parse error, the developer notices immediately because the runtime is conservative in what it accepts and refuses to run it. Fixing the error is mandatory before the code can make it into production where it can affect your customers and make them not buy stuff.

When somebody writes HTML or CSS with a parse error, that can easily make it into production because nothing between the point where the mistake is made and production will refuse to parse it, everything in the chain is lenient in what they accept and pass it along to where your customers can be affected.


Isn’t the point of a protocol is that anyone can write a parser and browser? How would I test immediately in every browser, since there’s so many different things parsing and interpreting and rendering?


The whole point of what we are discussing is to define the protocol to require unambiguous errors instead of lax undefined behaviour. If every parser rejects errors instead of trying to work around them in their own special way, errors are surfaced in the first browser you test with because it won’t be trying to compensate for the error in ways you might not be aware of.


For the best case example design your code with the goal of failure and properly describing failure states for the users benefit. The success state should be a narrow exception provided the input is formatted exactly as the specification describes.

This greatly lowers the acceptance criteria to test for and instead forces a greater focus on negative tests and error conditions.


As someone who has dealt with a lot of syslog over the years... There are RFCs which specify the overall structure and the correct timestamp format, but many tools (open and closed source alike) follow the following "standard" instead:

"Just print a timestamp in some format, then maybe the hostname if you feel like it, and then your message"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: