WIP | Security set up in compose

This commit is contained in:
adelyaou 2025-08-22 10:21:38 +07:00
parent 4b1f6d6362
commit 892619df08
8 changed files with 568 additions and 49 deletions

View File

@ -41,3 +41,6 @@ yarn-error.log*
next-env.d.ts next-env.d.ts
/src/generated/prisma /src/generated/prisma
# secrets
/secrets/

4
.env
View File

@ -1,4 +1,4 @@
# DATABASE_URL="mysql://sipintar_user:sipintar_password123:@db:3306/sipintar_school" DATABASE_URL="mysql://sipintar_user:sipintar_password123:@db:3306/sipintar_school"
DATABASE_URL="mysql://root:root123@sipintar-mysql:3306/sipintar_school" # DATABASE_URL="mysql://root:root123@sipintar-mysql:3306/sipintar_school"
NEXTAUTH_SECRET="your-secret-key-here-change-this-in-production" NEXTAUTH_SECRET="your-secret-key-here-change-this-in-production"
NEXTAUTH_URL="http://localhost:3000" NEXTAUTH_URL="http://localhost:3000"

3
.gitignore vendored
View File

@ -43,3 +43,6 @@ yarn-error.log*
next-env.d.ts next-env.d.ts
/src/generated/prisma /src/generated/prisma
#secrets
/secrets/

View File

@ -1,7 +1,14 @@
# Build stage # Build stage
FROM node:20-alpine AS builder FROM node:20-alpine AS builder
#buat user baru untuk security setup
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app WORKDIR /app
# change ownership untuk user baru
RUN chown -R appuser:appgroup /app
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile RUN pnpm install --frozen-lockfile
@ -9,15 +16,27 @@ RUN pnpm install --frozen-lockfile
COPY . . COPY . .
RUN npx prisma generate RUN npx prisma generate
RUN pnpm run build RUN pnpm run build
RUN chown -R appuser:appgroup /app/node_modules
# Production stage # Production stage
FROM node:20-alpine AS runner FROM node:20-alpine AS runner
WORKDIR /app WORKDIR /app
#buat user di runner stage
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY package*.json ./ COPY package*.json ./
COPY --from=builder /app/.next ./.next COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public COPY --from=builder /app/public ./public
COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/src ./src
COPY --chown=appuser:appgroup --from=builder /app/node_modules ./node_modules
ENV NODE_ENV=production ENV NODE_ENV=production
EXPOSE 3000 EXPOSE 3000
#ganti user jadi non root
USER appuser
CMD ["npm", "run", "start"] CMD ["npm", "run", "start"]

View File

@ -1,71 +1,109 @@
version: '3.8' version: '3.8'
services: services:
app: app:
build: image: adelyao/sipintar-app:latest
context: .
dockerfile: Dockerfile.prod
container_name: sipintar-app
restart: unless-stopped
working_dir: /app working_dir: /app
ports: ports:
- "3000:3000" - "3000:3000"
environment: # environment:
NODE_ENV: production # # DATABASE_URL: /run/secrets/db_url
DATABASE_URL: mysql://sipintar_user:sipintar_password123@db:3306/sipintar_school # # DATABASE_URL_FILE: /run/secrets/db_url
# DATABASE_URL: "mysql://sipintar_user:$$(cat /run/secrets/db_password)@sipintar_mysql:3306/sipintar_school"
depends_on: depends_on:
db: - db
condition: service_healthy
# volumes:
# - .:/app
# - /app/node_modules
# - /app/.next
networks: networks:
- sipintar-network - sipintar-overlay
command: ["npm", "run", "start"] deploy:
resources:
limits:
cpus: '0.5'
memory: 350M
reservations:
cpus: '0.1'
memory: 100M
restart_policy:
condition: on-failure
command: ["sh", "-c", "export DATABASE_URL=$$(cat /run/secrets/db_url) && npm run start"] #nanti tambahin biar prisma langsung di run
secrets:
- db_url
sipintar_mysql:
db:
image: mysql:5.7 image: mysql:5.7
container_name: sipintar-mysql
restart: unless-stopped
environment: environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123} MYSQL_DATABASE: sipintar_school
MYSQL_DATABASE: ${MYSQL_DATABASE:-sipintar_school} MYSQL_USER: sipintar_user
MYSQL_USER: ${MYSQL_USER:-sipintar_user} MYSQL_PASSWORD_FILE: /run/secrets/db_password
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-sipintar_password123} MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
ports:
- '3307:3306'
volumes: volumes:
- mysql_data:/var/lib/mysql - mysql_data:/var/lib/mysql
- ./setup-database.sql:/docker-entrypoint-initdb.d/setup-database.sql - ./setup-database.sql:/docker-entrypoint-initdb.d/setup-database.sql
networks: networks:
- sipintar-network - sipintar-overlay
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot123"] test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p$$(cat /run/secrets/db_root_password)"]
interval: 10s interval: 30s
timeout: 5s timeout: 10s
retries: 5 retries: 10
start_period: 30s start_period: 40s
deploy:
restart_policy:
condition: on-failure
resources:
limits:
cpus: '0.5'
memory: 350M
reservations:
cpus: '0.1'
memory: 100M
secrets:
- db_password
- db_root_password
- db_url
seed:
build: scanner:
context: . image: aquasec/trivy:latest
dockerfile: Dockerfile.prod
container_name: sipintar-seed
restart: "no"
working_dir: /app working_dir: /app
environment: environment:
NODE_ENV: production TRIVY_SEVERITY: "CRITICAL,HIGH"
DATABASE_URL: mysql://sipintar_user:sipintar_password123@db:3306/sipintar_school TRIVY_IGNORE_UNFIXED: "true"
depends_on: TRIVY_OUTPUT: "/app/trivy-report.json"
db: volumes:
condition: service_healthy - /var/run/docker.sock:/var/run/docker.sock
command: ["npm", "run", "db:seed"] - ./trivy-results:/tmp/trivy-results
command: ["image", "-q", "--format", "json", "--severity", "CRITICAL,HIGH", "app", "--output", "/tmp/trivy-results/trivy-report.json"]
networks: networks:
- sipintar-network - sipintar-overlay
deploy:
resources:
limits:
cpus: '0.5'
memory: 350M
reservations:
cpus: '0.1'
memory: 100M
secrets:
db_password:
file: ./secrets/db_password.txt
db_root_password:
file: ./secrets/db_root_password.txt
db_url:
file: ./secrets/db_url.txt
volumes: volumes:
mysql_data: mysql_data:
networks: networks:
sipintar-network: sipintar-overlay:
driver: bridge driver: overlay
#docker-compose -f docker-compose-prod.yml --env-file .env.prod build
#docker-compose -f docker-compose-prod.yml --env-file .env.prod up -d
#docker-compose -f docker-compose-prod.yml --env-file .env.prod up (yg ada pilusnya)
#docker-compose -f docker-compose-prod.yml --env-file .env.prod up --build -d
#docker stack deploy -c docker-compose-prod.yml sipintar_stack
#docker-compose down
# docker system prune -f
# docker network prune -f

View File

@ -0,0 +1,52 @@
services:
prometheus:
image: prom/prometheus:v2.37.1
volumes:
- ./prometheus:/etc/prometheus
- prometheus_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
deploy:
placement:
constraints:
- node.role == manager
networks:
- traefik-public
node-exporter:
image: prom/node-exporter:v1.3.1
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- "--path.procfs=/host/proc"
- "--path.sysfs=/host/sys"
- "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)"
deploy:
mode: global
networks:
- traefik-public
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.45.0
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
deploy:
mode: global
networks:
- traefik-public
volumes:
prometheus_data:
networks:
traefik-public:
external: true

View File

@ -1,6 +1,7 @@
import bcrypt from 'bcryptjs' import bcrypt from 'bcryptjs'
export async function hashPassword(password: string): Promise<string> { export async function hashPassword(password: string): Promise<string> {
const salt = await bcrypt.genSalt(12)
return await bcrypt.hash(password, 12) return await bcrypt.hash(password, 12)
} }

View File

@ -0,0 +1,403 @@
{
"SchemaVersion": 2,
"CreatedAt": "2025-08-18T15:58:35.089280383Z",
"ArtifactName": "sipintar-app",
"ArtifactType": "container_image",
"Metadata": {
"Size": 1139341312,
"OS": {
"Family": "alpine",
"Name": "3.22.1"
},
"ImageID": "sha256:4422c1774f227fddf9fa7eb97a50bfbd03ac96ca2060d64c918486d8d3c70fb6",
"DiffIDs": [
"sha256:418dccb7d85a63a6aa574439840f7a6fa6fd2321b3e2394568a317735e867d35",
"sha256:54e9a650f7b7eb822819549a555f1da682a949a2f834ee90538cdcf2c5b4e72c",
"sha256:2e12e022f9bc7fa1e7abcaaa1ca88eed4ec895ff88a92da70f4fc79360e22600",
"sha256:eadc3b779d42558c703232696a3b9f95793b1aff49f10b11991712a7710460f1",
"sha256:54f04cfbae253965e994b8b7afbf8d925ff78a4d9782dc8beea35eedd5a97146",
"sha256:52de82b62fcee570f16bd4a4cace3a61a9a2c40e01c16ca020a53f77542529cd",
"sha256:cedd4988c45e525dae0c0126cc5f31a60307e5b2c4c58dde3e22d408ee6ddfcc",
"sha256:84216d29d7b76773d49638b5b51c8d8b19fa99088aa7dc93b048e335bcbe777f",
"sha256:498f30cdf8d028e8584de14df30886e071ef725a05e6eedd1408f4dc610e6886",
"sha256:0d241dc8aff74030e8c1293f46143cd369ee252712b605f2ed7fbdc43fa0e5a7",
"sha256:2fa6215ab739c975fdfb47cd629833d744397135088f968ca4ac97998f87ecb9",
"sha256:de4d3153fae86c6cac0e472b54585fb9ea675ce0e9b0d4865d8e6754a26d5668",
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
],
"RepoTags": [
"adelyao/sipintar-app:latest",
"sipintar-app:latest"
],
"RepoDigests": [
"adelyao/sipintar-app@sha256:4422c1774f227fddf9fa7eb97a50bfbd03ac96ca2060d64c918486d8d3c70fb6",
"sipintar-app@sha256:4422c1774f227fddf9fa7eb97a50bfbd03ac96ca2060d64c918486d8d3c70fb6"
],
"ImageConfig": {
"architecture": "amd64",
"created": "2025-08-18T09:26:53.256765583Z",
"history": [
{
"created": "2025-07-15T11:01:16Z",
"created_by": "ADD alpine-minirootfs-3.22.1-x86_64.tar.gz / # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-07-15T11:01:16Z",
"created_by": "CMD [\"/bin/sh\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "ENV NODE_VERSION=20.19.4",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "RUN /bin/sh -c addgroup -g 1000 node \u0026\u0026 adduser -u 1000 -G node -s /bin/sh -D node \u0026\u0026 apk add --no-cache libstdc++ \u0026\u0026 apk add --no-cache --virtual .build-deps curl \u0026\u0026 ARCH= OPENSSL_ARCH='linux*' \u0026\u0026 alpineArch=\"$(apk --print-arch)\" \u0026\u0026 case \"${alpineArch##*-}\" in x86_64) ARCH='x64' CHECKSUM=\"8a4633a9f8101de6870f7d4e5ceb3aa83d3c6cd7c11ad91cd902ea223b8c55fe\" OPENSSL_ARCH=linux-x86_64;; x86) OPENSSL_ARCH=linux-elf;; aarch64) OPENSSL_ARCH=linux-aarch64;; arm*) OPENSSL_ARCH=linux-armv4;; ppc64le) OPENSSL_ARCH=linux-ppc64le;; s390x) OPENSSL_ARCH=linux-s390x;; *) ;; esac \u0026\u0026 if [ -n \"${CHECKSUM}\" ]; then set -eu; curl -fsSLO --compressed \"https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\"; echo \"$CHECKSUM node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\" | sha256sum -c - \u0026\u0026 tar -xJf \"node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\" -C /usr/local --strip-components=1 --no-same-owner \u0026\u0026 ln -s /usr/local/bin/node /usr/local/bin/nodejs; else echo \"Building from source\" \u0026\u0026 apk add --no-cache --virtual .build-deps-full binutils-gold g++ gcc gnupg libgcc linux-headers make python3 py-setuptools \u0026\u0026 export GNUPGHOME=\"$(mktemp -d)\" \u0026\u0026 for key in C0D6248439F1D5604AAFFB4021D900FFDB233756 DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 CC68F5A3106FF448322E48ED27F5E38D5B0A215F 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C 108F52B48DB57BB0CC439B2997B01419BD92F80A A363A499291CBBC940DD62E41F10027AF002F8B0 ; do { gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$key\" \u0026\u0026 gpg --batch --fingerprint \"$key\"; } || { gpg --batch --keyserver keyserver.ubuntu.com --recv-keys \"$key\" \u0026\u0026 gpg --batch --fingerprint \"$key\"; } ; done \u0026\u0026 curl -fsSLO --compressed \"https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz\" \u0026\u0026 curl -fsSLO --compressed \"https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc\" \u0026\u0026 gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \u0026\u0026 gpgconf --kill all \u0026\u0026 rm -rf \"$GNUPGHOME\" \u0026\u0026 grep \" node-v$NODE_VERSION.tar.xz\\$\" SHASUMS256.txt | sha256sum -c - \u0026\u0026 tar -xf \"node-v$NODE_VERSION.tar.xz\" \u0026\u0026 cd \"node-v$NODE_VERSION\" \u0026\u0026 ./configure \u0026\u0026 make -j$(getconf _NPROCESSORS_ONLN) V= \u0026\u0026 make install \u0026\u0026 apk del .build-deps-full \u0026\u0026 cd .. \u0026\u0026 rm -Rf \"node-v$NODE_VERSION\" \u0026\u0026 rm \"node-v$NODE_VERSION.tar.xz\" SHASUMS256.txt.asc SHASUMS256.txt; fi \u0026\u0026 rm -f \"node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\" \u0026\u0026 find /usr/local/include/node/openssl/archs -mindepth 1 -maxdepth 1 ! -name \"$OPENSSL_ARCH\" -exec rm -rf {} \\; \u0026\u0026 apk del .build-deps \u0026\u0026 node --version \u0026\u0026 npm --version \u0026\u0026 rm -rf /tmp/* # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "ENV YARN_VERSION=1.22.22",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "RUN /bin/sh -c apk add --no-cache --virtual .build-deps-yarn curl gnupg tar \u0026\u0026 export GNUPGHOME=\"$(mktemp -d)\" \u0026\u0026 for key in 6A010C5166006599AA17F08146C2130DFD2497F5 ; do { gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$key\" \u0026\u0026 gpg --batch --fingerprint \"$key\"; } || { gpg --batch --keyserver keyserver.ubuntu.com --recv-keys \"$key\" \u0026\u0026 gpg --batch --fingerprint \"$key\"; } ; done \u0026\u0026 curl -fsSLO --compressed \"https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz\" \u0026\u0026 curl -fsSLO --compressed \"https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc\" \u0026\u0026 gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \u0026\u0026 gpgconf --kill all \u0026\u0026 rm -rf \"$GNUPGHOME\" \u0026\u0026 mkdir -p /opt \u0026\u0026 tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \u0026\u0026 ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \u0026\u0026 ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \u0026\u0026 rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \u0026\u0026 apk del .build-deps-yarn \u0026\u0026 yarn --version \u0026\u0026 rm -rf /tmp/* # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "COPY docker-entrypoint.sh /usr/local/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "ENTRYPOINT [\"docker-entrypoint.sh\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-07-15T23:35:30Z",
"created_by": "CMD [\"node\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-08-13T01:47:32Z",
"created_by": "WORKDIR /app",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-17T02:45:33Z",
"created_by": "RUN /bin/sh -c addgroup -S appgroup \u0026\u0026 adduser -S appuser -G appgroup # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:20:22Z",
"created_by": "COPY package*.json ./ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:42Z",
"created_by": "COPY /app/.next ./.next # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:42Z",
"created_by": "COPY /app/public ./public # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:42Z",
"created_by": "COPY /app/prisma ./prisma # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:47Z",
"created_by": "COPY /app/node_modules ./node_modules # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:47Z",
"created_by": "COPY /app/src ./src # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:53Z",
"created_by": "COPY --chown=appuser:appgroup /app/node_modules ./node_modules # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2025-08-18T09:26:53Z",
"created_by": "ENV NODE_ENV=production",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-08-18T09:26:53Z",
"created_by": "EXPOSE map[3000/tcp:{}]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-08-18T09:26:53Z",
"created_by": "USER appuser",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2025-08-18T09:26:53Z",
"created_by": "CMD [\"npm\" \"run\" \"start\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:418dccb7d85a63a6aa574439840f7a6fa6fd2321b3e2394568a317735e867d35",
"sha256:54e9a650f7b7eb822819549a555f1da682a949a2f834ee90538cdcf2c5b4e72c",
"sha256:2e12e022f9bc7fa1e7abcaaa1ca88eed4ec895ff88a92da70f4fc79360e22600",
"sha256:eadc3b779d42558c703232696a3b9f95793b1aff49f10b11991712a7710460f1",
"sha256:54f04cfbae253965e994b8b7afbf8d925ff78a4d9782dc8beea35eedd5a97146",
"sha256:52de82b62fcee570f16bd4a4cace3a61a9a2c40e01c16ca020a53f77542529cd",
"sha256:cedd4988c45e525dae0c0126cc5f31a60307e5b2c4c58dde3e22d408ee6ddfcc",
"sha256:84216d29d7b76773d49638b5b51c8d8b19fa99088aa7dc93b048e335bcbe777f",
"sha256:498f30cdf8d028e8584de14df30886e071ef725a05e6eedd1408f4dc610e6886",
"sha256:0d241dc8aff74030e8c1293f46143cd369ee252712b605f2ed7fbdc43fa0e5a7",
"sha256:2fa6215ab739c975fdfb47cd629833d744397135088f968ca4ac97998f87ecb9",
"sha256:de4d3153fae86c6cac0e472b54585fb9ea675ce0e9b0d4865d8e6754a26d5668",
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
]
},
"config": {
"Cmd": [
"npm",
"run",
"start"
],
"Entrypoint": [
"docker-entrypoint.sh"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NODE_VERSION=20.19.4",
"YARN_VERSION=1.22.22",
"NODE_ENV=production"
],
"User": "appuser",
"WorkingDir": "/app",
"ExposedPorts": {
"3000/tcp": {}
},
"ArgsEscaped": true
}
},
"Layers": [
{
"Size": 8596480,
"Digest": "sha256:9824c27679d3b27c5e1cb00a73adb6f4f8d556994111c12db3c5d61a0c843df8",
"DiffID": "sha256:418dccb7d85a63a6aa574439840f7a6fa6fd2321b3e2394568a317735e867d35"
},
{
"Size": 123036672,
"Digest": "sha256:8c59d92d6fc9f01af4aaa86824be72b74bd4d940c4c46aa95d9710bfa46c975e",
"DiffID": "sha256:54e9a650f7b7eb822819549a555f1da682a949a2f834ee90538cdcf2c5b4e72c"
},
{
"Size": 5389824,
"Digest": "sha256:54225bd601967a0aa669ec9be621c24d8eeac874b698d55874018070898685c2",
"DiffID": "sha256:2e12e022f9bc7fa1e7abcaaa1ca88eed4ec895ff88a92da70f4fc79360e22600"
},
{
"Size": 3584,
"Digest": "sha256:a9e48ad1219d4d11c6456a8db0fd5c11af46242d52edf84e17ab84a7bfd93809",
"DiffID": "sha256:eadc3b779d42558c703232696a3b9f95793b1aff49f10b11991712a7710460f1"
},
{
"Size": 1536,
"Digest": "sha256:0acc2a2bdf69d278947470113f79bc624dcc672a328ccf41657d1093ea7ac237",
"DiffID": "sha256:54f04cfbae253965e994b8b7afbf8d925ff78a4d9782dc8beea35eedd5a97146"
},
{
"Size": 10752,
"Digest": "sha256:4ce2fe5b490be14137c39d7a05adddb6e9712317a651a0ba1a09170ac48bfd77",
"DiffID": "sha256:52de82b62fcee570f16bd4a4cace3a61a9a2c40e01c16ca020a53f77542529cd"
},
{
"Size": 319488,
"Digest": "sha256:82027a5441a2188d23f508670e0b65191f8da4ff49120f4c902b265bd7d3c25f",
"DiffID": "sha256:cedd4988c45e525dae0c0126cc5f31a60307e5b2c4c58dde3e22d408ee6ddfcc"
},
{
"Size": 134096896,
"Digest": "sha256:303f9011b20d7dc5150807034500a70a22707109da269ca736c290e4b9c22a7c",
"DiffID": "sha256:84216d29d7b76773d49638b5b51c8d8b19fa99088aa7dc93b048e335bcbe777f"
},
{
"Size": 1474048,
"Digest": "sha256:ca4a39f0cf921046127ac9362d111e627f1551d9bf6806ca6668f8468392a87d",
"DiffID": "sha256:498f30cdf8d028e8584de14df30886e071ef725a05e6eedd1408f4dc610e6886"
},
{
"Size": 18432,
"Digest": "sha256:cac1fc27c7c00da22f9fadef43ae0f6f03235af5c62f115f77004d5ac7b5078d",
"DiffID": "sha256:0d241dc8aff74030e8c1293f46143cd369ee252712b605f2ed7fbdc43fa0e5a7"
},
{
"Size": 866106368,
"Digest": "sha256:cfad1940bb9c092c84218657f55c636bb12b5a841a361271f6ea47cea28cc44f",
"DiffID": "sha256:2fa6215ab739c975fdfb47cd629833d744397135088f968ca4ac97998f87ecb9"
},
{
"Size": 286208,
"Digest": "sha256:f3fb51f92f7844fb809251866d6af9c1cfc1d888c3d807ce966d329ad7155d45",
"DiffID": "sha256:de4d3153fae86c6cac0e472b54585fb9ea675ce0e9b0d4865d8e6754a26d5668"
},
{
"Size": 1024,
"Digest": "sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1",
"DiffID": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
}
]
},
"Results": [
{
"Target": "sipintar-app (alpine 3.22.1)",
"Class": "os-pkgs",
"Type": "alpine"
},
{
"Target": "Node.js",
"Class": "lang-pkgs",
"Type": "node-pkg",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2024-21538",
"PkgID": "cross-spawn@7.0.3",
"PkgName": "cross-spawn",
"PkgPath": "usr/local/lib/node_modules/npm/node_modules/cross-spawn/package.json",
"PkgIdentifier": {
"PURL": "pkg:npm/cross-spawn@7.0.3",
"UID": "480da04347e2e299"
},
"InstalledVersion": "7.0.3",
"FixedVersion": "7.0.5, 6.0.6",
"Status": "fixed",
"Layer": {
"Digest": "sha256:8c59d92d6fc9f01af4aaa86824be72b74bd4d940c4c46aa95d9710bfa46c975e",
"DiffID": "sha256:54e9a650f7b7eb822819549a555f1da682a949a2f834ee90538cdcf2c5b4e72c"
},
"SeveritySource": "ghsa",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2024-21538",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory npm",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm"
},
"Title": "cross-spawn: regular expression denial of service",
"Description": "Versions of the package cross-spawn before 6.0.6, from 7.0.0 and before 7.0.5 are vulnerable to Regular Expression Denial of Service (ReDoS) due to improper input sanitization. An attacker can increase the CPU usage and crash the program by crafting a very large and well crafted string.",
"Severity": "HIGH",
"CweIDs": [
"CWE-1333"
],
"VendorSeverity": {
"amazon": 2,
"azure": 3,
"cbl-mariner": 3,
"ghsa": 3,
"redhat": 1
},
"CVSS": {
"ghsa": {
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"V3Score": 7.5
},
"redhat": {
"V3Vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:N/I:N/A:H",
"V3Score": 4.4
}
},
"References": [
"https://access.redhat.com/security/cve/CVE-2024-21538",
"https://github.com/moxystudio/node-cross-spawn",
"https://github.com/moxystudio/node-cross-spawn/commit/5ff3a07d9add449021d806e45c4168203aa833ff",
"https://github.com/moxystudio/node-cross-spawn/commit/640d391fde65388548601d95abedccc12943374f",
"https://github.com/moxystudio/node-cross-spawn/commit/d35c865b877d2f9ded7c1ed87521c2fdb689c8dd",
"https://github.com/moxystudio/node-cross-spawn/issues/165",
"https://github.com/moxystudio/node-cross-spawn/pull/160",
"https://nvd.nist.gov/vuln/detail/CVE-2024-21538",
"https://security.snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-8366349",
"https://security.snyk.io/vuln/SNYK-JS-CROSSSPAWN-8303230",
"https://www.cve.org/CVERecord?id=CVE-2024-21538"
],
"PublishedDate": "2024-11-08T05:15:06.453Z",
"LastModifiedDate": "2025-05-20T15:16:03.53Z"
}
]
},
{
"Target": "app/node_modules/.pnpm/@esbuild+linux-x64@0.25.8/node_modules/@esbuild/linux-x64/bin/esbuild",
"Class": "lang-pkgs",
"Type": "gobinary",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2025-47907",
"PkgID": "stdlib@v1.23.10",
"PkgName": "stdlib",
"PkgIdentifier": {
"PURL": "pkg:golang/stdlib@v1.23.10",
"UID": "195c06e8a44e6ede"
},
"InstalledVersion": "v1.23.10",
"FixedVersion": "1.23.12, 1.24.6",
"Status": "fixed",
"Layer": {
"Digest": "sha256:cfad1940bb9c092c84218657f55c636bb12b5a841a361271f6ea47cea28cc44f",
"DiffID": "sha256:2fa6215ab739c975fdfb47cd629833d744397135088f968ca4ac97998f87ecb9"
},
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2025-47907",
"DataSource": {
"ID": "govulndb",
"Name": "The Go Vulnerability Database",
"URL": "https://pkg.go.dev/vuln/"
},
"Title": "database/sql: Postgres Scan Race Condition",
"Description": "Cancelling a query (e.g. by cancelling the context passed to one of the query methods) during a call to the Scan method of the returned Rows can result in unexpected results if other queries are being made in parallel. This can result in a race condition that may overwrite the expected results with those of another query, causing the call to Scan to return either unexpected results from the other query or an error.",
"Severity": "HIGH",
"VendorSeverity": {
"bitnami": 3,
"redhat": 3
},
"CVSS": {
"bitnami": {
"V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L",
"V3Score": 7
},
"redhat": {
"V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L",
"V3Score": 7
}
},
"References": [
"https://access.redhat.com/security/cve/CVE-2025-47907",
"https://go.dev/cl/693735",
"https://go.dev/issue/74831",
"https://groups.google.com/g/golang-announce/c/x5MKroML2yM",
"https://nvd.nist.gov/vuln/detail/CVE-2025-47907",
"https://pkg.go.dev/vuln/GO-2025-3849",
"https://www.cve.org/CVERecord?id=CVE-2025-47907"
],
"PublishedDate": "2025-08-07T16:15:30.357Z",
"LastModifiedDate": "2025-08-07T21:26:37.453Z"
}
]
}
]
}