6 ms·
Can we please stop trying to enumerate badness[1]? When parsing input it is possible to define the set of valid input, not all possible invalid inputs. Also, a
by pdkl95 10y ago
Can we please stop trying to enumerate badness[1]? When parsing input it is possible to define the set of valid input, not all possible invalid inputs.
Also, anybody accepting input from an untrusted source (such as anything from a network or the user) that isn't verifying the data with a formal recognizer is doing it wrong[2]. Instead of writing another weird machine, guarantee that the input is valid with a parser generator (or whatever) recognize the input and drop anything even slightly invalid.
[1] http://www.ranum.com/security/computer_security/editorials/dumb/ http://www.ranum.com/security/computer_security/editorials/d...
[2] https://media.ccc.de/v/28c3-4763-en-the_science_of_insecurity https://media.ccc.de/v/28c3-4763-en-the_science_of_insecurit...
- ptero 10y agoI agree with the approach. However, specific examples of different badnesses are useful for testing the final product.
- kazinator 10y agoI.e. move enumeration of badness from code into test-cases.
- ubernostrum 10y agoguarantee that the input is valid with a parser generator OK, that works really well... until you learn how much non-RFC-specified behavior is built in to web browsers. Simply building a parser to the RFC will leave you wide open to all sorts of nastiness! The is_safe_url() internal function in Django is a bit of a historical dive into things we've learned about how browsers interpret (or, arguably, misinterpret) various types of oddball URLs: https://github.com/django/django/blob/master/django/utils/http.py#L287 https://github.com/django/django/blob/master/django/utils/ht...
- oneplane 10y agoI do wonder; is there any browser that is actually full-RFC-specced? I checked a few (the mainstream desktop ones, but also links2 etc.), but so far they all seem to have glue to fix historical behavior.
- gsnedders 10y agoPretty much no, because it'd be practically useless. And I don't think anyone has the willingness to spend time or money on something that will essentially just be a toy. There's been plenty of work on moving the standards so that there are actually implementations of them, instead of them being practically useless at best and misleading at worst (given doing input validation based on a spec that nobody actually implements is just outright dangerous), with HTML 5 and much of CSS 2.1 leading that charge (though CSS 2.1 still has massive blackholes, notably table layout remains largely undefined, though that is finally being worked on).
- pdkl95 10y ago> non-RFC-specified behavior I never said anything about limiting the parser to what's defined in an RFC. The acceptable input to "quirks mode" is just another (non-RFC) grammar, which still needs to be defined and validated.
- ubernostrum 10y agoThen I do wish you luck, but I don't think you'll ever be able to produce a suitably complete grammar since parts of it will require knowledge of undocumented proprietary internals of Internet Explorer. Hence we scrape along doing our best with what we can figure out from observing behavior and collecting bug reports. But even with that, is_safe_url() is one of the most prone-to-security-issues functions in Django's codebase.
- gsnedders 10y agoHopefully the URL spec (https://url.spec.whatwg.org https://url.spec.whatwg.org) is helpful here in finding other potentially unsafe behaviours that browsers have, though given much of it seems to be dealing with the fact that urllib.urlparse doesn't match what browsers do in many, many ways it's probably of limited help. (Nobody really implements it yet; it's just an attempt at standardising rough intersection semantics of what browsers currently do. Eventually, however, it should suffice, once legacy browsers eventually die.)
- kuschku 10y agoThat URL spec is just "this is what chrome does, everyone repeat that". They’re unwilling to modify anything, or standardize anything, but just want to cement the current piece of shit that URL parsing it for the future.
- gsnedders 10y agoGiven Chrome Canary currently fails a large number of tests, it seems like it's hardly just "this is what chrome does, everyone repeat that".
- kuschku 10y agoBecause the standard was changed to clean a bit of the stuff Google did up. But WHATWG only changes standards to include more, never to include less.
- jcranmer 10y agoWHATWG standards are generally formed by starting from what the 4 major browsers (Chrome, Firefox, IE (Edge), Safari) do. Anything that is done in common by all of them gets implemented no problem. It's when they all differ that the editor(s) tries to come up with more reasoned algorithms.
- kuschku 10y agoWhich is not really ideal. Standards aren’t about documenting what is, but about defining what will be.
- kazinator 10y agoException: passwords. Do not enumerate goodness when accepting a new password.
- sgift 10y agoPassword checking could be so easy ... if(password.size() < 24) "Your password sucks! Choose a longer one" Update each year to stay ahead of faster computer speeds.
- tracker1 10y agoSubstitute password with passphrase, mention hard limit (24 characters) and suggest using a sentence instead of word(s)
- zrm 10y ago> Can we please stop trying to enumerate badness[1]? No. Because we don't know what goodness looks like. The world can be separated into good, bad and unknown. If you classify anything unknown as bad then anything new is DOA. People aren't going to add new things to the whitelist before they're popular which means they can never become popular. It's stasis. But people do that anyway, which makes the good guys have to adopt the MO of the bad guys and make the new thing look like the existing thing. So everything uses HTTP and everything looks the same. Which means everything is more complicated than it needs to be, because it has to pretend to be something else, which creates more attack surface. And which means the whitelist is no longer meaningful because allow-http becomes equivalent to allow-everything. It's like buying a car that can only drive to home and work on the theory that it will be safer. It will be at first, except that you can no longer go anywhere but home and work. But when enough people do that then everything (including the bad stuff) has to move to where people are allowed to go. Which puts you right back where you started except that now you have two problems.
- pdkl95 10y ago> Because we don't know what goodness looks like. You're writing the parser, so you define the set of acceptable input. > The world can be separated into good, bad and unknown The data your software receives as input can be separated into valid input that your software will correctly interpret, or invalid input that is either and error or an attack. There shouldn't ever be any "unknown" input, as that would imply you don't know how your software parses its input. As the ccc talk in my previous [2] explains, this may be true if recognition of input is scattered across your software and thus hard to understand as a complete grammar. Thus the recommendation to put it all in one place using a parser generator (or whatever). > If you classify anything unknown as bad then anything new is DOA. Anything unknown is by definition not properly supported by the software you're writing.
- zrm 10y ago> Anything unknown is by definition not properly supported by the software you're writing. This seems to be where you're going wrong. There is no god-mode where you can see the whole universe and perfectly predict everything that will happen in the future. Your code has to do something when it gets a URI for a scheme that didn't exist when you wrote your code. The handler for that URI is third party code. Your code can either pass the URI to the registered handler or not. And if the answer is "not" then it will be prohibitively difficult for a new URI scheme (or what have you) to gain traction. Which means every new thing has to be shoehorned into HTTP and HTTP becomes an ever larger and more complicated attack surface.