📄 2026.01.27 (Day 64) - 웹 보안 기초 및 SQL Injection 입문


1. 핵심 개념 정리

웹 애플리케이션 구조

# 핵심 개념 설명 실무/보안 관점
1 클라이언트-서버 모델 사용자가 브라우저를 통해 요청을 보내면 웹 서버가 응답을 반환하는 구조 요청/응답 과정에서 보안장비(WAF, IPS)가 악성 트래픽을 탐지하고 차단
2 3계층 구조 웹 서버(정적 콘텐츠) -> WAS(로직 처리) -> DB(데이터 저장)로 구성 각 계층마다 보안 취약점이 존재하며, 다층 방어 전략 필수
3 웹 서버와 WAS 분리 Apache/Nginx는 정적 파일 제공, Tomcat/WAS는 동적 로직 처리 서버 분리로 부하 분산 및 보안 강화 가능
4 주요 웹 기술 스택 Java(80%), PHP(15%), ASP 등 / Oracle(60%), MySQL(30%) 기술 스택별로 고유한 취약점과 공격 기법이 존재
5 MVC 패턴 Model-View-Controller 구조로 코드 분리 및 유지보수성 향상 각 계층의 입력값 검증이 제대로 이루어지지 않으면 보안 취약점 발생

HTTP 프로토콜 특성

# 핵심 개념 설명 실무/보안 관점
6 1회성 연결 HTTP는 요청-응답 후 즉시 연결 종료 상태를 유지하지 않아 Session/Cookie로 상태 관리 필요
7 Stateless 서버는 이전 요청 정보를 기억하지 않음 인증 상태 유지를 위해 Session ID나 Token 사용
8 Request 구조 HTTP Method + URL + Header + Body로 구성 Header 조작 공격, Body 페이로드 삽입 등 공격 벡터 존재
9 Response 구조 Status Code + Header + Body로 구성 500 에러 시 상세 에러 메시지 노출은 정보 유출 위험
10 HTTP Method GET(조회), POST(전송), HEAD, OPTIONS, PUT, DELETE 등 불필요한 Method 허용 시 보안 위험 증가

HTTP 상태 코드 및 에러

# 핵심 개념 설명 실무/보안 관점
11 200 OK 요청 정상 처리 정상 응답이지만 민감 정보 과다 노출 주의
12 302 Redirect 주소 이동 Open Redirect 취약점 악용 가능
13 400 Bad Request 메소드 또는 요청 형식 오류 잘못된 입력값 필터링 여부 확인 가능
14 404 Not Found 경로가 존재하지 않음 디렉터리 구조 노출 방지 필요
15 500 Internal Server Error 서버 내부 오류 (예외처리 미흡) 상세 에러 메시지 노출 시 SQL Injection 등 공격에 악용 가능

인코딩과 문자 처리

# 핵심 개념 설명 실무/보안 관점
16 URL Encoding 특수문자를 %xx 형태로 인코딩 (예: 공백 -> %20) 공격 구문을 인코딩하여 필터 우회 시도
17 Base64 Encoding 바이너리 데이터를 텍스트로 변환 (예: qlewk+jflw/efklfw==) 인코딩은 암호화가 아니므로 누구나 디코딩 가능
18 HTML Encoding HTML 특수문자를 엔티티로 변환 (예: &#xx;) XSS 공격 방어를 위해 출력 시 HTML 인코딩 필수
19 Character Set 특정 문자를 숫자로 매핑하는 문자 집합 (ASCII, UTF-8) DB와 웹 애플리케이션의 문자 집합 불일치 시 인코딩 오류 발생
20 URL 예약어 &, ?, +, /, *, , “, ‘, . 등은 기능으로 작동 예약어를 문자열로 사용하려면 반드시 인코딩 필요

브라우저 보안 정책 및 웹 트렌드

# 핵심 개념 설명 실무/보안 관점
21 SOP Same-Origin Policy: 다른 출처의 리소스 접근 제한 CSRF, XSS 공격 방어의 기본 메커니즘
22 CORS Cross-Origin Resource Sharing: 다른 출처 간 리소스 공유 허용 allow-origin: * 설정 시 보안 위험 증가
23 AJAX 비동기 방식으로 새로고침 없이 데이터 송수신 백그라운드 요청이므로 트래픽 모니터링 필요
24 JSON JavaScript Object Notation: 데이터 교환 형식 content-type: application/json으로 전송
25 WebSocket HTTP 연결을 유지하며 양방향 실시간 통신 연결 유지형이므로 세션 하이재킹 위험 존재
# 핵심 개념 설명 실무/보안 관점
26 Session 서버 측에 저장되는 사용자 상태 정보 서버 메모리 사용, 안전하지만 확장성 제한
27 Cookie 브라우저에 저장되는 클라이언트 측 데이터 탈취 위험이 있으므로 민감 정보 저장 금지
28 Session ID 사용자를 식별하기 위한 고유 ID Session Hijacking 공격으로 탈취 가능
29 Cookie 속성 HttpOnly, Secure, SameSite 등 보안 속성 설정 가능 HttpOnly로 XSS 방어, Secure로 HTTPS 강제
30 상태 관리의 필요성 HTTP는 Stateless이므로 로그인 상태 유지 위해 필수 Session Fixation, Session Hijacking 공격 대상

2. 실습 내용 정리

실습 62-1: 개발 환경 구축

목표: 웹 보안 실습을 위한 기본 개발 환경 설정

실습 단계:

  1. VSCode 설치: 구글 검색 -> VSCODE 다운로드 -> 설치
  2. VSCode 폰트 설정: 파일 -> 기본 설정 -> 설정(Ctrl+,) -> font-family 맨 왼쪽에 ‘D2Coding’ 추가
  3. 한글 언어팩 설치: 왼쪽 확장프로그램 메뉴 -> korean 검색 -> Korean Language Pack 설치 -> “Change Language and Restart” 클릭
  4. Oracle Database 설치: 구글 검색 -> Oracle DB download -> Download Oracle AI Database Free for Windows 클릭
  5. SQL Developer 설치: 구글 검색 -> SQL Developer -> Windows 64-bit with JDK 17 included 다운로드

확인 항목:

  • VSCode가 정상적으로 실행되는지 확인
  • D2Coding 폰트가 올바르게 적용되었는지 확인
  • Oracle Database가 정상 설치되어 서비스 실행 중인지 확인
  • SQL Developer로 DB 접속이 가능한지 확인

보안 인사이트:

  • 개발 환경 구축 시 최신 버전 사용으로 알려진 취약점 패치
  • Oracle Database 기본 계정의 강력한 비밀번호 설정 필수
  • 개발용 DB와 운영 DB를 반드시 분리하여 관리

실습 62-2: Oracle Database 사용자 생성 및 권한 부여

목표: SQL Injection 실습을 위한 Oracle 사용자 계정 생성

접속 정보:

  • 아이디: SYSTEM
  • 비밀번호: 1234
  • 호스트 이름: 192.168.0.156 (또는 localhost)
  • 포트: 1521
  • SID: free

실습 단계 (SQL):

  1. SQL Developer로 SYSTEM 계정 접속
  2. Oracle 12c 이상에서 일반 사용자명에 C## 접두사 강제되는 제약 해제: ALTER SESSION SET “_ORACLE_SCRIPT”=true;
  3. richman 사용자 생성: CREATE USER richman IDENTIFIED BY 1234;
  4. 권한 부여: GRANT connect, resource, dba TO richman;
  5. richman 계정으로 재접속하여 테이블 생성 준비

Oracle 사용자 생성 원리:

  1. Oracle 12c 이상에서는 일반 사용자명 앞에 C## 접두사를 강제함 (Container Database 개념)
  2. ALTER SESSION 명령으로 이 제약을 일시적으로 해제
  3. CREATE USER로 새 사용자 생성 및 비밀번호 설정

부여된 권한:

  • connect: DB 접속 권한
  • resource: 테이블, 시퀀스 등 객체 생성 권한
  • dba: 관리자 권한 (실습용으로만 사용, 운영 환경에서는 절대 금지)

보안 고려사항:

  • 실습 환경에서만 dba 권한 부여, 운영 환경에서는 최소 권한 원칙 적용
  • 기본 비밀번호(1234) 사용 금지, 복잡한 비밀번호 설정 필수
  • DBA 권한을 가진 웹 애플리케이션 계정은 즉시 점검 필요
  • 계정 생성 로그 모니터링으로 비인가 계정 생성 탐지

실습 62-3: 테이블 생성 및 샘플 데이터 삽입

목표: SQL Injection 실습을 위한 friends 및 members 테이블 생성

실습 단계:

  1. friends 테이블 생성: name(VARCHAR2 20), address(VARCHAR2 10), age(NUMBER 2), hobby(VARCHAR2 10)
  2. friends 테이블에 20명 샘플 데이터 삽입 (이름, 주소, 나이, 취미)
  3. members 테이블 생성: name(VARCHAR2 20), user_id(VARCHAR2 20), password(VARCHAR2 30), email(VARCHAR2 50), phone(VARCHAR2 20)
  4. members 테이블에 20명 샘플 데이터 삽입 (이름, 아이디, 비밀번호, 이메일, 전화번호)
  5. 데이터 확인: SELECT * FROM friends; / SELECT * FROM members;

DB 구조:

friends 테이블: name(이름), address(거주 지역 - 서울/대구/부산/대전), age(나이), hobby(취미 - 축구/농구/야구/배구)

members 테이블: name(회원 이름), user_id(로그인 아이디), password(비밀번호 - 평문 저장은 실습용), email(이메일 주소), phone(전화번호)

보안 관점:

  • 실제 운영 환경에서는 비밀번호를 평문으로 저장하지 않고 반드시 해시화(bcrypt, SHA-256 등) 필요
  • 개인정보 암호화 의무 대상 데이터(주민번호, 비밀번호, 생체정보 등)는 암호화 저장 필수

실습 62-4: SQL SELECT 문 기초

목표: SQL SELECT 문법 이해 및 WHERE 조건절 활용

주요 쿼리 예시:

  • 전체 데이터 조회: SELECT * FROM friends;
  • 지역 조건: SELECT * FROM friends WHERE address = ‘서울’;
  • 비교 연산자: SELECT * FROM friends WHERE age > 27;
  • LIKE 패턴 매칭 (김씨 성): SELECT * FROM friends WHERE name LIKE ‘김%’;
  • AND 조건 (서울+축구): SELECT * FROM friends WHERE address = ‘서울’ AND hobby = ‘축구’;
  • OR 조건 (서울 또는 축구): SELECT * FROM friends WHERE address = ‘서울’ OR hobby = ‘축구’;
  • 항상 참인 조건: SELECT * FROM friends WHERE ‘q’ = ‘q’; => 결과: 모든 데이터 조회

SQL 논리 연산자 진리표:

AND 연산자: T AND T -> T / T AND F -> F / F AND T -> F / F AND F -> F

OR 연산자: T OR T -> T / T OR F -> T / F OR T -> T / F OR F -> F

실무 적용:

  • ‘q’=‘q’ 같은 항상 참인 조건은 SQL Injection 공격에 자주 사용됨
  • WHERE 절의 논리 연산자 우선순위 이해 필수

보안 인사이트:

  • LIKE 연산자와 % 와일드카드는 SQL Injection 공격 포인트로 자주 악용됨
  • 항상 참인 조건(‘1’=‘1’, ‘q’=‘q’)을 삽입하여 인증 우회 시도 가능
  • WHERE 절의 논리 연산 구조를 이해해야 공격 쿼리 분석 가능

실습 62-5: SQL Injection 기본 개념 및 인증 우회

목표: SQL Injection 공격 원리 이해 및 로그인 인증 우회 실습

정상적인 로그인 쿼리 구조:

  • SELECT * FROM members WHERE user_id = ‘사용자입력’ AND password = ‘비밀번호입력’;

SQL Injection 공격 시나리오:

  • 아이디 입력: leesy’ or ‘k’=‘k
  • 비밀번호 입력: (아무거나)
  • 실제 실행되는 쿼리: SELECT * FROM members WHERE user_id = ’leesy’ OR ‘k’=‘k’ AND password = ‘아무거나’;
  • 논리 연산 우선순위(AND > OR)에 따라: user_id = ’leesy’ OR (‘k’=‘k’ AND password = ‘아무거나’) -> ‘k’=‘k’가 항상 참이므로 결과적으로 leesy 계정 조회됨

OR 조건만 사용:

  • 아이디: ’ or ‘1’=‘1 / 비밀번호: (아무거나)
  • 실제 쿼리: SELECT * FROM members WHERE user_id = ’’ OR ‘1’=‘1’ AND password = ‘아무거나’;
  • 결과: 전체 회원 데이터 조회, 첫 번째 계정으로 로그인 성공

특정 계정 타겟팅 (주석 처리):

  • 아이디: kimms’ –
  • 실제 쿼리: SELECT * FROM members WHERE user_id = ‘kimms’ –’ AND password = ‘아무거나’;
  • 주석 처리로 비밀번호 검증 우회, kimms 계정으로 로그인

SQL Injection 공격 메커니즘:

  1. 사용자 입력값이 SQL 쿼리에 직접 삽입됨 (Prepared Statement 미사용)
  2. 공격자가 입력란에 SQL 구문을 삽입하여 쿼리 구조 변경
  3. 의도하지 않은 데이터 조회, 인증 우회, 데이터 탈취 등 발생

공격 포인트 판별:

  • 입력란에 싱글쿼트(’)를 입력했을 때 에러 발생하거나 동작이 이상하면 취약
  • 에러 메시지가 상세하게 노출되면 쿼리 구조 파악 가능

로그인 인증 우회 공격 단계:

  1. 쿼리문 유추: SELECT * FROM members WHERE user_id = ‘입력값’ AND password = ‘입력값’
  2. 공격 포인트 확인: 입력란에 ’ 입력 시 에러 발생 여부 확인
  3. 제약사항 파악: 이 경우는 제약사항 없음 (기본 인증 우회)
  4. 공격 실행: 항상 참인 조건 삽입 또는 주석 처리

보안 고려사항:

취약점: 사용자 입력값을 쿼리에 직접 결합 (String Concatenation), 입력값 검증 및 필터링 미흡, SQL 주석 처리 문자 미차단

방어 방법:

  • Prepared Statement (Parameterized Query) 사용 필수
  • 입력값 화이트리스트 검증 (허용된 문자만 통과)
  • ORM(Object-Relational Mapping) 프레임워크 활용
  • 에러 메시지 상세 정보 노출 차단

3. 웹 기술 비교표

데이터 전송 형식 비교

항목 Query String JSON XML 실무 사용 사례
형식 ?key1=value1&key2=value2 {“key1”:“value1”} key1 태그 방식 Query String은 GET 요청, JSON은 API, XML은 레거시 시스템
가독성 낮음 (URL에 노출) 높음 (구조화) 중간 (태그 많음) JSON이 가장 직관적이며 현대 API 표준
데이터 크기 제한적 (URL 길이 제한) 중간 큼 (태그 오버헤드) 대용량 데이터는 POST + JSON 사용
보안 URL에 노출되어 위험 HTTPS 사용 시 안전 HTTPS 사용 시 안전 Query String으로 민감 정보 전송 금지

HTTP Method 비교

Method 용도 멱등성 안전성 보안 고려사항
GET 리소스 조회 O O URL에 데이터 노출, 민감 정보 전송 부적합
POST 리소스 생성/전송 X X Body에 데이터 포함, CSRF 공격 대상
HEAD 응답 헤더만 조회 O O 정보 수집 용도로 악용 가능
OPTIONS 사용 가능 메소드 확인 O O CORS Pre-flight에 사용, 정보 노출 위험
PUT 리소스 전체 수정 O X 불필요 시 비활성화 필요
DELETE 리소스 삭제 O X 권한 검증 필수

4. 심화 분석

웹 애플리케이션 요청-응답 플로우

구분 클라이언트 측 네트워크 서버 측 보안 체크포인트
요청 생성 브라우저가 HTTP Request 생성 패킷 전송 - 클라이언트 측 검증은 우회 가능하므로 서버 검증 필수
보안장비 통과 - WAF, IPS 통과 - SQL Injection, XSS 등 공격 패턴 탐지 및 차단
웹 서버 처리 - - Apache/Nginx 요청 수신 정적 파일 직접 제공, 동적 요청은 WAS로 전달
WAS 로직 실행 - - Tomcat 등 비즈니스 로직 실행 입력값 검증, 인증/인가 확인
DB 쿼리 - - DB 연결 및 쿼리 실행 Prepared Statement 사용 여부, 권한 확인
응답 생성 - - 웹 서버가 Response 생성 에러 메시지 필터링, 민감 정보 노출 차단
응답 수신 브라우저가 응답 렌더링 패킷 수신 - XSS 방어를 위한 Content-Type 검증

SQL Injection 방어 코드 원리

취약한 코드 예시:

  • name = request.args.get(’name’)
  • query = “SELECT * FROM friends WHERE name = ‘” + name + “’”
  • 공격: name에 ’ or ‘1’=‘1 입력 시 모든 데이터 조회

안전한 코드 (Prepared Statement):

  • query = “SELECT * FROM friends WHERE name = ?”
  • result = db.execute(query, (name,))
  • 입력값이 단순 문자열로 처리되어 공격 실패

5. 실무/보안 적용

보안 전문가 관점 - 웹 애플리케이션 보안 점검

단계/항목 점검 포인트 취약점 예시 대응 방안
입력값 검증 모든 사용자 입력값 검증, 특수문자 필터링, 길이 제한 SQL Injection, XSS, Command Injection 화이트리스트 방식 검증, Prepared Statement 사용, 입력값 이스케이프 처리
인증/인가 세션 관리, 비밀번호 강도, 권한 검증 인증 우회, 세션 하이재킹, 권한 상승 강력한 세션 ID 생성, HttpOnly/Secure 쿠키 설정, 비밀번호 해시화 (bcrypt)
에러 처리 에러 메시지 노출, 디버그 모드, 스택 트레이스 정보 유출, 쿼리 구조 노출 일반화된 에러 페이지, 운영 환경에서 디버그 모드 비활성화, 상세 로그는 서버에만 저장

SQL 쿼리 보안 체크리스트

개발 단계:

  • Prepared Statement 사용 여부 확인 (Java: PreparedStatement, Python: parameterized queries, PHP: PDO with placeholders)
  • 입력값 화이트리스트 검증: 허용된 문자만 통과 (영문, 숫자, 일부 특수문자)
  • 에러 메시지 필터링: 운영 환경에서 상세 에러 노출 차단, 사용자에게는 일반 메시지만 표시
  • DB 계정 권한 최소화: SELECT, INSERT, UPDATE, DELETE만 허용, DROP/ALTER/CREATE 권한 제거

WAF 룰 예시 (SQL Injection 탐지)

ModSecurity WAF Rule 주요 항목:

  • SQL Injection 키워드 탐지: union, select, insert, update, delete, drop, alter, create, exec, script
  • 싱글쿼트 연속 출현 탐지: ’ or ‘, ’ and '
  • 주석 기호 탐지: –, #, /*, */
  • 항상 참인 조건 탐지: ‘1’=‘1’, ‘q’=‘q’, 1=1

6. 배운 점 및 인사이트

새로 알게 된 점

  • 웹 애플리케이션의 3계층 구조: 웹 서버, WAS, DB로 이루어진 구조와 각 계층의 역할을 이해했습니다. 각 계층마다 보안 취약점이 존재하며, 다층 방어가 필요함을 깨달았습니다.
  • HTTP의 Stateless 특성: HTTP는 1회성 연결이며 상태를 저장하지 않기 때문에 Session과 Cookie로 상태 관리를 해야 한다는 점을 배웠습니다.
  • 인코딩과 암호화의 차이: 인코딩은 데이터 무결성 보장 목적이며 누구나 디코딩 가능한 반면, 암호화는 기밀성까지 보장하여 특정인만 복호화 가능함을 이해했습니다.
  • SQL Injection의 기본 원리: 사용자 입력값이 쿼리에 직접 삽입되면 공격자가 쿼리 구조를 변경할 수 있으며, 특히 로그인 인증을 우회할 수 있다는 점을 실습으로 확인했습니다.
  • 500 에러의 보안적 의미: Internal Server Error가 발생하면서 상세 에러 메시지가 노출되면, 공격자가 쿼리 구조를 파악하여 SQL Injection 공격에 악용할 수 있음을 깨달았습니다.

이전 학습과의 연결고리

  • 네트워크 보안 지식 확장: 이전에 학습한 네트워크 계층별 보안이 웹 애플리케이션 레벨에서 어떻게 적용되는지 연결지어 이해할 수 있었습니다.
  • SIEM 로그 분석 관점 연계: Wazuh, Splunk에서 웹 서버 로그를 분석할 때 어떤 패턴을 찾아야 하는지 구체적으로 알게 되었습니다. 특히 SQL Injection 시도는 URL에 특수문자나 SQL 키워드가 포함되므로 탐지 룰 작성 가능성을 확인했습니다.
  • 컴플라이언스 관점: ISMS-P에서 요구하는 개인정보 보호 조치가 웹 애플리케이션에서 어떻게 구현되어야 하는지 연결하여 생각할 수 있었습니다.

실무 적용 아이디어

보안 전문가 관점:

  • 웹 애플리케이션 보안 점검 체크리스트 작성: 입력값 검증, Prepared Statement 사용 여부, 에러 메시지 노출, DB 권한 등을 점검하는 체크리스트를 만들어 정기 점검에 활용할 수 있겠습니다.
  • SIEM 탐지 룰 생성: 웹 로그에서 union, select, ‘or’, – 같은 SQL Injection 키워드가 포함된 요청을 탐지하는 Custom Rule을 Wazuh나 Splunk에 작성할 수 있겠습니다.
  • WAF 룰셋 최적화: ModSecurity 같은 WAF에서 SQL Injection 패턴을 효과적으로 차단하는 룰을 연구하고, False Positive를 최소화하는 방안을 고민해야겠습니다.

7. Quick Reference

SQL 기본 명령어 모음

CRUD 기본 문법:

  • 삽입: INSERT INTO 테이블명 VALUES (값1, 값2, 값3);
  • 조회: SELECT * FROM 테이블명 WHERE 조건;
  • 수정: UPDATE 테이블명 SET 컬럼1 = 값1 WHERE 조건;
  • 삭제: DELETE FROM 테이블명 WHERE 조건;

조건절 연산자:

  • WHERE 컬럼 = 값 (동등 비교)
  • WHERE 컬럼 > 값 (크기 비교)
  • WHERE 컬럼 LIKE ‘김%’ (패턴 매칭)
  • WHERE 조건1 AND 조건2 (논리 AND)
  • WHERE 조건1 OR 조건2 (논리 OR)

HTTP 핵심 개념 요약표

구분 항목 핵심 키워드 주요 내용 보안 적용
Request Method GET, POST, HEAD, OPTIONS 요청 방식 지정 불필요한 Method 비활성화
Request URL 프로토콜://도메인:포트/경로?쿼리 리소스 위치 지정 Query String에 민감 정보 포함 금지
Request Header Cookie, Content-Type, User-Agent 메타 정보 전달 Header 조작 공격 주의
Response Status Code 200, 302, 400, 404, 500 처리 결과 코드 500 에러 상세 정보 노출 차단
Session 상태 관리 Session ID, Cookie HTTP Stateless 보완 Session Hijacking 방어 필요

SQL Injection 방어 체크리스트

개발 단계:

  • 모든 DB 쿼리에 Prepared Statement 적용 확인
  • 사용자 입력값 화이트리스트 검증 구현
  • 에러 메시지 일반화 (상세 정보 노출 차단)
  • ORM 프레임워크 활용 (가능한 경우)

인프라 단계:

  • DB 계정 권한 최소화 (DBA 권한 제거)
  • WAF 룰셋 적용 및 테스트
  • 웹 로그 및 DB 쿼리 로그 수집
  • SIEM에 SQL Injection 탐지 룰 생성

운영 단계:

  • 정기 보안 점검 (입력란별 SQL Injection 테스트)
  • 로그 모니터링 (이상 쿼리 패턴 탐지)
  • 침해사고 대응 매뉴얼 수립
  • 개발자 보안 교육 정기 실시

8. 트러블슈팅

문제 원인 해결 방법
Oracle 사용자 생성 시 C## 에러 Oracle 12c 이상에서 일반 사용자명에 C## 접두사 강제 ALTER SESSION SET “_ORACLE_SCRIPT”=true; 실행 후 사용자 생성, 또는 C## 접두사를 포함한 이름 사용
SQL Developer 접속 불가 Oracle 서비스 미실행 또는 방화벽 차단 서비스 관리자에서 Oracle 서비스 실행 확인, 방화벽에서 1521 포트 허용, 호스트명을 localhost 또는 127.0.0.1로 변경 시도
싱글쿼트(’) 입력 시 에러 발생 입력값이 쿼리에 직접 삽입되어 쿼리 구조 파괴 이는 SQL Injection 취약점의 증거, Prepared Statement로 수정 필요
WHERE 조건이 예상대로 동작하지 않음 AND/OR 논리 연산자 우선순위 혼동 AND가 OR보다 우선순위 높음, 괄호()로 명확히 우선순위 지정

Today’s Insight:

웹 애플리케이션 보안의 시작은 ‘사용자 입력을 절대 신뢰하지 말라’는 원칙에서 출발합니다. HTTP는 Stateless하고 1회성 연결이라는 특성 때문에 Session/Cookie로 상태를 관리해야 하며, 이 과정에서 다양한 보안 취약점이 발생할 수 있습니다. 특히 오늘 학습한 SQL Injection은 입력값이 쿼리에 직접 삽입될 때 발생하는 가장 치명적인 취약점 중 하나입니다. Prepared Statement 사용, 입력값 검증, 에러 메시지 필터링이라는 3가지 방어 원칙만 제대로 지켜도 대부분의 SQL Injection 공격을 차단할 수 있다는 점을 깨달았습니다.