""" GUARDiA 준수성 자동 점검 엔진 1. 시큐어코딩 (행안부 SW 보안약점 기준 + OWASP Top 10) 2. 웹 접근성 (WCAG 2.1 / KWCAG 2.1 — 한국형) 3. 개인정보보호법 (PIPA — 개인정보 식별자 탐지) """ from __future__ import annotations import ast import re import os import logging from datetime import datetime from pathlib import Path from typing import Any logger = logging.getLogger(__name__) # ── 1. 시큐어코딩 점검 ─────────────────────────────────────────────────────── # 행안부 SW 보안약점 주요 패턴 SECURE_CODING_RULES = [ # SQL 인젝션 { "id": "SC-001", "category": "SQL 인젝션", "severity": "CRITICAL", "pattern": r'execute\s*\(\s*f["\'].*\{|execute\s*\(\s*".*%.*%|execute\s*\(\s*\'.*\'\.format\(', "message": "SQL 문자열 직접 포맷팅 — 파라미터 바인딩 사용 필요", }, # XSS { "id": "SC-002", "category": "XSS", "severity": "HIGH", "pattern": r'innerHTML\s*=\s*(?!"|\')|\.html\s*\(', "message": "innerHTML 직접 삽입 — textContent 또는 escapeHtml 함수 사용 필요", }, # 하드코딩 비밀번호/키 { "id": "SC-003", "category": "하드코딩 자격증명", "severity": "CRITICAL", "pattern": r'(?i)(password|passwd|secret|api_key|apikey|token)\s*=\s*["\'][^"\']{6,}["\']', "message": "하드코딩된 자격증명 — 환경변수 또는 시크릿 관리자 사용 필요", }, # OS 명령어 인젝션 { "id": "SC-004", "category": "OS 명령어 인젝션", "severity": "CRITICAL", "pattern": r'os\.system\s*\(|subprocess\.call\s*\(.*shell\s*=\s*True|eval\s*\(', "message": "shell=True 또는 eval 사용 — 입력값 검증 필수", }, # 경로 조작 { "id": "SC-005", "category": "경로 조작", "severity": "HIGH", "pattern": r'open\s*\(\s*.*\+|open\s*\(\s*f["\']', "message": "사용자 입력 기반 파일 경로 — Path.resolve().relative_to() 검증 필수", }, # 정보 노출 { "id": "SC-006", "category": "민감 정보 노출", "severity": "MEDIUM", "pattern": r'traceback\.print_exc\(\)|print\s*\(.*exception|logger\.(info|debug).*password', "message": "예외 스택트레이스 직접 출력 — 상세 오류 메시지 은닉 필요", }, # CSRF 위험 (GET으로 상태 변경) { "id": "SC-007", "category": "CSRF", "severity": "MEDIUM", "pattern": r'@router\.get\s*\([^\)]+\)\s*\nasync def.*(delete|remove|drop|truncate)', "message": "GET 메서드로 데이터 변경 — POST/DELETE 사용 및 CSRF 토큰 적용 필요", }, # 취약한 암호화 { "id": "SC-008", "category": "취약 암호화", "severity": "HIGH", "pattern": r'md5|sha1\s*\(|DES\.|RC4\.', "message": "취약한 해시/암호화 알고리즘 — SHA-256 이상 또는 AES-256-GCM 사용 필요", }, ] # ── 2. 웹 접근성 점검 (HTML 기반) ──────────────────────────────────────────── ACCESSIBILITY_RULES = [ { "id": "WA-001", "category": "대체 텍스트", "level": "A", "pattern": r']*alt=)[^>]*>', "message": "img 요소에 alt 속성 없음 — 시각 장애인 스크린리더 접근 불가", }, { "id": "WA-002", "category": "색상 대비", "level": "AA", "pattern": r'color:\s*#(?:aaa|999|bbb|ccc|ddd|eee|f{3,6})', "message": "낮은 색상 대비 — 4.5:1 이상 비율 필요 (WCAG 2.1 AA)", }, { "id": "WA-003", "category": "키보드 접근성", "level": "A", "pattern": r'onclick="[^"]*"(?![^>]*tabindex)', "message": "onclick만 있는 요소 — tabindex + onkeydown 추가 또는