Hacker News new | past | comments | ask | show | jobs | submit login
Probably Are Gonna Need It: Application Security Edition (jacobian.org)
137 points by goranmoomin on July 29, 2021 | hide | past | favorite | 24 comments



This is a great list.

I think one of the hardest things to add after the fact are security headers. Once marketing is involved with an app's marketing site, it's going to be hard to add them in later. So I add them from day one, ace the Mozilla Observatory thing, and then if marketing needs something special, we can always deal with it then. Usually the result is something more secure, but sometimes turning off a flag for a single page is fine.

If it's the style of app where the backend is basically just a JSON API + workers, I like to follow JSON API[0] but I always add the `meta` and `errors` fields, even if it's just an empty dict, but usually there is something meta, like the latest versions of the client and server or a rate limit use + available combo. It makes writing clients easier. It also has knock-on effects, for example a delete request never gets a 204 NO CONTENT, since there is always content!

Once you get a consistent API the frontend just snaps together. Every now and then you may have to deviate a bit for performance or third-party reasons, but it's fine.

[0] jsonapi.org


I really like Jacob's suggestion to set up the "restore a copy of the production database to staging" script to use an allow-list of columns, rather than a deny-list.

It's so, so easy for PII and other sensitive data to end up copied to a staging environment, which has a higher chance of shipping a security vulnerability than the production environment does (plus exposes data to staff within an organization).

Strictly allow-listing columns from the start seems like a great way to minimize accidental leaks.


I’m not sure if it would work for everyone, but we keep all our sensitive data in an entirely separate schema, and everything is to be built to assume the sensitive rows can suddenly not exist at any time.

This way we only need to restore the insensitive schema to staging areas, and have different backup policies, keeping the insensitive far longer.


Get your AuthZ design right early on, or you’ll forever be plagued with APIs that fail open or aren’t protected, and it’s so very hard to change later on.

The best advice I’ve seen on this: https://research.nccgroup.com/2020/04/21/code-patterns-for-a...


One more thing to have, which seems obvious, but is also worth mentioning here: a Security Configuration Guide.

Basically, one guide that explains all the security features, how they work, when they should be used, associated configuration settings, what defaults are, what other possible values are, known gotchas, how to verify security features are working correctly, which ports and protocols are used and when they're used (so that a firewall admin can setup accordingly), etc.


Password hashing. Because you’re not storing clear text passwords, it can be tricky to upgrade later if you’ve chosen something bad like md5. You either have to force your entire user base to reset, or you do an over-time migration when people login, which will always leave some not upgraded.


I like the way Django stores passwords:

    pbkdf2_sha256$260000$theHashDataGoesHere
The algorithm comes first, then the number of iterations, then finally the hash value.

This makes it possible to increase iterations or even switch algorithms upgrade and re-hash existing passwords automatically later on when users sign in. Django handles this for you.

Another good reason to use a mature, extensively tested mechanism for authentication rather than rolling your own from scratch.


There's a third pattern forward, which is that you rehash the entire password database with a more secure (specifically, slower) hash plus new, secret salt.

This also means you have a chance to crack any improper salt/secret storage, such as provisioning into memory only.

You will still need to do a password upgrade on login, but you at least have now made it a requirement that an attacker not only grab your database, but also a memory snapshot or disk snapshot.


We switched from a hash to bcrypt five+ years ago on a rolling migration. Just a month ago I received final go ahead to clear out legacy passwords and require a password reset if someone does try to get in. My point is that there are office politics at work here even.


Or you set a suitable deadline after which users are forced to reset, with the comfortable over-time migration happening until then.


That's a much better suggestion that most of the points in the article, IMO.


Are there good security checklists for (1) personal security to protect one from hacking, identity theft, etc. and (2) businesses that have online services but aren't as tech savvy as a large tech giant that has huge security teams etc.


As for (1), I can directly recommend Personal Security Checklist (https://security-list.js.org/#/README), it has complete, updated and reasonable advice for most people.


It's showing a little age, but this list from Tech Solidarity gives you an intro to (1): https://techsolidarity.org/resources/basic_security.htm


Using well known tools is a double edged sword. On the one hand security issues are often found fast and fixed fast. On the other hand they are also exploited fast and en masse.

I have been building websites professionally for nearly two decades. In that time I have seen major attacks against a number of sites I worked on. They were ALL exploits in up to date frameworks/applications found by bots scanning for known vulnerabilities. In order of severity Wordpress, Django, osCommerce; Django was actually the most recent.

I’ve never had a custom built app compromised. Unless you’re some major player, no one wants to take the time to find flaws in your snowflake (outside query injection and the other common things you should know to protect against with experience). They find a flaw in a framework or library and then try to apply the known flaw everywhere.

Should every site be a snowflake? Surely not, not every developer is competent enough to build safe applications. Does it come with major upsides? Absolutely.


I'm very curious about the "major attack" against Django you mention. I'm unaware of in-the-wild attacks targeting Django itself, so I'd really like to know what I missed. Can you share more details with me? Public or private is fine, send me an email if you prefer.


> I’ve never had a custom built app compromised.

That you are aware of.


I love this. It’s such an uphill battle sometimes to explain how small things will save so much time and pain later on but people will cling to YAGNI as a reason to ignore everything. Maddening at times.


I feel SSO should also be table stakes. Why even bother implementing your own account management if you can just use Keycloak or something even simpler to do it for you. This way your users can easily connect your app to whatever identity provider they are using.


> it’s nearly impossible to retrofit mitigations for spam, harassment, or abuse

... why?


Because they often represents fundamental flaws in the overall social design of your service.

Twitter allows anyone to reply-to or quote-tweet anyone else, for example. That has a huge impact on how abuse works on that service.

The abusive-ex persona Jacob describes is super-useful for avoiding making bad design decisions early on that end up being too hard to fix.


It seems more like these features of twitter are working as intended. I seriously doubt its because its too hard for them to block these actions.


It's not technically hard to change that - it's hard because the service now has millions of users who expect it to work the way it does.


It is bad enough that I have had to apply “application-layer” security to systemd in order to ensure that it “behaves”.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: