Overengineering Security for Fun and no Profit

Confronted with lack of budget for proper security tooling, I decided to just create my own. We occasionally ran Prowler manually. The results were mostly ignored. There was no ownership tracking, no history, no breakdown by account or team, and no good way to correlate findings over time.

Basically the standard “we technically do security scans” setup.

So I built something myself.

The actual application itself is honestly not that interesting. It’s mostly a CRUD app written in Go and HTMX. It handles the usual things.

  • Launch and schedule scans
  • Store and display findings
  • Track ownership
  • Send Slack notifications
  • Group findings by team/account/repository
  • Show some basic graphs

The interesting part was the security model around the scanners themselves. Because the more I worked on it, the more I realized something uncomfortable: the scanners were actually some of the highest risk components in the entire environment.

Think about what these tools normally get:

  • Unrestricted read access to AWS accounts
  • Unrestricted read access to repositories
  • Full internet access
  • CI/CD integration
  • Permissions to pull arbitrary images and dependencies

That is an absurd amount of trust.

Read More »

Lazy Secret Rotation with CDK

A few years ago, I needed periodic rotation for MongoDB Atlas API keys. We had a pretty well established CDK project with linting, cdk-nag, diffs on PRs, automatic deployments on merge to main, the works. Everything was reasonably locked down with least privilege, backups, automatically rotating secrets, hardened containers, and the kitchen sink. So obviously when adding MongoDB Atlas to the mix, I wanted to apply the same principles and build secure automated deployment with CDK.

Luckily for me, MongoDB Atlas has CloudFormation resources and even a CDK library. A lot of the resources are L1, but it’s better than creating custom resources for everything. Creating an API key is something along the lines of:

import * as cdk from 'aws-cdk-lib';
import * as l1_resources from 'awscdk-resources-mongodbatlas/lib/l1-resources/api-key';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'mongo-example');
const apiSecret = new secretsmanager.Secret(stack, 'API Key Secret');
new l1_resources.CfnApiKey(stack, 'API Key', {
awsSecretName: apiSecret.secretFullArn,
});

This takes care of creating the API key and writing it into a secret. It’s not exactly the usual CDK pattern where the secret is created but its value needs to be filled later outside of the deployment. It’s actually pretty nice, since one command can do it all including taking care of rollbacks and everything.

But there was still one problem. I wanted periodic API key rotation. For security. Of course…

Read More »

Docker Combo Images

combo

I’ve been working with Docker a lot for the past year and it’s pretty great. It especially shines when combined with Kubernetes. As the projects grew more and more complex, a common issue I kept encountering was running both Python and JavaScript code in the same container. Certain Django plugins require Node to run, Serverless requires both Python and Node, and sometimes you just need some Python tools on top of Node to build.

I usually ended up creating my own image containing both Python and Node with:

FROM python:3

RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
RUN apt-get install -y nodejs

# ... rest of my stuff

There are two problems with this approach.

  1. It’s slow. Installing Node takes a while and doing it for every non-cached build is time consuming.
  2. You lose the Docker way of just pulling a nice prepared image. If Node changes their deployment method, the Dockerfile has to be updated. It’s much simpler to just docker pull node:8

The obvious solution is going to Docker Hub and looking for an image that already contains both. There are a bunch of those but they all look sketchy and very old. I don’t feel like I can trust them to have the latest security updates, or any updates at all. When a new version of Python comes out, I can’t trust those images to get new tags with the new version which means I’d have to go looking for a new image.

So I did what any sensible person would do. I created my own (obligatory link to XKCD #927 here). But instead of creating and pushing a one-off image, I used Travis.ci to update the images daily (update 2022: GitHub Actions). This was actually a pretty fun exercise that allowed me to learn more about Docker Python API, Docker Hub and Travis.ci. I tried to make it as easily extensible as possible so anyone can submit a PR for a new combo like Node and Ruby, or Python or Ruby, or Python and Java, etc.

The end result allows you to use:

docker run --rm combos/python_node:3_6 python3 -c "print('hello world')"
docker run --rm combos/python_node:3_6 node -e "console.log('hello world')"

You can rest assured you will always get the latest version of Python 3 and the latest version of Node 6. The image is updated daily. And since the build process is completely transparent on Travis.ci you should be able to trust that there is no funny business in the image.

Images: https://hub.docker.com/r/combos/
Source code: https://github.com/kichik/docker-combo
Build server: https://github.com/kichik/docker-combo/actions

Staying Safe Online

I have seen a few “staying safe online” guides lately. I wrote one of my own a while back after some of my friends were threatened online and got worried. This guide should be a good starting point for most common casual internet users. It’s important to remember that no matter what you do if it’s online, it can be hacked.

  • Never reuse passwords
    • Some websites are easier to hack than others
    • Hackers will try the same password on other websites
    • Use 1Password for easier management
  • Don’t use simple passwords
    • Hackers guess passwords all the time
    • There are easy automatic tools that enumerate all password options
    • Don’t use your name, birthday, SSN, or any public information in passwords
  • Keep your computer & phone up-to-date
    • Old software has known and easily exploitable vulnerabilities
  • Never click links in emails
    • Clicking the wrong link can give control of your accounts to hackers
    • Manually browse to the website even if the email looks legit
  • Always logout on public computers
    • Preferably never login on public computers in the first place
    • Data can be linger even after logging out
    • Some public computers record your passwords
  • If it was put online, it will stay online
  • Any private information shared can help hacking
    • Your name and birth year can be enough to guess your SSN

Securing Facebook

  • Click the little lock icon on top and follow instructions
    • Set everything to private
    • Hide your birth year
  • Click the little triangle on the top right and choose Settings
    • Enable login alerts to be notified of hacks
    • Enable login approvals
    • Enable trusted contacts in case your account is hacked

Securing Google Account