Live data from Hacker News

Web Developer Security Checklist

simplesecurity.sensedeep.com

91–100 of 249 posts

Re: Web Developer Security Checklist

#91

Earlier quoted context omitted.

Agree with the point, but remember normal HTTP/1.1 /2 keep alive should close that connection in 15-30 seconds for all modern browsers. It will give rise to a DOS vulnerability as you point out.

But all the objects remain leaked even if the request connection ends. And if the request stream got piped into another stream the problem can become more severe. Usually error events propagate through piped streams, but that largely depends on the order in which the event handlers were defined.

Are you sure the objects remain leaked when a connection disconnect comes through? I don't have hard data on that.

Depending on the node web framework (express, ...) they may handle that differently and may have timeouts to cleanup.

I'd love to get a firm answer on this one.

Re: Web Developer Security Checklist

#92

How much of this is built into various frameworks such as Rails, Django, EmberJS (for frontend) etc?

Django actually has pretty good out of the box security settings and support for XSS, CSRF and SQL injection protection, support for bcrypt and argon2, setting password rules/validation through settings, etc:

https://docs.djangoproject.com/en/1.11/topics/security/

Re: Web Developer Security Checklist

#93
post #14

While it means well, I think some of this advice is pretty bad, or at least unbalanced. From the very first section: > Encrypt all data at rest in the database ALL data? How are you supposed to query against it then? What does "at rest" even mean in the context of an always-on database? An encrypted partition or something? I'm not even sure what this is supposed to mean and it is certainly not common practise. > Use…

I'm going to go the other way on the SQL advice, even though the author has clarified below that he was talking about prepared statements.

It doesn't cost me much, if any, developer time to work with stored procedures. I realize most full stack devs don't have as much in-depth experience with SQL. That was literally all I did for the first several years of my career. Before it ever occurred to me to learn other programming languages and. It was pure SQL all day every day.

If you have the resources to implement even half of this checklist, you probably have the resources to go whole hog on stored procs.

I sometimes do this, and sometimes don't. Partly, it's because I need to stay current with ORMs for the sake of potential job opportunities. And partially because it can be more convenient to keep my head in one language for fleshing out an idea. But for serious projects, I'll go the stored proc route.

In that kind of scenario, I think of the database as a type of microservice that's completely separate from the application layer. You write in the most performant language for that service, even if it's different for the main language the app is written in. And you reap the benefits of the database optimizing the procs as well as the database handling transactions instead of trying to manage that in your application.

How much of a burden this is boils down to whether you personally have the chops (or someone on the team does), and if you get your shit together when it comes to deployment. Stored Proc code should be saved in text files under version control, and your deploy process should make updates to the procs automatically.

If you do things this way, it's not any more painful than versioning your database with migrations, which I do on every project, no matter how small. Using stored procs doesn't have to mean you're working with a mess of unmanageable database code. You can use SQL Alchemy to create models and relationships, Alembic (just speaking to the Python world here), and use a thin wrapper around executing the stored proc, and it's really not that much different from writing prepared statements in Alchemy.

In principle, it's really not different from writing a web app that provides an API that your front end hits (a Python app that resents REST for Angular to call or something else equally common). In this case, I'm just pushing the API down one layer in the stack.

People can argue that the logic that applies to the data should be kept with the logic that defines the data--i.e., that if your model defines the shape of the date, your code that defines its behavior should reside there as well: in the model definition. So the ORM is the correct place for that. Methods on the Class object. I'm sympathetic to that argument, but I also disagree with it, sort of.

I think the rules that govern the behavior of data should exist where the data exists rather than any abstraction layer. Otherwise you have to rewrite them for every new thing that wants to access the data.

And every useful application that people use involving data is going to serve that data to more than the first application you designed to work with it. Keeping these rules in sync across even a very minimal web app that consists only of the app itself, an API, and an analytics platform is already some overhead.

And, every data-driven application already has two means of interface regardless of whether you intend that or not: direct database manipulation. That is going to happen sometimes, whether you want it or not or how bad a practice it is. If there are rules about how things should behave (there are always rules about how things should behave) you have to enforce them at the database level.

If you're doing that correctly already, there's really not that much overhead in using stored procedures. Going that route means that every connection to a database for a certain dataset means that there is a single source of truth for that dataset. Execute procedure x to get data y. That's all any developer on any service needs to know.

It also makes the idea of minimum privilege easier to manage. You don't have to grant select on a table for the API user, for example. You can grant execute to the set of procs that user needs, and only those procs are accessible. Combine that with some well-thought views, and you can greatly limit your attack surface. If someone breaches part of your system and manages to obtain so source code, they don't get any real information about the structure of your database. They only get conn.execute('check_valid_user') or whatever.

The obvious problem here is versioning APIs. Which you must always do. So you have to version your stored procs when there are breaking changes. But the overhead in adding a _v1 or _v1.1 to the end of an .sql file for a proc really isn't that big of a deal compared to all the other stuff you have to do when maintaining an API.

Again, I'm sympathetic to objections to this model. It is not perfect, and I've never once tried to inflict it on coworkers who want to do things differently. I'll do this in my own projects, and when I've gone into a company that's already working with that mindset. I don't hold up the train based on philosophical differences.

There's a lot of criticism I agree with that SOA is not a good place to start. It carries a lot of overhead, and you shouldn't go there until you need to. But to me, the reality is that any web app that comprises a data store, a controller layer, and a front end is already by definition SOA--not the monolith that you want to think of it as. And therefore you should treat it as such and give the various components the attention they deserve.

If you're working on a project you have reasonable expectation will be used enough to require some scaling, this is a totally acceptable way to do things. Let the database do what it's best at, let the controller layer do what it's best at, and then use the front end that's best for your use case.

Because this response isn't long enough already, I'll just add this. I don't think the MVC model is really appropriate for web apps. Even the modified MVVC model is still weird to me. It seems like a model we shoehorned onto what a web app really is. To me, the web app model is data, logic, presentation. The data layer comprises both the data and the rules about the data. The logic layer dictates what happens when an event is triggered by the presentation layer. And it should be relatively thin, particularly when working with one of the slower languages like Python or Ruby. The presentation layer simply defines the user interface and sends messages to the logic layer.

These things really are decoupled by nature in ways they aren't necessarily in native or desktop apps or mobile apps. I think that web developers need to understand that this model really doesn't fit very well. And behave accordingly.

There are obviously exceptions to everything I'm saying here. But the exceptions come at very large scales. Most apps that start out as MVC web apps on whatever stack are not going to become Facebook or Reddit and are not going to have the specific problems that come with that level of scale.

Even so, I would encourage people to rethink what web apps are, and what the MVC/MVVC model really means. I really don't think it's the right model, and the decisions we make about architecture are generally not good ones.

Finally, since this is so long now, I want to point out that I didn't generate these ideas all on my own. I've been heavily influenced by Lex de Haan and Toon Kopplaars in their book, Applied Mathematics for Database Professionals.

Re: Web Developer Security Checklist

#94
OWASP has published a release candidate of the OWASP "top-ten" available as a PDF at https://github.com/OWASP/Top10/raw/master/2017/OWASP%20Top%2.... They also support the creation and maintenance of quite a few OSS tools to help secure systems.

To those who are claiming some of these steps are too onerous or would cause performance issues: Are you sure? For an individual system, maybe some of these checkboxes are indeed overkill. Or perhaps your system isn't as secure as you believe? To be fair, there are systems that don't require as much security because the data simply doesn't matter - if they systems contain email address / password hash combinations, they should still treated very carefully.

I think the biggest mistake I've seen made time and time again is that teams go the cheap route and put the database on an Internet connected machine. Don't build a whole architecture until you've got customers to support it but don't be quite that cheap at the beginning.

For systems that require higher than average security, I've been part of a team that went to MUCH further extremes.

Re: Web Developer Security Checklist

#96
post #86

Earlier quoted context omitted.

If it's symmetric, then doesn't an app vulnerability make it possible for you to leak your key? Then the app also contains access credentials to the DB, so vulnerabilities in the app will still lead to real access to the DB, right?

Yes, we're not protecting against the app being attacked, the key being jacked and then the attacker getting access to the db. Rather, we're protecting the database against being accessed directly. That could happen due to an error in configuring network access to the database or another service could be compromised that has access to the same database -- as has happened to many mongo databases over this year.

So your solution to fixing a basic ops problem 'software package A was exposed to the internet with(out|effectively no) auth' is: encrypt shit in an ORM layer and destroy your ability to do anything beyond absolute string comparison queries.

No thanks.

Re: Web Developer Security Checklist

#97
Prepared statements are amazing. Found out about them very soon after I started programming (incidentally my first language was PHP), and switched to PDO right away. This was years ago, I don't understand how people are still using the deprecated and insecure mysql_* functions, you can still find them all over SO and my university "web" class was teaching them as well...

Re: Web Developer Security Checklist

#98

Earlier quoted context omitted.

Yes, we're not protecting against the app being attacked, the key being jacked and then the attacker getting access to the db. Rather, we're protecting the database against being accessed directly. That could happen due to an error in configuring network access to the database or another service could be compromised that has access to the same database -- as has happened to many mongo databases over this year.

So your solution to fixing a basic ops problem 'software package A was exposed to the internet with(out|effectively no) auth' is: encrypt shit in an ORM layer and destroy your ability to do anything beyond absolute string comparison queries. No thanks.

No, we don't encrypt indiscriminately. We selectively pick fields to encrypt - fields that are highly sensitive.

And you are right, we do this because an ops error can easily make a mistake sometime in the future and probably will one day. We all make mistakes and defense in depth is all about that.

Re: Web Developer Security Checklist

#99
post #87

Isn't best practice when it comes to passwords to actually choose a good one, use a password safe, and _not_ rotate?

Both. You want to choose a good password and then not let it get too stale. A very old password (say 1 year) has a higher chance of being subverted purely because there is more elapsed time wherein attackers could have gained access. Choose good passwords, long, special chars, preferably random and generated by a password generator / manager. And then change periodically. That period depends on your application. We c…

"A very old password (say 1 year) has a higher chance of being subverted purely because there is more elapsed time wherein attackers could have gained access."

Any actual evidence for this? My counter-hypothesis is if your password lasts 6 months of attempted hacks it'll last >6 years (unless social engineering attempts succeed).

I ask because rotating goes against the current NIST password guidance. In fact, for your recommendation "Implement simple but adequate password rules that encourage users to have long, random passwords", I'd recommend pointing people in that direction.

Re: Web Developer Security Checklist

#100

Earlier quoted context omitted.

Both. You want to choose a good password and then not let it get too stale. A very old password (say 1 year) has a higher chance of being subverted purely because there is more elapsed time wherein attackers could have gained access. Choose good passwords, long, special chars, preferably random and generated by a password generator / manager. And then change periodically. That period depends on your application. We c…

"A very old password (say 1 year) has a higher chance of being subverted purely because there is more elapsed time wherein attackers could have gained access." Any actual evidence for this? My counter-hypothesis is if your password lasts 6 months of attempted hacks it'll last >6 years (unless social engineering attempts succeed). I ask because rotating goes against the current NIST password guidance. In fact, for you…

Sorry, I should be clearer (late here).

With time passing, the chance of you or anyone with access to the password being socially engineered, or some other human error, or a hack on your PC desktop systems, increases linearly with time. The password may last a decade of brute force cracking, but we humans .... continue to make mistakes far more frequently.

So rotating passwords protects against the accumulation of human mistakes and insider threats.

If you are using proper hashing, then your passwords should be safe even if the hashes are compromised.

Could you please point to the NIST recommendation you mention. I thought they said that you should NOT force customers to change passwords. But that is different to you rotating your own critical passwords at a time of your choosing and on your policy.

Post reply on HN