DDSS: 단계별 설명

발행: (2026년 1월 8일 오전 02:12 GMT+9)
12 min read
원문: Dev.to

Source: Dev.to

중요 안전 주의 – 이 가이드는 오직 로컬 머신에서 학습용입니다.
취약한 코드를 인터넷에 노출하지 마세요.

1️⃣ 사전 요구 사항

필요한 것필요한 이유
Docker가 설치된 컴퓨터Docker는 앱과 데이터베이스를 격리된 컨테이너에서 실행합니다.
Python 3.x (Python 패키지를 로컬에 설치하려는 경우)Flask 코드와 pip 명령어에 필요합니다.
터미널 / 명령 프롬프트가이드에 표시된 명령을 실행하기 위해.

Docker가 아직 설치되지 않았다면, docker.com 에서 다운로드하고 운영 체제에 맞는 설치 안내를 따르세요.

설치를 테스트해 보세요:

docker --version

다음과 같은 형태로 Docker 버전이 표시됩니다 Docker version 24.0.5, build abcdefg.

2️⃣ 프로젝트 파일 받기

  1. Download (다운로드) 하라는 ZIP 아카이브를 받습니다 (ddss-2025-assignment2-rc-main-2.zip 파일).
  2. Unzip (압축 해제) 합니다:
OSHow to unzip
WindowsZIP 파일을 오른쪽 클릭 → Extract All…
macOSZIP 파일을 더블 클릭 (자동으로 압축이 해제됩니다).
Linux터미널을 열고 unzip ddss-2025-assignment2-rc-main-2.zip 명령을 실행합니다.

압축을 풀면 (예: ddss-2025-assignment2-rc-main-2) 다음과 같은 폴더가 생성됩니다:

  • Python 소스 파일 (app.py 등)
  • Docker 관련 파일 (Dockerfile, docker-compose.yml, docker-compose-python-psql.sh)
  • 기타 자산 (템플릿, 정적 파일, README 등)

3️⃣ Docker 시작

  1. Docker Desktop을 엽니다 (또는 Docker 데몬을 실행합니다).
  2. 실행 중인지 확인합니다 – 작업 표시줄 / 메뉴 막대에 Docker 고래 아이콘이 표시되어야 합니다.

4️⃣ 터미널 / 명령 프롬프트 열기

플랫폼열기 방법
WindowsCommand Prompt(또는 PowerShell)를 검색합니다.
macOSTerminal을 엽니다 (⌘ Space → “Terminal”).
Linux선호하는 터미널 에뮬레이터를 엽니다.

5️⃣ 프로젝트 폴더로 이동

cd ~/Downloads               # 또는 ZIP 파일을 저장한 위치
cd ddss-2025-assignment2-rc-main-2

“No such file or directory”(해당 파일이나 디렉터리가 없습니다) 오류가 발생하면, 내용물을 확인하세요(macOS/Linux에서는 ls, Windows에서는 dir` 사용) 그리고 폴더 이름을 알맞게 수정하십시오.

6️⃣ 필요한 Python 패키지 설치

pip install flask psycopg2-binary werkzeug bandit
패키지기능 설명
flaskPython용 최소 웹 프레임워크.
psycopg2‑binaryPython용 PostgreSQL 드라이버.
werkzeugFlask에서 사용하는 유틸리티 라이브러리.
bandit정적 보안 분석기 (선택 사항이지만 유용함).

격리된 환경을 선호한다면, 먼저 virtualenv를 생성하세요 (python -m venv venv && source venv/bin/activate).

7️⃣ Docker 컨테이너 빌드 및 시작

프로젝트에는 Docker Compose를 실행하는 도우미 스크립트가 포함되어 있습니다.

# 스크립트를 실행 가능하게 만들기 (첫 번째 실행 시에만 필요)
chmod +x docker-compose-python-psql.sh

# 실행
./docker-compose-python-psql.sh

무슨 일이 일어나나요

  • Docker Compose가 두 개의 컨테이너를 빌드합니다:
    1. Python/Flask 애플리케이션 (web).
    2. PostgreSQL 데이터베이스 (db).
  • 이미지가 Docker Hub에서 풀됩니다 (몇 분 정도 걸릴 수 있습니다).
  • 스크립트가 완료되면 “finished building”와 같은 메시지가 표시됩니다.

8️⃣ (Optional) DB 컨테이너 안에서 psql 셸 열기

두 번째 터미널 탭/창을 열고 다음을 실행합니다:

docker exec -it db psql -U ddss-database-assignment-2 -d ddss-database-assignment-2

PostgreSQL 프롬프트에 들어갑니다:

ddss-database-assignment-2=#

\q 로 종료합니다.
테이블을 확인하거나 디버깅할 때 유용합니다.

9️⃣ 웹 애플리케이션에 접근하기

ActionURL
홈 페이지 열기http://localhost:8080
새 사용자 등록http://localhost:8080/register

모던 브라우저(Chrome, Firefox, Edge, Safari)를 사용하세요.

  1. 등록 일반 계정을 만듭니다(원하는 사용자명/비밀번호 선택).
  2. 이제 로그인하여 과제의 다양한 부분을 탐색할 수 있습니다.

🔟 취약점 시연

10.1 SQL Injection (취약 버전)

  1. 로그인 페이지로 이동합니다(보통 /login 또는 /part1).
  2. 다음 값을 입력합니다:
필드페이로드
사용자 이름' OR '1'='1' --
비밀번호아무 것이나(예: blah)
  1. Login 버튼을 클릭합니다.

결과: “VULNERABLE LOGIN SUCCESS” 와 같은 메시지가 표시됩니다.

동작 원리
앱은 다음과 유사한 쿼리를 생성합니다:

SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = 'blah';
  • OR '1'='1' 은 항상 참입니다.
  • -- 은 나머지 라인을 주석 처리하여 비밀번호 검사를 제거합니다.
  • 쿼리가 행을 반환하므로 유효한 자격 증명 없이 로그인에 성공합니다.

10.2 SQL Injection (보안 버전)

  1. 동일한 페이로드를 보안 로그인 폼에 사용합니다(보통 /secure-login 또는 다른 경로).
  2. 이제 앱은 파라미터화된 쿼리(prepared statements)를 사용하므로 입력값이 코드가 아니라 데이터로 처리됩니다.

결과: **“Invalid credentials”(또는 유사한) 메시지가 표시됩니다 – 인젝션이 실패합니다.

📚 배운 내용

개념가이드에서 나타난 방식
Docker containersFlask 앱과 PostgreSQL 데이터베이스를 격리합니다.
Flask취약한 앱에 사용된 최소한의 Python 웹 프레임워크입니다.
SQL injection로그인 폼에 ' OR '1'='1' -- 를 삽입하여 시연했습니다.
Parameterised queries삽입을 차단하는 해결책입니다.
XSS (cross‑site scripting)(발췌본에는 포함되지 않았지만 과제의 일부입니다.)
BanditPython 코드의 보안 문제를 스캔하는 도구입니다.

✅ 다음 단계

  1. Run Bandit on the source code to see what it flags:

    bandit -r .
  2. Fix the XSS vulnerability (look for places where user input is rendered without escaping).

  3. Write a short report describing each vulnerability, how you exploited it, and how you mitigated it.

Good luck, and remember: always test security flaws offline and never expose vulnerable code to the public internet!

로그인 실패 설명

Message: LOGIN FAILED.

Why?
보안 버전은 prepared statements를 사용하여 SQL 인젝션을 방지합니다. 입력값은 실행 가능한 코드가 아니라 데이터로 처리됩니다.

Source:

Step 11 – Test Part 2: Session Authorization & More

1. Not Logged In

  • /part2.html/part3.html에 접근해 보세요.
  • 기대 동작: /part1.html(로그인 필요)으로 리디렉션되어야 합니다.

2. Logged In (Secure Way)

  1. secure 로그인 폼을 통해 정상적으로 로그인합니다.
  2. 그 후 /part2.html/part3.html에 접근하면 정상적으로 로드됩니다.

Why?
취약한 로그인으로 들어가더라도, 애플리케이션은 세션(예: 쿠키)을 사용해 인증 상태를 추적합니다. 유효한 세션 없이는 보호된 페이지에 접근할 수 없습니다.

XSS (Cross‑Site Scripting) 시연

취약한 폼

  1. 메시지 폼(아마 /part2 경로)에서 다음 페이로드를 제출합니다:

    alert('XSS')
  2. 페이지를 새로 고칩니다.

결과: 알림 팝업이 표시됩니다.

이유:
앱이 원시 스크립트를 데이터베이스에 그대로 저장하고, 이스케이프 없이 렌더링하기 때문에 브라우저가 JavaScript로 실행합니다.

보안된 폼

  1. 동일한 페이로드(alert('XSS'))를 제출합니다.
  2. 페이지를 새로 고칩니다.

결과: 팝업이 나타나지 않으며, 스크립트가 일반 텍스트로 표시됩니다.

이유:
보안 버전은 출력 시 이스케이프를 수행합니다(예: Flask의 Jinja 자동 이스케이프 사용). <&lt;와 같이 변환해 스크립트를 무해하게 만듭니다.

메시지 목록

가이드에는 예시 메시지가 표시됩니다. 귀하의 메시지는 다를 수 있지만, 동작(실행 vs. 이스케이프)은 동일해야 합니다.


보고서 요약 표

다음 마크다운 표를 과제 보고서에 복사하십시오:

버전취약점결과
취약저장된 XSSJS 실행
안전이스케이프된 출력안전한 표시

이제 SQL injection(로그인 및 데이터 접근을 위한)과 XSS를 시연했으며, 그에 대한 완화 방안도 포함되었습니다.

SQL Injection Demonstration (Books Query)

Vulnerable Query

  1. In the insecure form (look for “price more than”), enter:

    0 OR 1=1 --
  2. Submit the form.

Result: All books are listed.

Why?
The injection tricks the SQL engine into ignoring the price condition, returning every row (similar to a login bypass).

Secure Query

  • Use the same input (0 OR 1=1 --).
  • Expected behavior: no books are returned or the query fails safely.

Why?
Parameterized (prepared) statements prevent the injection from altering the query logic.

최종 팁

  • 문제 해결: 무언가 실패하면 터미널에서 오류를 확인하세요. docker-compose down으로 Docker를 재시작한 뒤 설정 스크립트를 다시 실행합니다.
  • 학습 포인트: 이 연습은 웹 애플리케이션에서 입력 검증, 준비된 문장, 출력 이스케이프가 왜 중요한지를 보여줍니다.
  • 보고서 안내: 성공 및 실패 시도의 스크린샷을 캡처하고, 위와 같이 각 단계를 설명하며 요약 표를 포함합니다.
  • 정리: 작업이 끝나면 프로젝트 폴더에서 docker-compose down 명령으로 Docker 컨테이너를 중지합니다.

단계가 명확하지 않다면 해당 부분에 대해 자유롭게 질문하세요. 할 수 있어요—컴퓨터 과학은 실험하는 것이 전부입니다! 🚀

Back to Blog

관련 글

더 보기 »