4 ms·
This advice is not great! From the top: Flat promise chains aren't fully general (you'll need a lot of trivial helper functions to do anything other than seque
by bcoates 5y ago
This advice is not great! From the top:
Flat promise chains aren't fully general (you'll need a lot of trivial helper functions to do anything other than sequence of single operations). This is fine because you shouldn't be using nontrivial .then()s outside of utility code.
Alternate advice: always use async/await for asynchronous control flow.
Request limits, toobusy, and several other pieces of advice assume you're throwing a single node process on the internet directly. Do not do this, you probably want at least an nginx or other battle-ready front end proxy, and probably want a CDN and/or load-balancer too. Configure these correctly to not send overlarge, weird, slowloris, etc., requests through to the node processes.
The thing about express letting API attackers create exotic objects is genuinely scary, and if true makes me want to not use express anymore or at least install a middleware to drop requests that try it.
Describing anti-XSS measures as 'escaping' is a little questionable, you should be using proper tools for generating machine-readable information, not string concatenation or (shudder) interpolation. Build a DOM, convert it to text, send it out unmodified.
IP level rate limiting simply doesn't work, at least not in the trivial "just use bouncer" way described.
It's unexplained what you could possibly use object property descriptors for to obtain security benefits. They are not, in general, a security perimeter. If attacker is running code in your context, attacker has won.
uncaughtException is difficult to use correctly, error prone, and has little to offer in general. The default behavior does the right thing. uncaughtExceptionMonitor lets you do a little extra logging before crashing if you like and is less of a footgun.
Much of the rest of the advice is generic web application security recommendations.
- polishdude20 5y agoWhy is up level rate limiting bad?
- bcoates 5y agoAttackers have a practically unlimited number of IPs to use if they want to do a brute force password attack.
- polishdude20 5y agoSo how do you stop it?
- nokya 5y agoIn cryptography, a brute force (BF) attack should be the last resort for the attacker. Unfortunately, many designs involve poor crypto thus creating a context in which a BF attack is cheaper than other attacks. Unless BF attacks cost you money directly (e.g. consumption based or pay-as-you-go billing) you should not aim at preventing them but rather aim at making them impractical for the attacker. In other words: computing one test should be as expensive as possible (e.g., computational cost, a waiting time, etc.) and/or the number of possibilities must be so gigantic that the attacker can't even dream of trying all options within reasonable time. Think about well-implemented access tokens: there are so many possible values that computing or guessing a valid token would likely cost a lot of energy/time. Best course of action may vary depending on the asset you are trying to protect. For password-protected accounts, increasing the cost typically translates into inducing artificial wait times (e.g., authorising max. N tries per minute on an account) and increasing the "possibilities" would typically require ensuring users choose robust passwords (very unlikely) or use 2-factor authentication (which essentially brings you the "gigantic number of possible values"). Hope it helps.
- Rd6n6 5y agoIf you’re not crazy about this advice, is there an alternative resource you would recommend for securing an app stack with a nodejs backend?
- Too 5y agoAuto parsing query into objects of various types is scary indeed. This could break for all kinds of legitimate or malicious user input if you were not aware of it. There is an option called “query parser” which can be set to false to disable it globally. Having a format for such data was probably a good idea but when it’s not defined by http and thus inconsistent across frameworks (php does similar parsing, but differently), and doesn’t have an easy way to access the raw string, I’d just stick to json for complex data. Maybe the assumption is that one should use route parameters instead.