상황
용어
지시 예문
상황
/orders/1024의 숫자를 1025로 바꾸니 남의 주문 내역이 보인다(진단 Q2)./admin을 직접 쳐서 들어왔다."role": "admin"을 몰래 끼워 보냈더니 관리자가 됐다.용어
/admin, /api/users 같은 주소를 직접 쳐서 들어가 보는 것. 숨긴 주소는 숨겨진 게 아니다.role, is_admin, balance, user_id)까지 덮어쓰는 취약점(상황 3).
지시 예문
상황
용어
지시 예문
상황
a.jpg; rm -rf /로 올리자 서버 파일이 지워졌다./download?file=report.pdf인데, file=../../.env로 바꾸자 서버의 비밀 설정 파일이 내려받아졌다.eval()로 실행했더니, 수식 대신 코드를 넣는 사람이 생겼다.용어
../를 넣어 허락된 폴더 밖의 파일에 접근하는 것(상황 2). .env(웹 용어 17번), 설정 파일, 다른 사용자 파일이 노출된다.
eval(), new Function()처럼 코드로 실행하는 것(상황 3). 사용자가 서버(또는 다른 사용자 브라우저)에서 아무 코드나 돌릴 수 있게 된다. 사용자 입력을 코드로 실행하는 설계 자체를 피한다 — 계산기라면 수식 전용 파서 라이브러리를 쓴다.{"$ne": null} 같은)를 끼워 넣어 필터를 무력화할 수 있다. “SQL 안 쓰니 안전”은 착각.// ❌ 셸 문자열에 입력을 이어 붙임 — file = "a.jpg; rm -rf /" 이면 두 번째 명령까지 실행
exec(`convert ${file} out.png`)
// ⭕ 셸을 거치지 않고 인자를 배열로 — file은 통째로 "파일 이름 하나"로만 취급
execFile('convert', [file, 'out.png'])
// ⭕⭕ 명령 대신 라이브러리
await sharp(file).toFile('out.png')
// ❌ path.join('/app/uploads', '../../.env') → '/.env' (업로드 폴더 밖)
res.sendFile(path.join('/app/uploads', req.query.file))
// ⭕ id로 받고, 소유자 확인 후 서버가 경로를 찾음
const doc = await db.files.findFirst({ where: { id: req.params.id, ownerId: user.id } })
if (!doc) return res.status(404).end()
res.sendFile(doc.storagePath)
// ⭕ 이름을 꼭 받아야 하면: 정규화 후 허용 폴더 안인지 확인
const full = path.resolve(BASE, name)
if (!full.startsWith(BASE + path.sep)) return res.status(403).end()
// ❌ expr = "process.exit()" 같은 코드도 그대로 실행
eval(req.body.expr)
// ⭕ 수식만 해석하는 전용 파서
import { evaluate } from 'mathjs'
evaluate('2 * (3 + 4)')
// ❌ body가 {"email":"admin@x.com","password":{"$ne":null}} 이면
// "비밀번호가 null이 아닌" 조건이 되어 비밀번호 없이 통과
users.findOne({ email: req.body.email, password: req.body.password })
// ⭕ 타입부터 검증 — 문자열이 아니면 거부 (그리고 비밀번호는 3번 레슨처럼 해시 비교)
const { email, password } = z.object({ email: z.string().email(), password: z.string() }).parse(req.body)
// ❌ denylist — "<SCRIPT>", "<img onerror=...>" 같은 변형은 그대로 통과
if (name.includes('<script>')) throw new Error('blocked')
// ⭕ allowlist — 허용한 모양만 통과
z.enum(['jpg', 'png']).parse(ext)
z.string().regex(/^[a-zA-Z0-9_-]{1,30}$/).parse(username)
지시 예문
상황
javascript:로 시작하는 주소를 넣으니 클릭한 사람 브라우저에서 스크립트가 실행됐다.용어
innerHTML 같은 곳에 넣다가 발생.{comment}처럼 텍스트로 넣을 땐 자동으로 안전하게 바꿔 준다. 그러나 다음은 보호 밖이다:
dangerouslySetInnerHTML, v-html, innerHTML — HTML을 직접 넣는 곳(웹 용어 25번, DOMPurify로 sanitize).href·src에 사용자 URL — javascript: 같은 위험한 프로토콜이 들어갈 수 있다(상황 1). https://·http://만 허용(allowlist)한다.frame-ancestors 'none'(또는 옛 헤더 X-Frame-Options: DENY)로 다른 사이트가 우리를 액자에 못 넣게 막는다.지시 예문
상황
http://localhost:6379 같은 내부 주소를 넣자, 서버가 바깥에선 접근할 수 없는 내부 서비스에 대신 접속해 응답을 보여줬다.용어
169.254.169.254). 서버 설정과 임시 접속 키를 알려준다. SSRF가 노리는 1순위 표적(상황 2). AWS는 이 주소에 토큰을 먼저 받아야 접근되는 IMDSv2(Instance Metadata Service version 2) 방식을 쓰도록 권장한다.
127.0.0.1(localhost), 10.x, 192.168.x, 169.254.x 같은 내부 대역이면 거부한다(인프라 용어 1번 사설 IP).지시 예문
상황
npm install 후 “12 vulnerabilities (3 high)” 경고와 함께 CVE-2025-XXXXX 같은 번호가 떴다(진단 Q3). 무엇을 의미하는지, 무엇부터 고쳐야 하는지 모르겠다.node_modules 안엔 1,000개가 넘는 패키지가 들어 있다. 그중 하나에 취약점이 있다.용어
package.json에 우리가 적은 것.CVE-연도-번호). 전 세계가 같은 취약점을 같은 이름으로 부르게 해 준다(진단 Q3의 답). 4번 레슨 사례의 MOVEit(CVE-2023-34362), Fortinet(CVE-2018-13379)도 이 번호.
npm audit fix로 호환되는 범위 안의 수정 버전으로 올린다. 큰 버전 변경(기획 용어 9번 SemVer(Semantic Versioning)의 MAJOR)은 동작이 깨질 수 있어 테스트(기획 용어 8번 regression test)와 함께.
package-lock.json, pnpm-lock.yaml처럼 설치된 정확한 버전(간접 의존성까지)을 기록한 파일. 이게 있어야 모든 환경이 똑같은 코드를 설치한다. git에 반드시 커밋하고, 배포·CI(Continuous Integration)에선 lockfile 그대로 설치(npm ci)한다.reqeusts, lodahs)으로 악성 패키지를 올려 오타를 노리는 것(상황 4). AI가 존재하지 않는 패키지 이름을 지어내면 공격자가 그 이름을 먼저 등록해 두는 수법(slopsquatting)도 있다 — AI 보안 주제에서 자세히.지시 예문
상황
우리도메인.com/.git/에 접속해 소스 코드와 커밋 기록 전체를 내려받았다. 기록 속엔 예전에 지운 API 키도 남아 있었다.용어
.git 폴더·백업 파일 — 서버에 코드를 올릴 때 .git, .env, backup.zip, db.sql 같은 파일이 웹에서 접근 가능하게 남는 것(상황 2). git 기록엔 지운 비밀값도 남아 있다(인프라 용어 11번).admin/admin, root/root 같은 계정을 그대로 둠(상황 3). 자동화된 봇이 가장 먼저 시도한다./admin, DB 관리 도구, DB 포트를 인터넷에 공개(2번 레슨 forced browsing, 인프라 용어 11번 방화벽).NEXT_PUBLIC_ 붙은 비밀 키(웹 용어 17번).지시 예문
상황
.jpg인지만 확인했는데, 누군가 shell.php.jpg처럼 이름만 바꾼 실행 파일을 올렸다.용어
.jpg). 그냥 이름이라 아무렇게나 붙일 수 있다.Content-Type을 정확히, 5번 레슨 X-Content-Type-Options: nosniff, 문서류는 Content-Disposition: attachment(브라우저에서 열지 말고 다운로드하게).지시 예문
상황
용어
exec에 들어감”(4번 레슨), “dangerouslySetInnerHTML에 sanitize 없음”(5번 레슨). Semgrep, CodeQL 등. AI 기반 코드 보안 스캔도 이 계열. 비유: 설계도 검토.지시 예문