# 1단계 · 위협과 입력 검증 - 교시: 1교시 강의 (09:00~09:50) · 2교시 [Lab 01](../../Last3Mon/73/LAB-01-Q-THREATS-AND-INPUT.md) 실습 5개 (10:00~10:50) - 이 단계가 끝나면: LLM 워크플로우가 받는 위협을 나열하고, 먼저 공격해 본 뒤, LLM을 부르기 전에 입력을 검사하고 알려진 공격을 규칙으로 막을 수 있다. 글자를 숨긴 공격은 정리한 뒤에 보고, 정상 질문을 막지 않는 것까지 테스트로 확인한다. - 숫자: 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, OpenAI `gpt-4.1-mini`, 10/26 실습을 5개로 늘린 뒤 정답 워크플로우를 학생 순서대로 1회). 출력 전부는 수업 뒤 공개되는 `Last3Mon/73/answers/LAB-TEST-RESULT.md`에 있습니다. - 실습 가리키기: 이 문서에서 "Lab 01 예제 1"은 2교시 [Lab 01 문서](../../Last3Mon/73/LAB-01-Q-THREATS-AND-INPUT.md)의 그 절입니다. 파일 경로(`cases/` · `requests/` · `my-work/` · `reference/`)는 실습 폴더 `~/aio-01d4-stu/Last3Mon/73` 기준입니다. ```mermaid flowchart LR A["1. 왜 보안인가"] --> B["2. 위협 다섯 가지"] --> C["3. 먼저 공격해 보기"] --> D["4. 입력 검증"] --> E["5. 400과 차단"] E --> F["6. 관문이 아낀 시간"] --> G["7. 규칙과 정상 질문"] --> H["8. 숨긴 공격 · 글자 정리"] --> I["9. 요청문(프롬프트)으로"] ``` ## 0. 이 시간 (50분) | 시간 | 절 · 개요 | 하는 일 | | --- | --- | --- | | 09:00~09:06 | 개요 1~6장 | 오늘 하루, 공격 대상, 실습 15개 | | 09:06~09:10 | 1 · 개요 7장 | LLM 앱이 새로 만든 위험, OWASP LLM Top 10 | | 09:10~09:16 | 2 · 개요 8장 | 위협 다섯 가지, 프롬프트 인젝션 (직접 · 간접) | | 09:16~09:22 | 3 · 개요 9장 | 레드팀, 공격 대상 실측 2/9, "대체로 막는다 ≠ 막힌다" | | 09:22~09:30 | 4 · 5 · 개요 10장 | 입력 검증, 허용 목록 · 차단 목록, 400 · 차단 | | 09:30~09:34 | 6 · 개요 11장 | 관문이 아낀 시간 실측 | | 09:34~09:42 | 7 · 개요 12장 | 규칙의 두 실패(덜 막음 · 지나치게 막음), 정규식 | | 09:42~09:46 | 8 · 개요 13~14장 | 유니코드 정규화, 숨긴 공격 | | 09:46~09:50 | 9 · 10 · 확인 질문 | 요청문, 자주 하는 실수, 질문 | ### 2교시 Lab 01에서 이어서 하는 것 | 2교시 실습 (시각) | 이 강의의 절 | 실습에서 하는 일 | 쓰는 파일 · 명령 | | --- | --- | --- | --- | | 시작 (10:00) | — | 보안 점검표 복사 | `cp templates/SECURITY-CHECKLIST-TEMPLATE.md my-work/SECURITY.md` (오늘 표를 모두 여기에 적음) | | Lab 01 예제 1 (10:00~10:10, 에이전트 없이) | 2 · 3 | 공격 대상을 공격해 보고 새어 나간 것 적기 | `call open-it-agent requests/first-instructions.json -v` 등, `test cases/lab01-attacks.json --webhook open-it-agent` → `my-work/SECURITY.md` 1절 | | Lab 01 예제 2 (10:10~10:22) | 4 · 5 | 에이전트에게 입력 검증 · 규칙을 넣게 하기 | `my-work/secure-agent.json` (공격 대상을 복사), 테스트 `cases/lab01.json` | | Lab 01 예제 3 (10:22~10:30, 에이전트 없이) | 6 | 400 · 차단 · 공격 대상 · 정상의 시간 재기 | `bench my-secure requests/bad-user.json -n 5` 등 → `SECURITY.md` 2절 | | Lab 01 과제 1 (10:30~10:40) | 7 | 알려진 공격 10개를 막고 정상 10개는 지나가게 | 테스트 `cases/lab01-challenge.json` | | Lab 01 과제 2 (10:40~10:50) | 8 · 9 | 규칙 앞에서 글자 정리 | 테스트 `cases/lab01-challenge2.json` → `SECURITY.md` 3절 | ## 1. 왜 보안인가: LLM 앱이 새로 만든 위험 ### 일반 설명 보통의 웹 앱에서 사용자가 보내는 글은 **데이터**입니다. 데이터베이스에 저장하고 화면에 보여 줄 뿐, 그 글이 프로그램의 동작을 바꾸지는 않습니다. 그런데 보안 사고의 오랜 역사는 대부분 **"데이터가 명령으로 읽힌" 사고**입니다. | 오래된 공격 | 데이터가 어디서 명령이 되나 | 막는 법 (정해진 것) | | --- | --- | --- | | SQL 인젝션 | 검색어 `' OR 1=1 --`가 SQL 문장의 일부가 됨 | 매개변수 바인딩: 데이터 자리와 명령 자리를 **문법으로** 나눔 | | XSS (교차 사이트 스크립트) | 게시글 속 `