CI4 Playground v4.7.3
한국어문서
입력 새니타이즈 비교 — esc() vs strip_tags() vs htmlspecialchars() vs sanitizeFilename()
함수결과
왼쪽에 문자열을 입력하고 버튼을 누르세요.
XSS 패턴 → esc() 처리 결과 시각적 비교
원본 입력 (위험!)
esc($input, 'html') — 안전
esc($input, 'js') — JS 컨텍스트
XSS 페이로드를 입력하면 esc() 처리 전/후를 비교할 수 있습니다.
esc() — 컨텍스트별 이스케이프
$input = '<script>alert("xss")</script>';

// HTML 컨텍스트 (기본값)
esc($input);           // <script>...
esc($input, 'html');   // <script>...

// HTML 속성 컨텍스트
// <input value="<?= esc($val, 'attr') ?>">
esc($input, 'attr');

// JavaScript 컨텍스트
// var x = '<?= esc($val, 'js') ?>';
esc($input, 'js');

// URL 컨텍스트
// <a href="<?= esc($url, 'url') ?>">
esc($input, 'url');

// CSS 컨텍스트
esc($input, 'css');
주의: esc()는 출력 시 이스케이프합니다. DB 저장 전에 적용하면 이중 인코딩이 발생합니다. 항상 출력 직전에 사용하세요.
sanitizeFilename() — 파일명 보안
$security = \Config\Services::security();

// 경로 탐색 공격 방어
$filename = '../../../etc/passwd';
$safe = $security->sanitizeFilename($filename);
// 결과: 'etcpasswd'

// 특수문자 제거
$filename = 'my file <script>.php';
$safe = $security->sanitizeFilename($filename);
// 결과: 'my file script.php'

// 파일 업로드 시 실제 사용 예
public function upload()
{
    $file = $this->request->getFile('upload');
    $name = $security->sanitizeFilename(
        $file->getClientName()
    );
    $file->move(WRITEPATH . 'uploads', $name);
}
함수별 특성 비교
함수용도특징권장 컨텍스트
esc($v, 'html') HTML 출력 <>&"' 변환 HTML 본문
esc($v, 'attr') HTML 속성 속성 값 내 특수문자 변환 태그 속성값
esc($v, 'js') JS 인라인 JS 특수문자 이스케이프 script 태그 내
esc($v, 'url') URL URL 인코딩 href, src 속성
strip_tags($v) 태그 제거 HTML 태그 완전 제거 평문 저장
sanitizeFilename() 파일명 경로 탐색, 특수문자 제거 파일 업로드
CSRF 활성화 (Config/Filters.php)
// app/Config/Filters.php
public array $globals = [
    'before' => [
        'csrf',   // 전역 CSRF 활성화
    ],
];

// 특정 라우트만 제외 (예: webhook)
public array $globals = [
    'before' => [
        'csrf' => ['except' => ['webhook/*']],
    ],
];
뷰에서 CSRF 토큰 삽입
// HTML 폼 — 히든 필드 자동 생성
<form method="post">
    <?= csrf_field() ?>
    <!-- <input type="hidden" name="csrf_test_name"
              value="abc123..."> -->
    ...
</form>

// AJAX 요청 — 헤더에 토큰 포함
fetch('/endpoint', {
    method: 'POST',
    headers: {
        'X-CSRF-TOKEN': '<?= csrf_hash() ?>',
    },
    body: formData
});
CSRF 설정 (Config/Security.php)
// app/Config/Security.php
class Security extends BaseConfig
{
    // 토큰 재생성 전략
    // 'cookie' : 요청마다 토큰 재생성 (기본값)
    // 'session': 세션에 토큰 저장
    public string $tokenRandomize = 'cookie';

    // CSRF 토큰 이름 (히든 필드 name)
    public string $tokenName = 'csrf_test_name';

    // CSRF 쿠키 이름
    public string $cookieName = 'csrf_cookie_name';

    // 토큰 만료 시간 (초, 0=세션과 동일)
    public int $expires = 7200;

    // SameSite 속성 (Strict/Lax/None/'')
    public string $samesite = 'Lax';
}
현재 상태: 이 프로젝트는 학습용이라 CSRF 전역 필터가 비활성화되어 있습니다. 운영 환경에서는 반드시 'csrf' 전역 필터를 활성화하세요.