No description
- PHP 66.2%
- JavaScript 22.6%
- CSS 11.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
바이브 코딩 워크숍의 해킹 타임 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(폐쇄 환경) 전용. |
||
| api | ||
| assets | ||
| uploads | ||
| .gitignore | ||
| db.php | ||
| index.php | ||
| README.md | ||
| schema.sql | ||
| switch_role.php | ||
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.phpGET (전체 조회) +assets/app.js의VISIBLE_BY_ROLE(화면에서만 필터) - 재현: Employee로 전환 → 화면엔 admin-only 파일 안 보임 → F12 Network 탭 →
api/files.php응답 확인 → 급여명세_2026.txt가 그대로 보임 - 고치는 법: SQL의
WHERE access_level IN (...)으로 서버에서 걸러서 내려주기
C. XSS (파일명·설명)
- 어디에:
api/upload.php(검증 없이 저장) +assets/app.js의tr.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 # 데이터 초기화