diff --git a/.dockerignore b/.dockerignore index 76f8732..5567664 100644 --- a/.dockerignore +++ b/.dockerignore @@ -41,3 +41,6 @@ yarn-error.log* next-env.d.ts /src/generated/prisma + +# secrets +/secrets/ \ No newline at end of file diff --git a/.env b/.env index 01696b9..9dc9bb6 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -# DATABASE_URL="mysql://sipintar_user:sipintar_password123:@db:3306/sipintar_school" -DATABASE_URL="mysql://root:root123@sipintar-mysql:3306/sipintar_school" +DATABASE_URL="mysql://sipintar_user:sipintar_password123:@db:3306/sipintar_school" +# DATABASE_URL="mysql://root:root123@sipintar-mysql:3306/sipintar_school" NEXTAUTH_SECRET="your-secret-key-here-change-this-in-production" NEXTAUTH_URL="http://localhost:3000" \ No newline at end of file diff --git a/.gitignore b/.gitignore index b5374a7..5f1dc02 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ yarn-error.log* next-env.d.ts /src/generated/prisma + +#secrets +/secrets/ \ No newline at end of file diff --git a/Dockerfile.prod b/Dockerfile.prod index 1964e15..b088adc 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,7 +1,14 @@ # Build stage FROM node:20-alpine AS builder + +#buat user baru untuk security setup +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + WORKDIR /app +# change ownership untuk user baru +RUN chown -R appuser:appgroup /app + COPY package.json pnpm-lock.yaml ./ RUN npm install -g pnpm RUN pnpm install --frozen-lockfile @@ -9,15 +16,27 @@ RUN pnpm install --frozen-lockfile COPY . . RUN npx prisma generate RUN pnpm run build +RUN chown -R appuser:appgroup /app/node_modules # Production stage FROM node:20-alpine AS runner WORKDIR /app + +#buat user di runner stage +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + COPY package*.json ./ COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./public COPY --from=builder /app/prisma ./prisma 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 EXPOSE 3000 + +#ganti user jadi non root +USER appuser + CMD ["npm", "run", "start"] diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 8bfd7b4..ee78b8a 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -1,71 +1,109 @@ version: '3.8' services: app: - build: - context: . - dockerfile: Dockerfile.prod - container_name: sipintar-app - restart: unless-stopped + image: adelyao/sipintar-app:latest working_dir: /app ports: - "3000:3000" - environment: - NODE_ENV: production - DATABASE_URL: mysql://sipintar_user:sipintar_password123@db:3306/sipintar_school + # environment: + # # DATABASE_URL: /run/secrets/db_url + # # DATABASE_URL_FILE: /run/secrets/db_url + # DATABASE_URL: "mysql://sipintar_user:$$(cat /run/secrets/db_password)@sipintar_mysql:3306/sipintar_school" depends_on: - db: - condition: service_healthy - # volumes: - # - .:/app - # - /app/node_modules - # - /app/.next + - db networks: - - sipintar-network - command: ["npm", "run", "start"] + - sipintar-overlay + 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 - - db: + sipintar_mysql: image: mysql:5.7 - container_name: sipintar-mysql - restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root123} - MYSQL_DATABASE: ${MYSQL_DATABASE:-sipintar_school} - MYSQL_USER: ${MYSQL_USER:-sipintar_user} - MYSQL_PASSWORD: ${MYSQL_PASSWORD:-sipintar_password123} - ports: - - '3307:3306' + MYSQL_DATABASE: sipintar_school + MYSQL_USER: sipintar_user + MYSQL_PASSWORD_FILE: /run/secrets/db_password + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password volumes: - mysql_data:/var/lib/mysql - ./setup-database.sql:/docker-entrypoint-initdb.d/setup-database.sql networks: - - sipintar-network + - sipintar-overlay healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot123"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p$$(cat /run/secrets/db_root_password)"] + interval: 30s + timeout: 10s + retries: 10 + 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: - context: . - dockerfile: Dockerfile.prod - container_name: sipintar-seed - restart: "no" + + scanner: + image: aquasec/trivy:latest working_dir: /app environment: - NODE_ENV: production - DATABASE_URL: mysql://sipintar_user:sipintar_password123@db:3306/sipintar_school - depends_on: - db: - condition: service_healthy - command: ["npm", "run", "db:seed"] + TRIVY_SEVERITY: "CRITICAL,HIGH" + TRIVY_IGNORE_UNFIXED: "true" + TRIVY_OUTPUT: "/app/trivy-report.json" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./trivy-results:/tmp/trivy-results + command: ["image", "-q", "--format", "json", "--severity", "CRITICAL,HIGH", "app", "--output", "/tmp/trivy-results/trivy-report.json"] 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: mysql_data: + networks: - sipintar-network: - driver: bridge + sipintar-overlay: + 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 diff --git a/monitoring/prometheus/prometheus.yml b/monitoring/prometheus/prometheus.yml new file mode 100644 index 0000000..2aef66d --- /dev/null +++ b/monitoring/prometheus/prometheus.yml @@ -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 \ No newline at end of file diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 900f1e4..caa278a 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,6 +1,7 @@ import bcrypt from 'bcryptjs' export async function hashPassword(password: string): Promise { + const salt = await bcrypt.genSalt(12) return await bcrypt.hash(password, 12) } diff --git a/trivy-results/trivy-report.json b/trivy-results/trivy-report.json new file mode 100644 index 0000000..d7325ff --- /dev/null +++ b/trivy-results/trivy-report.json @@ -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" + } + ] + } + ] +}