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
34 changes: 34 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CD

on:
workflow_run:
workflows: [ "CI" ]
types:
- completed
branches:
- main

jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Login to DockerHub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

- name: Extract Docker image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: dungbik/flipnote-reaction
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: ./gradlew build -x test

- name: Run tests
run: ./gradlew test

dependency-check:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run dependency check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'FlipNote-Reaction'
path: '.'
format: 'HTML'
Comment on lines +44 to +49
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub action security best practices pinning commit SHA version tags

💡 Result:

GitHub Actions security best practices for version pinning (commit SHA vs tags)

  • Prefer pinning every third‑party action to a full, immutable commit SHA (40 chars) rather than a branch or tag, to reduce supply‑chain risk (tags can be moved). Example:
    uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7  [1][2]
  • Pin SHAs that correspond to a published release/tag, and add a comment with the human version (e.g., # v4.1.7) to keep workflows readable and updateable. [2]
  • Verify the SHA is from the action’s official repository (not a fork) before pinning. [1]
  • Keep pinned SHAs updated with automation (e.g., Dependabot “version updates” for Actions) so you don’t trade supply‑chain risk for stale dependencies. [2]
  • Enforce SHA pinning via policy (org/repo/enterprise settings) so unpinned workflows can’t be introduced. [1][3]
  • Audit third‑party actions you rely on (especially those that touch secrets or repo contents). [1]

Sources

[1] GitHub Docs — Security hardening for GitHub Actions (docs.github.com)
[2] GitHub Well-Architected — Securing GitHub Actions Workflows (wellarchitected.github.com)
[3] GitHub Changelog — Actions policy now supports … SHA pinning (github.blog)

Citations:


🌐 Web query:

dependency-check/Dependency-Check_Action releases tags GitHub

💡 Result:

dependency-check/Dependency-Check_Action has 2 releases/tags on GitHub:

  • 1.1.0 (“Added extra parameters”) — Apr 28, 2021 (latest) [1][2]
  • 1.0.0 (“Dependency Check Action - Initial version”) — Feb 28, 2021 [1][2]

You can view them here:

Sources: [1] https://github.com/dependency-check/Dependency-Check_Action/tags [2] https://github.com/dependency-check/Dependency-Check_Action/releases


🌐 Web query:

dependency-check/Dependency-Check_Action v1.1.0 commit SHA GitHub

💡 Result:

For dependency-check/Dependency-Check_Action v1.1.0 (tag 1.1.0), the commit SHA is:

75ba02d6183445fe0761d26e836bde58b1560600 [1][2]


🏁 Script executed:

#!/bin/bash
# Find the commit SHA for dependency-check/Dependency-Check_Action v1.1.0 release
# Using curl to query GitHub API
curl -s "https://api.github.com/repos/dependency-check/Dependency-Check_Action/releases/tags/1.1.0" | jq -r '.target_commitish' 2>/dev/null || echo "Check failed"

Repository: FlipNoteTeam/FlipNote-Reaction

Length of output: 78


dependency-check/Dependency-Check_Action을 @main으로 고정하면 공급망 위협 발생

@main은 브랜치 참조이므로 해당 액션 저장소의 변경이 즉시 워크플로우에 영향을 미칩니다. GitHub 보안 강화 가이드라인은 서드파티 액션을 특정 커밋 SHA로 고정할 것을 권장합니다.

해당 액션은 v1.1.0(최신 릴리스, 2021년 4월)이 존재합니다. 다음과 같이 릴리스 버전의 커밋 SHA로 고정하고 버전 주석을 추가하세요:

-        uses: dependency-check/Dependency-Check_Action@main
+        uses: dependency-check/Dependency-Check_Action@75ba02d6183445fe0761d26e836bde58b1560600 # v1.1.0

이렇게 하면 공급망 위협을 줄이면서도 어떤 릴리스 버전을 사용하고 있는지 명확하게 유지할 수 있습니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Run dependency check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'FlipNote-Reaction'
path: '.'
format: 'HTML'
- name: Run dependency check
uses: dependency-check/Dependency-Check_Action@75ba02d6183445fe0761d26e836bde58b1560600 # v1.1.0
with:
project: 'FlipNote-Reaction'
path: '.'
format: 'HTML'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 44 - 49, The workflow step named "Run
dependency check" currently pins the action as
dependency-check/Dependency-Check_Action@main which is a branch ref; change it
to the specific commit SHA for the v1.1.0 release (replace `@main` with
@<v1.1.0-commit-sha>) and add an inline comment indicating the release version
and SHA (e.g., "v1.1.0 - <commit-sha>") so the action is fixed to a known
release and the version is explicit.


- name: Upload dependency check report
uses: actions/upload-artifact@v4
if: always()
with:
name: dependency-check-report
path: reports/
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM gradle:8-jdk21 AS build
WORKDIR /app

COPY build.gradle.kts settings.gradle.kts ./
COPY src ./src

RUN gradle bootJar --no-daemon

FROM eclipse-temurin:21-jre
WORKDIR /app

ENV TZ=Asia/Seoul
RUN apt-get update \
&& apt-get install -y tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& rm -rf /var/lib/apt/lists/*
Comment on lines +13 to +17
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

apt-get install--no-install-recommends 플래그 누락

불필요한 권장 패키지가 함께 설치되어 이미지 크기가 커지고 공격 표면이 넓어집니다. (Trivy DS-0029)

🛡️ 제안하는 수정
 RUN apt-get update \
-    && apt-get install -y tzdata \
+    && apt-get install -y --no-install-recommends tzdata \
     && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
     && echo $TZ > /etc/timezone \
     && rm -rf /var/lib/apt/lists/*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN apt-get update \
&& apt-get install -y tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get install -y --no-install-recommends tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& rm -rf /var/lib/apt/lists/*
🧰 Tools
🪛 Trivy (0.69.1)

[error] 13-17: 'apt-get' missing '--no-install-recommends'

'--no-install-recommends' flag is missed: 'apt-get update && apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && rm -rf /var/lib/apt/lists/*'

Rule: DS-0029

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 13 - 17, The RUN instruction in the Dockerfile
installs tzdata without suppressing recommended packages; update the RUN line
that calls apt-get install -y tzdata to include the --no-install-recommends flag
so it becomes apt-get install -y --no-install-recommends tzdata (keep the
surrounding apt-get update, timezone symlink/echo and rm -rf
/var/lib/apt/lists/* steps intact) to avoid pulling unnecessary recommended
packages into the image.


COPY --from=build /app/build/libs/reaction-0.0.1-SNAPSHOT.jar .

EXPOSE 8083

ENTRYPOINT ["java", "-jar", "reaction-0.0.1-SNAPSHOT.jar"]
Comment on lines +9 to +23
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

컨테이너가 root 사용자로 실행됨 (보안 취약점)

USER 명령이 없어 런타임 컨테이너가 root 권한으로 실행됩니다. 컨테이너 탈출 시 호스트에 대한 root 접근이 가능해집니다. (Trivy DS-0002)

🔒 제안하는 수정 - 비루트 사용자 추가
 FROM eclipse-temurin:21-jre
 WORKDIR /app
 
 ENV TZ=Asia/Seoul
 RUN apt-get update \
     && apt-get install -y --no-install-recommends tzdata \
     && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
     && echo $TZ > /etc/timezone \
     && rm -rf /var/lib/apt/lists/*
 
+RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
+
 COPY --from=build /app/build/libs/reaction-0.0.1-SNAPSHOT.jar .
 
+USER appuser
+
 EXPOSE 8083
 
 ENTRYPOINT ["java", "-jar", "reaction-0.0.1-SNAPSHOT.jar"]
🧰 Tools
🪛 Trivy (0.69.1)

[error] 13-17: 'apt-get' missing '--no-install-recommends'

'--no-install-recommends' flag is missed: 'apt-get update && apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && rm -rf /var/lib/apt/lists/*'

Rule: DS-0029

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 9 - 23, The Dockerfile currently runs the image as
root; add a non-root user and switch to it before ENTRYPOINT to avoid running as
root (address DS-0002). In the Dockerfile create a user/group (e.g., appuser),
set ownership of the copied artifact (reaction-0.0.1-SNAPSHOT.jar) to that user
(chown), and add a USER appuser line so the ENTRYPOINT ["java", "-jar",
"reaction-0.0.1-SNAPSHOT.jar"] runs unprivileged; ensure any directories the app
needs (WORKDIR /app) are writable by that user.

Comment on lines +19 to +23
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

하드코딩된 SNAPSHOT JAR 이름으로 인한 버전 변경 시 빌드 실패

reaction-0.0.1-SNAPSHOT.jarCOPYENTRYPOINT 양쪽에 하드코딩되어 있어, build.gradle.kts에서 버전이나 아카이브명이 변경되면 Docker 빌드가 즉시 실패합니다. 와일드카드로 복사 후 고정 이름으로 변경하는 방식이 표준입니다.

🐛 제안하는 수정
-COPY --from=build /app/build/libs/reaction-0.0.1-SNAPSHOT.jar .
+COPY --from=build /app/build/libs/*.jar app.jar
 
 EXPOSE 8083
 
-ENTRYPOINT ["java", "-jar", "reaction-0.0.1-SNAPSHOT.jar"]
+ENTRYPOINT ["java", "-jar", "app.jar"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 19 - 23, The Dockerfile hardcodes
reaction-0.0.1-SNAPSHOT.jar in both COPY and ENTRYPOINT causing builds to break
on version changes; update the Dockerfile to COPY the built jar using a wildcard
(e.g., COPY --from=build /app/build/libs/*.jar /app/), capture the actual
filename into a Docker ARG/ENV or rename the copied jar to a stable name (e.g.,
reaction.jar) so ENTRYPOINT can reliably run java -jar reaction.jar; modify the
ENTRYPOINT to reference the stable name or the ARG (java -jar ${JAR_NAME}) and
ensure the build stage still outputs a single jar to avoid ambiguous wildcard
matches.