Comment by duckmysick

2 years ago

> Twilio has detected that threat actors were able to identify data associated with Authy accounts, including phone numbers, due to an unauthenticated endpoint. We have taken action to secure this endpoint and no longer allow unauthenticated requests

How do I avoid such problems in my own app? Force authentication for all requests with row-level security? Rate limiting?

Any testing frameworks that would catch this? Something like "given endpoint /user/phone-number-validate make sure only <user> can access it".

One step we have taken is to build an auth system that requires you as the developer to explicitly specify the security of an endpoint using a decorator. If no decorator is provided, then the endpoint is completely locked down even to admins (effectively disabled).

If an endpoint is decorated with something that is considered dangerous (i.e. public access), that triggers additional review steps. In addition, the authentication forbids certain combinations of decorators and access patterns.

It's not perfect, but it has saved us a few times from securing endpoints incorrectly in code.

  • .NET web apps / APIs have an option where you can require authorization on all controllers (and their actions) by default. If you need an anonymous controller/action, you can use the `[AllowAnonymous]` attribute on it.

    • You can easily do the same with most (all?) routers using middleware. Whether you get it slotted in your roadmap is a different story.

  • That's pretty cool.

    > that triggers additional review steps

    Is this done by some sort of a linter running in CI?

It's a common problem. On a previous job, I'd found one unauthenticated endpoint just because I want to add some integration tests on it and my tests failed! After that, I'd created a script which lists all endpoints and curl each one with invalid credentials and expecting them to return 401.

This is really, really, simple.

1. build a single endpoint handler that handles auth, then looks up the endpoint on the path. 2. Never create direct endpoints, just register endpoints in the system that the auth endpoint works under.

You know table driven tests?

Use table driven endpoints. It works and makes things so much simpler and secure.

  • > 1. build a single endpoint handler that handles auth, then looks up the endpoint on the path. 2. Never create direct endpoints, just register endpoints in the system that the auth endpoint works under.

    So like, an authn/authz middleware ?

Mh, I'm probably comparing apples to oranges and such.

But the last 2-3 times I setup a config management, I made sure to configure the local firewalls as deny-all by default, except for some necessities, like SSH access. And then you provide some convenient way to poke the necessary holes into the firewall to make stuff work. Then you add reviews and/or linting to make sure no one just goes "everything is public to everyone".

This way things are secure by default. No access - no security issues. And you have to make a decision to allow access to something. Given decent developers, this results in a pretty good minimum-privilege setup. And if you fuck up... in this day and age, it's better to hotfix too little access over losing all of your data imo.

  • > necessities, like SSH access.

    SSM for life. Fun fact, one can also register non-AWS assets as SSM targets, so I could imagine a world in which it makes sense to create an AWS account, wire up federated auth, just to dispense with the hoopjumpery of SSH attack surface and Internet exposure

    The break-glass is always a consideration, so it's no panacea but I still hope one day the other clouds adopt the SSM protocol same as they did with S3Api

    I believe a lot of folks have had good experiences with Wireguard and similar, but thus far I haven't had hand-to-hand combat with it to comment. We use Teleport for its more fine-grained access and auditing, but I've had enough onoz with it to not recommend it in the same way as SSM

This is actually a use-case I use for interviews.

1. Everyone tests authenticated user can do the right thing.

2. Can <wrong|expired> authenticated user access the data?

3. Can an unauthenticated user access data?

If there’s a testing framework that does this scaffolding automatically, I’d love to hear it.

Holy shit why is this even a question?? You. Write. Tests.

You build into your testing framework/library a mechanism that will craft sessions across your range of authentication-levels - unauthenticated (no-session), authenticated but unauthorized, etc. You mandate new endpoints must have permissions test in code review.

Simple, straight forward, and absolutely the bare minimum of competency for any endpoint returning personal data.

  • And then someone forgets to test that one thing for that one endpoint and no one notices ("mandate in code review" is not going to be fool-proof), or lines get crossed and they test the wrong thing.

    This kind of arrogance is exactly how these mistakes get made.