No description
  • PHP 66.2%
  • JavaScript 22.6%
  • CSS 11.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
hardline7 424c49b39a 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL)
바이브 코딩 워크숍의 해킹 타임 4개 시나리오가 반드시 재현되도록
취약점을 일부러 남겨둔 강사용 정답 소스입니다. 참가자 앱에서 취약점이
재현되지 않을 때 이 저장소로 실습을 진행할 수 있습니다.

구성:
- index.php: 목록/업로드/URL가져오기 화면
- db.php: DB 연결, 현재 사용자, JSON 응답 도우미
- switch_role.php: 역할 전환(Admin/Manager/Employee/Guest)
- api/files.php: 목록 조회 + 삭제
- api/upload.php: 업로드
- api/download.php: 다운로드
- api/fetch_url.php: URL 검사(취약/방어 비교)
- assets/app.js, assets/style.css: 화면 동작과 스타일
- schema.sql: 테이블 + 예시 파일 5개(public 2, internal 2, admin-only 1)

일부러 심은 취약점(모두 로컬에서 재현 검증 완료):
- A 프론트 권한 우회: 삭제 버튼을 display:none으로 숨기기만 하고
  서버 DELETE는 권한 미검사 → Employee가 admin-only 파일 삭제 확인
- B 숨긴 데이터 노출: 목록 API가 전체 파일을 내려주고 화면에서만 필터 →
  Employee 응답에 급여명세(admin-only) 그대로 포함 확인
- C XSS: 파일명/설명을 검증 없이 저장하고 innerHTML로 출력 →
  <img onerror> 페이로드 원본 저장 확인
- D SSRF: fetch_url.php의 취약한 검사는 내부 IP를 통과시키고,
  방어된 검사(check_safe)는 사설/루프백/링크로컬 차단 →
  커리큘럼 허용/차단 표 10건과 일치 확인

그 외 실습 후반부용으로 남긴 것:
- 파일 크기/확장자 제한 없음
- audit_logs 테이블은 있으나 아직 기록 안 함
- 목록 페이지네이션/검색 없음

설치와 취약점별 재현/수정 방법은 README.md 참고.
실제 서비스에 사용 금지, 참가자 개인 VM(폐쇄 환경) 전용.
2026-09-01 00:20:51 +09:00
api 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
assets 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
uploads 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
.gitignore 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
db.php 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
index.php 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
README.md 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
schema.sql 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00
switch_role.php 해킹 타임 실습용 t-box 취약 샘플 앱 추가 (순수 PHP + PostgreSQL) 2026-09-01 00:20:51 +09:00

t-box 교육용 샘플 (의도적으로 취약한 버전)

바이브 코딩 워크숍의 해킹 타임 실습용 샘플 앱입니다. 순수 PHP + PostgreSQL로 만들었고, 실습 시나리오가 반드시 재현되도록 취약점을 일부러 남겨두었습니다.

⚠️ 이 코드는 교육용입니다. 실제 서비스에 절대 사용하지 마세요. 반드시 참가자 개인 VM(폐쇄 환경)에서만 실행합니다.

왜 이 저장소가 필요한가

참가자가 AI에게 "취약하게 만들어줘"라고 요청해도, 요즘 AI는 보안을 챙겨서 권한 검사를 넣어버리는 경우가 많습니다. 그러면 해킹 타임 실습이 성립하지 않습니다. 이 저장소는 강사용 안전망입니다. 참가자의 앱에서 취약점이 재현되지 않을 때 이걸 내려받아 실습을 진행하세요.

설치

1. 필요한 것

sudo apt update
sudo apt install -y nginx php-fpm php-pgsql postgresql

2. DB 만들기

sudo -u postgres psql -c "CREATE USER tbox WITH PASSWORD 'tbox';"
sudo -u postgres psql -c "CREATE DATABASE tbox OWNER tbox;"
psql "postgresql://tbox:tbox@127.0.0.1/tbox" -f schema.sql

schema.sql은 테이블과 함께 예시 파일 5개(public 2 · internal 2 · admin-only 1)를 넣어줍니다. 해킹 타임을 바로 시작할 수 있습니다.

3. 코드 배치

sudo mkdir -p /var/www/html
sudo chown -R $USER /var/www/html
cp -r . /var/www/html/
chmod 777 /var/www/html/uploads

4. nginx 설정

/etc/nginx/sites-available/tbox 에 아래를 넣고 활성화합니다. (php8.2-fpm.sock 부분은 설치된 PHP 버전에 맞게 바꾸세요 — ls /run/php/로 확인)

server {
    listen 80;
    server_name _;
    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
}
sudo ln -sf /etc/nginx/sites-available/tbox /etc/nginx/sites-enabled/tbox
sudo nginx -t && sudo systemctl reload nginx

브라우저에서 내 도메인으로 접속하면 목록이 보입니다.

파일 구조

파일 역할
index.php 화면 (목록 · 업로드 · URL 가져오기)
db.php DB 연결, 현재 사용자, JSON 응답 도우미
switch_role.php 역할 전환 (교육용 — 진짜 로그인 대신)
api/files.php 목록 조회 / 삭제 — 취약점 A·B
api/upload.php 업로드 — 취약점 C 준비 (검증 없음)
api/download.php 다운로드 — 권한 검사 없음
api/fetch_url.php URL 검사 — SSRF 실습 (취약/방어 비교)
assets/app.js 화면 동작 — 취약점 A·B·C
schema.sql 테이블 + 예시 데이터 5개

심어둔 취약점 (강사용 정답지)

A. 프론트엔드 권한 우회 → 삭제

  • 어디에: assets/app.js (버튼을 display:none으로 숨김) + api/files.php (DELETE에 권한 검사 없음)
  • 재현: Employee로 전환 → 삭제 버튼 안 보임 → F12 Elements에서 style="display:none" 제거 → 버튼 클릭 → 삭제됨
  • 콘솔로도 가능: fetch('api/files.php?id=1', {method:'DELETE'}).then(r=>r.json()).then(console.log)
  • 고치는 법: api/files.php의 DELETE 분기에서 current_user()['role']을 확인하고 권한 없으면 403 + 감사 로그

B. 숨긴 데이터가 API 응답에 노출

  • 어디에: api/files.php GET (전체 조회) + assets/app.jsVISIBLE_BY_ROLE (화면에서만 필터)
  • 재현: Employee로 전환 → 화면엔 admin-only 파일 안 보임 → F12 Network 탭 → api/files.php 응답 확인 → 급여명세_2026.txt가 그대로 보임
  • 고치는 법: SQL의 WHERE access_level IN (...)으로 서버에서 걸러서 내려주기

C. XSS (파일명·설명)

  • 어디에: api/upload.php (검증 없이 저장) + assets/app.jstr.innerHTML (이스케이프 없이 출력)
  • 재현: 파일 설명에 <img src=x onerror="alert('xss')"> 입력 후 업로드 → 목록 화면에서 알림창이 뜸
  • 고치는 법: 출력 시 이스케이프(textContent 사용 또는 서버에서 htmlspecialchars)

D. SSRF

  • 어디에: api/fetch_url.php
  • 재현: URL 칸에 http://127.0.0.1:3000 또는 http://169.254.169.254/latest/meta-data 입력 → 취약한 검사는 통과시킴
  • 비교: 같은 URL로 방어된 검사를 고르면 차단 사유가 나옴
  • 고치는 법: check_safe()가 목표 모습 — http/https만 허용, DNS 해석 후 사설·루프백·링크로컬 IP 차단

E. 그 밖에 (실습 후반부용)

  • 파일 크기·확장자 제한 없음 (api/upload.php)
  • 감사 로그 테이블(audit_logs)은 있지만 아무도 기록하지 않음
  • 목록에 페이지네이션·검색 없음

실습 후 되돌리기

git checkout .        # 수정한 내용 되돌리기
psql "postgresql://tbox:tbox@127.0.0.1/tbox" -f schema.sql   # 데이터 초기화