If is Evil when used in location context (2015)
nginx.com
nginx.com
In general, if the users consistently make the same mistakes when using your software, then it's your (the software developer's) mistake, not the users. No amount of documentation will make up for poor design.
In the case of NGINX's "if", it goes contrary to people's mental model of how "if" should work.
Another failure in NGINX is the way array directives inherit from higher contexts (search for "array directive" in [1]). If you have add_header directives at one context and then lower contexts (i.e. location) will inherit all the add_header directives UNLESS another add_header directive is in the lower context. In that case, NONE of the previous add_header directives are inherited. This is completely contrary to the directive name "add_header" which implies adding a header, not wiping out all previous headers.
[1] https://blog.martinfjordvald.com/understanding-the-nginx-con...
If you actually do try and make use of the apparent flexibility of the syntax, you very quickly start to run into situations where you inexplicably just "can't do that", with the failure mode frequently just being nginx quietly not doing the right thing.
A single misconfiguration can be a major security issue.
Is it just me or does it seem insane that they just casually mention a segfault being a known possible outcome for normal user input? I would think that any kind of segfault should be considered a severe bug that needs immediate attention. Am I missing something here?
One of the last paragraphs is illuminating as to why `if` is so weird in NGINX:
> Directive “if” is part of rewrite module which evaluates instructions imperatively. On the other hand, NGINX configuration in general is declarative. At some point due to users demand an attempt was made to enable some non-rewrite directives inside “if”, and this lead to situation we have now. It mostly works, but… see above.
Worse yet. I recall Apache segfaulting inconsistently on different machines. Very specifically segfaulting inside of MY modperl code in a way that logically should have been impossible, but ONLY in production. And not, say, in staging where I could have debugged it.
I forget what the configuration error was. (This happened in 2009.) But I very painfully remember it taking over a month before anyone tracked it down. And when I tracked it down, it was because I was reading documentation for some other reason. I noticed the configuration mentioning that segfaults were possible if you did something, so I looked, and we did.
I was...not exactly happy.
C definitely considers a segfault as the intended result of bad user input. Perl actually has the dump function to create a segfault. Lots of configurations for lots of things have, "This gives you speed+flexibility but is unsafe."
In all of these cases, the intended result of bad user input is a segfault. It just comes with the territory. For example nginx allows third party modules to be loaded. There is no way to avoid the fact that some third party modules will dump core. Should nginx therefore stop allowing third party modules? How is that fundamentally different?
Plugins are software, and all software can crash because validation is not just practically but even theoretically impossible for a Turing-complete language. But the fundamental difference is not in whether a crash can occur or not, but in your attitude to the crash: is it a software bug and hence should be fixed, or is it expected behavior and left as is? IMO the former attitude is almost always the correct one if the end user is anybody other than yourself.
There may be performance concerns that make it worthwhile to accept a crash (and that's the reason we run plugins as in-process native code instead of in a separate process or VM) but in the case of nginx I strongly doubt performance would be affected noticeably by validation of config files.
I think it's reflective of Rust vs C design philosophy.
https://news.ycombinator.com/newsguidelines.html
> Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize.
[0] "If is Evil when used in location context"
Coupled with the nginx.com domain, I know exactly what the page is and why it’s linked here.
What, are you a time traveler from 2009? Since when does iOS not allow you to copy text on a webpage?