Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include sast check for dockerfiles #696

Merged
merged 15 commits into from
Jun 22, 2023
Merged
99 changes: 99 additions & 0 deletions .github/scripts/dockerfile-security.rego
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little curious. Are these checks recommended ones?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, from the security team. I can share with you internally the link if you are interested, Aki.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please. I should have known them before I write any dockerfile :-)

Copy link
Member Author

@Tansito Tansito Jun 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Np, they seem relatively new. I didn't know them until we started some weeks ago with the deployment.

Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

# Do Not store secrets in ENV variables
secrets_env = [
"passwd",
"password",
"pass",
"secret",
"key",
"access",
"api_key",
"apikey",
"token",
"tkn"
]

deny[msg] {
input[i].Cmd == "env"
val := input[i].Value
contains(lower(val[_]), secrets_env[_])
msg = sprintf("Line %d: Potential secret in ENV key found: %s", [i, val])
}

# Only use trusted base images
deny[msg] {
input[i].Cmd == "from"
val := split(input[i].Value[0], "/")
count(val) > 2
msg = sprintf("Line %d: use a trusted base image", [i])
}

# Do not use 'latest' tag for base imagedeny[msg] {
deny[msg] {
input[i].Cmd == "from"
val := split(input[i].Value[0], ":")
contains(lower(val[1]), "latest")
msg = sprintf("Line %d: do not use 'latest' tag for base images", [i])
}

# Avoid curl bashing
deny[msg] {
input[i].Cmd == "run"
val := concat(" ", input[i].Value)
matches := regex.find_n("(curl|wget)[^|^>]*[|>]", lower(val), -1)
count(matches) > 0
msg = sprintf("Line %d: Avoid curl bashing", [i])
}

# Do not upgrade your system packages
upgrade_commands = [
"apk upgrade",
"apt-get upgrade",
"dist-upgrade",
]

deny[msg] {
input[i].Cmd == "run"
val := concat(" ", input[i].Value)
contains(val, upgrade_commands[_])
msg = sprintf("Line: %d: Do not upgrade your system packages", [i])
}

# Do not use ADD if possible
deny[msg] {
input[i].Cmd == "add"
msg = sprintf("Line %d: Use COPY instead of ADD", [i])
}

# Any user...
any_user {
input[i].Cmd == "user"
}

deny[msg] {
not any_user
msg = "Do not run as root, use USER instead"
}

# ... but do not root
forbidden_users = [
"root",
"toor",
"0"
]

warn[msg] {
input[i].Cmd == "user"
val := input[i].Value
contains(lower(val[_]), forbidden_users[_])
msg = sprintf("Line %d: Do not run as root: %s", [i, val])
}

# Do not sudo
deny[msg] {
input[i].Cmd == "run"
val := concat(" ", input[i].Value)
contains(lower(val), "sudo")
msg = sprintf("Line %d: Do not use 'sudo' command", [i])
}
30 changes: 26 additions & 4 deletions .github/workflows/docker-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ on:

env:
HADOLINT_DOCKER_IMAGE: hadolint/hadolint:v2.12.0

defaults:
run:
working-directory: ./infrastructure/docker
OPENPOLICYAGENT_DOCKER_IMAGE: openpolicyagent/conftest:v0.43.1

jobs:
lint:
Expand All @@ -24,7 +21,32 @@ jobs:
Dockerfile-repository-server,
]
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./infrastructure/docker
steps:
- uses: actions/checkout@v3
- name: Run hadolint in ${{ matrix.dockerfile }}
run: docker run --name hadolint --rm --interactive ${{ env.HADOLINT_DOCKER_IMAGE }} < ${{ matrix.dockerfile }}
sast:
strategy:
matrix:
dockerfile:
[
Dockerfile-gateway,
Dockerfile-notebook,
Dockerfile-ray-qiskit,
Dockerfile-repository-server,
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run conftest in ${{ matrix.dockerfile }}
shell: bash
run: |
docker run \
--name conftest \
--rm --volume $GITHUB_WORKSPACE:/project ${{ env.OPENPOLICYAGENT_DOCKER_IMAGE }} \
test --strict --parser dockerfile \
--policy .github/scripts/dockerfile-security.rego \
Tansito marked this conversation as resolved.
Show resolved Hide resolved
./infrastructure/docker/${{ matrix.dockerfile }}