Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Dockerfile
.git/

__pycache__/
**/__pycache__/
*.py[cod]
.pytest_cache/
.ruff_cache/
.coverage
htmlcov/
.vscode/

content/
Expand All @@ -10,4 +16,5 @@ attack-releases/

venv/
.venv/
**/node_modules/
.env
2 changes: 1 addition & 1 deletion .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
node-version: '18.x'
node-version: '26.x'

- name: Upgrade pip
run: python3 -m pip install --upgrade pip
Expand Down
187 changes: 127 additions & 60 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,65 +1,132 @@
# Use multi-stage build
FROM node:16 as node-build

WORKDIR /app

# Copy package.json, package-lock.json, and webpack configuration
COPY attack-search/package*.json ./attack-search/
COPY attack-search/webpack.config.cjs ./attack-search/

# Copy src/ folder with all subdirectories
COPY attack-search/src ./attack-search/src

# Generate the webpack bundle containing the search service
RUN cd attack-search && \
npm ci && \
npm run build

# Use the official Python image as the base image
FROM python:3.13-slim-bullseye as python-build

ENV DEBIAN_FRONTEND noninteractive
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8

# Install dependencies
RUN apt-get update --fix-missing && \
apt-get upgrade -y && \
apt-get install -y -qq --no-install-recommends locales sudo git apt-transport-https ca-certificates && \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen && \
update-ca-certificates

WORKDIR /home/attackuser/attack-website

# Copy the source code
COPY . .

# Install all Python dependencies
RUN python3 -m pip install --no-cache-dir wheel && \
python3 -m pip install --no-cache-dir -r requirements.txt

# Build the website
RUN python3 update-attack.py --no-test-exitstatus

# Copy the search service webpack bundle from the node-build stage
COPY --from=node-build /app/attack-search/dist/search_bundle.js output/theme/scripts/search_bundle.js

# Nginx stage
FROM nginx:stable-alpine as production-stage

COPY --from=python-build /home/attackuser/attack-website/output /var/www/html
# syntax=docker/dockerfile:1.7

FROM node:26-bookworm-slim AS search-build

WORKDIR /src/attack-search

COPY attack-search/package*.json ./
RUN npm ci

Check warning on line 8 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Omitting "--ignore-scripts" allows lifecycle scripts to run during package installation.

See more on https://sonarcloud.io/project/issues?id=mitre-attack_attack-website&issues=AZ-lXPX-HyoFLGN6uwxI&open=AZ-lXPX-HyoFLGN6uwxI&pullRequest=622

Check warning

Code scanning / SonarCloud

JavaScript package manager scripts should not be executed during installation Medium

Omitting "--ignore-scripts" allows lifecycle scripts to run during package installation. See more on SonarQube Cloud

COPY attack-search/webpack.config.cjs ./
COPY attack-search/src ./src
RUN npm run build


FROM python:3.13-slim-bookworm AS site-build

ARG PELICAN_SITEURL=""
ARG BANNER_ENABLED="true"
ARG BANNER_MESSAGE=""
ARG INCLUDE_OSANO="false"
ARG GOOGLE_ANALYTICS=""
ARG GOOGLE_SITE_VERIFICATION=""
ARG ATTACK_BRAND="false"
ARG UPDATE_ATTACK_EXTRAS=""
ARG GENERATE_STIX_CHANGELOG="false"
ARG VERSION_ARCHIVE_DIR="/var/cache/attack-website/version-archives"
ARG ATTACK_RELEASES_DIR="/var/cache/attack-website/attack-releases"
ARG DIFF_STIX_VERSION="v19.1"
ARG STIX_LOCATION_ENTERPRISE="https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json"
ARG STIX_LOCATION_MOBILE="https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json"
ARG STIX_LOCATION_ICS="https://raw.githubusercontent.com/mitre/cti/master/ics-attack/ics-attack.json"
ARG WORKBENCH_USER=""
# `:` is the POSIX shell no-op, used when optional setup commands are not supplied.
ARG OS_CA_TRUST_SETUP_COMMAND=":"
ARG PYTHON_CA_TRUST_SETUP_COMMAND=":"

ENV PELICAN_SITEURL=${PELICAN_SITEURL} \
BANNER_ENABLED=${BANNER_ENABLED} \
BANNER_MESSAGE=${BANNER_MESSAGE} \
GOOGLE_ANALYTICS=${GOOGLE_ANALYTICS} \
GOOGLE_SITE_VERIFICATION=${GOOGLE_SITE_VERIFICATION} \
UPDATE_ATTACK_EXTRAS=${UPDATE_ATTACK_EXTRAS} \
VERSION_ARCHIVE_DIR=${VERSION_ARCHIVE_DIR} \
ATTACK_RELEASES_DIR=${ATTACK_RELEASES_DIR} \
DIFF_STIX_VERSION=${DIFF_STIX_VERSION} \
STIX_LOCATION_ENTERPRISE=${STIX_LOCATION_ENTERPRISE} \
STIX_LOCATION_MOBILE=${STIX_LOCATION_MOBILE} \
STIX_LOCATION_ICS=${STIX_LOCATION_ICS} \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl git \
&& sh -ec "${OS_CA_TRUST_SETUP_COMMAND}" \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src/attack-website

COPY requirements.txt ./
RUN python3 -m pip install --no-cache-dir wheel \

Check warning on line 60 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=mitre-attack_attack-website&issues=AZ-lXPX-HyoFLGN6uwxJ&open=AZ-lXPX-HyoFLGN6uwxJ&pullRequest=622

Check warning

Code scanning / SonarCloud

Python dependencies should be locked to verified versions Medium

Using dependencies without locking resolved versions is security-sensitive. See more on SonarQube Cloud
&& python3 -m pip install --no-cache-dir -r requirements.txt \

Check warning on line 61 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Using dependencies without locking resolved versions is security-sensitive.

See more on https://sonarcloud.io/project/issues?id=mitre-attack_attack-website&issues=AZ-lXPX-HyoFLGN6uwxK&open=AZ-lXPX-HyoFLGN6uwxK&pullRequest=622

Check warning

Code scanning / SonarCloud

Python dependencies should be locked to verified versions Medium

Using dependencies without locking resolved versions is security-sensitive. See more on SonarQube Cloud
&& sh -ec "${PYTHON_CA_TRUST_SETUP_COMMAND}"

COPY . ./

# The generator copies theme assets into output/, so place the generated search bundle
# in the theme before running it.
COPY --from=search-build /src/attack-search/dist/search_bundle.js attack-theme/static/scripts/search_bundle.js

# A Workbench API key is optional for local/upstream builds. When supplied as a BuildKit secret,
# it is available only to this command and is not persisted in an image layer.
RUN --mount=type=secret,id=workbench_api_key,required=false \
--mount=type=cache,id=attack-website-artifacts-v1,target=/var/cache/attack-website,sharing=locked \
if [ -f /run/secrets/workbench_api_key ]; then \
export WORKBENCH_API_KEY="$(cat /run/secrets/workbench_api_key)"; \
export WORKBENCH_USER; \
fi; \
if [ "${INCLUDE_OSANO}" = "true" ]; then export INCLUDE_OSANO; else unset INCLUDE_OSANO; fi; \
mkdir -p "${VERSION_ARCHIVE_DIR}"; \
set --; \
if [ "${ATTACK_BRAND}" = "true" ]; then \
set -- "$@" --attack-brand; \
fi; \
if [ -n "${UPDATE_ATTACK_EXTRAS}" ]; then \
set -- "$@" --extras ${UPDATE_ATTACK_EXTRAS}; \
fi; \
python3 update-attack.py "$@" --no-test-exitstatus \
--version-archive-dir "${VERSION_ARCHIVE_DIR}"


FROM site-build AS changelog-build

RUN --mount=type=cache,id=attack-website-artifacts-v1,target=/var/cache/attack-website,sharing=locked \
if [ "${GENERATE_STIX_CHANGELOG}" = "true" ]; then \
download_attack_stix --download-dir "${ATTACK_RELEASES_DIR}" --all --stix21; \
fi

RUN --mount=type=cache,id=attack-website-artifacts-v1,target=/var/cache/attack-website,sharing=locked \
if [ "${GENERATE_STIX_CHANGELOG}" = "true" ]; then \
mkdir -p output/reports output/changes \
&& cp reports/* output/reports/ \
&& cp reports/tests.html output/ \
&& diff_stix -v \
--old "${ATTACK_RELEASES_DIR}/stix-2.0/${DIFF_STIX_VERSION}/" \
--new output/stix/ \
--show-key \
--contributors \
--html-file output/changes/index.html \
--html-file-detailed output/changes/changelog-detailed.html \
--markdown-file output/changes/changelog.md \
--json-file output/changes/changelog.json \
--layers output/changes/layer-enterprise.json output/changes/layer-mobile.json output/changes/layer-ics.json; \
fi


FROM nginx:stable-alpine AS production

Check warning on line 116 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

The "nginx" image runs with "root" as the default user. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=mitre-attack_attack-website&issues=AZ-lXPX-HyoFLGN6uwxM&open=AZ-lXPX-HyoFLGN6uwxM&pullRequest=622

Check notice

Code scanning / SonarCloud

Docker containers should not run as a privileged user Low

The "nginx" image runs with "root" as the default user. Make sure it is safe here. See more on SonarQube Cloud

COPY --from=changelog-build /src/attack-website/output /var/www/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Label metadata
LABEL name="attack-website" \
description="Dockerfile for the ATT&CK Website" \
usage="https://github.com/mitre-attack/attack-website/blob/master/README.md#install-and-build" \
url="https://attack.mitre.org/" \
vcs-url="https://github.com/mitre-attack/attack-website" \
vendor="MITRE ATT&CK" \
maintainer="attack@mitre.org"
LABEL org.opencontainers.image.title="ATT&CK Website" \
org.opencontainers.image.description="Static ATT&CK Website served by Nginx" \
org.opencontainers.image.source="https://github.com/mitre-attack/attack-website" \
org.opencontainers.image.url="https://attack.mitre.org/" \
org.opencontainers.image.vendor="MITRE ATT&CK"

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -q -O /dev/null http://127.0.0.1/ || exit 1

Check warning on line 130 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this invocation of "wget" with the ADD instruction.

See more on https://sonarcloud.io/project/issues?id=mitre-attack_attack-website&issues=AZ-lXPX-HyoFLGN6uwxN&open=AZ-lXPX-HyoFLGN6uwxN&pullRequest=622

CMD ["nginx", "-g", "daemon off;"]
Loading