회원가입 | 고객센터 |
DESIGNONEX
디자인원엑스
Q&A
지식공유
공지사항
DX마켓
통계
로그인 회원가입
고객센터

DX Security — Cookie Attribute 보안 플러그인

D DX관리자
2026.09.02 00:58 4 0



DX Security — Cookie Attribute 보안 v1.0.0 안내서

DesignOneX CMS Cookie 보안 기업 납품 수준 강화 플러그인
PHP 5.6+ · IIS / Apache / Nginx · 공유호스팅 완전 호환
코어(Auth.php / Secure.php / session_extend.php) 수정 없음 — 훅으로만 동작
기업 납품 요구사항 COOKIE-001~008 완전 준수
OWASP Session Management Cheat Sheet 준수



목차

  1. Cookie 보안이 왜 중요한가
  2. DXCMS 코어의 현재 Cookie 보안 수준
  3. 코어의 실제 버그와 미비점
  4. 설치 방법
  5. 방어층 상세 설명
    • CA1. Cookie Policy Registry — 중앙 정책 관리
    • CA2. dx_remember SameSite 통일
    • CA3. 삭제 시 Secure=false 버그 수정
    • CA4. csrf_refresh 세션 쿠키 속성 통일
    • CA5. __Host- Cookie Prefix 지원
    • CA6. 로그아웃 시 모든 인증 Cookie 완전 제거
    • CA7. Cookie Injection 방어 — 입력값 검증
    • CA8. 보안 감사 로그
  6. 훅 실행 타이밍 전체 흐름
  7. 보안 로그 읽는 법
  8. Cookie Inventory — 기업 보안감사 대응
  9. 보안 강점 요약 — 기업 납품 요구사항 준수 현황
  10. 방어하지 못하는 영역
  11. __Host- Prefix 활성화 방법
  12. 개발자 연동 가이드 — 표준 함수 사용법
  13. 자주 묻는 질문


1. Cookie 보안이 왜 중요한가

Session ID, Remember Me Token 등 인증 정보는 Cookie를 통해 브라우저와 서버 사이를 오갑니다. Cookie 속성 하나의 누락이 치명적인 보안 취약점으로 이어집니다.


Cookie 속성별 방어 대상

Secure   — HTTPS에서만 전송
           → 네트워크 도청(패킷 스니핑)으로 Cookie 탈취 방어
           → HTTP 평문 구간에서 Cookie 노출 방지

HttpOnly — JavaScript 접근 차단
           → XSS 공격으로 document.cookie 읽기 방어
           → 악성 스크립트가 Session ID 탈취 시도 방어

SameSite — Cross-Site 요청에서 Cookie 전송 제한
           → CSRF 공격의 보조 방어층
           → Lax: 최상위 GET 탐색은 허용, Cross-Site POST는 차단
           → Strict: 모든 Cross-Site 요청 차단

Path     — Cookie 전송 경로 제한
           → /admin Path Cookie가 /board에서 전송되지 않도록

Domain   — Cookie 전송 도메인 제한
           → 미지정 시 현재 Host만 (Subdomain 제외)
           → 지정 시 Subdomain 포함 → Cookie Shadowing 위험

__Host-  — 브라우저 레벨 Secure+Domain없음+Path=/ 강제
           → Subdomain 공격으로 Cookie 덮어쓰기 방어


Cookie 속성 하나 누락의 실제 위험

Secure 없음:
  HTTP 요청에서도 Cookie 전송
  → 공개 Wi-Fi에서 세션 탈취 가능

HttpOnly 없음:
  <script>document.cookie</script>Session ID 탈취
  → XSS 1개로 계정 장악

SameSite 없음:
  Cross-Site POST 요청에 Cookie 자동 첨부
  → CSRF Token 없이도 CSRF 가능 (구버전 브라우저)

삭제 시 Secure 불일치:
  set: Secure Cookie
  delete: Non-Secure Cookie
  → 브라우저가 다른 Cookie로 인식 → 실제 삭제 안 됨


2. DXCMS 코어의 현재 Cookie 보안 수준

코어 Secure.php initSession()을 분석한 결과입니다.


세션 Cookie (코어 initSession())

// Secure.php 실제 코드
@ini_set('session.use_only_cookies',  1);  // URL 세션 금지
@ini_set('session.cookie_httponly',   1);  // HttpOnly
@ini_set('session.cookie_path',       '/'); // Path=/
@ini_set('session.cookie_lifetime',   86400); // 24시간
@ini_set('session.cookie_secure',     1);   // Secure (HTTPS)
@ini_set('session.cookie_samesite',   'Lax'); // PHP 7.3+
@ini_set('session.use_strict_mode',   1);   // PHP 7.1+
속성 상태 평가
HttpOnly 완벽
Secure ✅ HTTPS 자동 완벽
SameSite=Lax ✅ PHP 7.3+ 완벽
use_only_cookies URL 세션 차단
use_strict_mode ✅ PHP 7.1+ 미발급 세션 거부
Path=/ 완벽
Domain ✅ 미지정 현재 Host만
__Host- Prefix 이 플러그인 선택 적용

세션 Cookie 자체 평가: 9/10 — 매우 우수


Remember Me Cookie (코어 Auth.php)

코어에서 dx_remember 쿠키를 발급하는 코드:

// Auth.php — setcookie 실제 코드
setcookie('dx_remember', $userId.':'.$newToken,
    time() + 2592000, '/', '', $isHttps, true);
//                           ↑Path ↑Domain ↑Secure ↑HttpOnly
// SameSite 속성 없음 ←──────────────────────────────────────
속성 상태 평가
HttpOnly 완벽
Secure ✅ HTTPS 완벽
SameSite 없음 이 플러그인 추가
Path=/ 완벽
Domain ✅ 미지정 완벽


삭제 코드의 치명적 버그

// Auth.php — 쿠키 삭제 실제 코드 (여러 곳)
setcookie('dx_remember', '', time() - 3600, '/', '', false, true);
//                                                  ↑
//                                           Secure=false 하드코딩!
//                                           HTTPS 환경에서도 false


HTTPS 환경에서 발생하는 실제 문제:

발급: Set-Cookie: dx_remember=42:abc...; Secure; HttpOnly
삭제: Set-Cookie: dx_remember=; Secure 없음; HttpOnly

브라우저 판단:
  Secure Cookie와 Non-Secure Cookie는 다른 Cookie
  → 삭제 요청이 발급된 쿠키에 적용되지 않음
  → 로그아웃해도 dx_remember 쿠키가 브라우저에 남음
  → 자동 로그인 쿠키가 만료(30일)까지 브라우저에 유지


3. 코어의 실제 버그와 미비점

코어 소스를 직접 분석한 결과입니다.


버그 1: dx_remember 삭제 시 Secure=false 하드코딩

// Auth.php의 tryRememberMe(), login(), loginById(), logout()
// 모든 삭제 경로에서 동일하게 발생
setcookie('dx_remember', '', time() - 3600, '/', '', false, true);
//                                                  ↑ HTTPS에서도 false

영향: HTTPS 사이트에서 로그아웃해도 Remember Me 쿠키가 30일간 브라우저에 남음


버그 2: session_extend.php의 삭제도 동일 버그

// session_extend.php — 5곳 모두 동일
setcookie($cookieName, '', time() - 3600, '/', '', false, true);


미비점 1: dx_remember에 SameSite 없음

발급 경로 4곳 모두:

Auth::login()          → setcookie(..., $isHttps, true)  // SameSite 없음
Auth::loginById()      → setcookie(..., $isHttps, true)  // SameSite 없음
Auth::tryRememberMe()  → setcookie(..., $isHttps, true)  // SameSite 없음
session_extend.php     → setcookie(..., $isHttps, true)  // SameSite 없음


미비점 2: csrf_refresh.php 세션 쿠키 직접 재발급

// csrf_refresh.php
@setcookie(session_name(), session_id(), time() + 86400, '/', '', $isHttps, true);
// SameSite 없음 — Secure.php initSession()의 설정과 별개로 동작

Heartbeat(30초마다 호출)가 SameSite 없는 세션 쿠키를 재발급하여 브라우저의 세션 쿠키 속성을 덮어씁니다.


미비점 3: Cookie 정책 중앙 관리 없음

setcookie() 호출 위치:
  Auth.php          — 9곳
  session_extend.php — 5곳
  csrf_refresh.php  — 1곳
  합계: 15곳에 분산

각각 다른 속성으로 Cookie를 발급하면 정책 불일치가 발생하고, 코드 리뷰에서 누락을 확인하기 어렵습니다.



4. 설치 방법

4-1. 파일 배치

(DXCMS 루트)/
└── plugins/
    └── dx-security-cookie/
        ├── manifest.php
        └── plugin.php


4-2. 관리자 페이지에서 활성화

관리자 → 플러그인 → dx-security-cookie → 활성화

활성화 즉시 모든 이후 로그인·로그아웃·Remember Me 요청에 올바른 Cookie 속성이 적용됩니다.


4-3. 권장 설치 순서

1. dx-security-guard       (Session Fixation, Timeout)
2. dx-security-hijacking   (Session Hijacking, Reuse Detection)
3. dx-security-csrf        (CSRF 방어)
4. dx-security-cookie      (이 플러그인 — Cookie 속성 통합)

단독 설치도 가능합니다.



5. 방어층 상세 설명


CA1. Cookie Policy Registry — 중앙 정책 관리


목적

분산된 15곳의 setcookie() 호출을 단일 정책으로 통합합니다.


Cookie 보안 등급 (기획서 §4.2)

등급 용도 적용
C0 인증 핵심 Session Cookie 최고 보안 필수
C1 장기 인증 Remember Me 최고 보안 필수
C2 보안 토큰 CSRF 토큰 (세션 저장) 해당 없음
C3 기능 UI 설정 중간 보안
C4 분석 통계 최소 보안


Registry 구조

$GLOBALS['_dx_cookie_registry'] = array(
    'session' => array(
        'grade'     => 0,        // C0 — 인증 핵심
        'purpose'   => '세션 식별',
        'httponly'  => true,
        'secure'    => 'auto',   // HTTPS 자동
        'samesite'  => 'Lax',
        'path'      => '/',
        'domain'    => '',       // 미지정 = 현재 Host만
        'max_age'   => 86400,    // 24시간
        'sensitive' => true,     // 값을 로그에 기록하지 않음
    ),
    'remember' => array(
        'grade'     => 1,        // C1 — 장기 인증
        'purpose'   => '자동 로그인 토큰',
        'name'      => 'dx_remember',
        'httponly'  => true,
        'secure'    => 'auto',
        'samesite'  => 'Lax',   // 코어 미적용 → 이 플러그인이 적용
        'path'      => '/',
        'domain'    => '',
        'max_age'   => 2592000, // 30일
        'sensitive' => true,
    ),
);


기업 보안감사 대응

감사관: "시스템에서 사용하는 모든 Cookie를 목록화할 수 있습니까?"dx_cookie_inventory() 함수 호출
                                    ↓
Cookie 이름·목적·등급·보안 속성 전체 즉시 출력


CA2. dx_remember SameSite 통일


문제

코어의 모든 Remember Me 쿠키 발급 경로에 SameSite 속성이 없습니다. Session Cookie에는 SameSite=Lax가 있지만 Remember Me Cookie에는 없어 정책이 불일치합니다.


동작

dx_after_login 훅(priority 8)에서 코어가 발급한 쿠키를 SameSite=Lax 속성으로 즉시 덮어씁니다.

코어 Auth::login()
  → setcookie('dx_remember', value, ...) // SameSite 없음
  → dx_after_login 훅 실행
      → 이 플러그인 (priority 8)
          → _dx_ca_set_remember() 호출
          → setcookie('dx_remember', 동일값, ... SameSite=Lax)
          → 브라우저: SameSite=Lax 쿠키로 최종 적용


PHP 버전별 처리

// PHP 7.3+ — samesite 파라미터 직접 지원
setcookie('dx_remember', $value, [
    'expires'  => time() + 2592000,
    'samesite' => 'Lax',  // 네이티브 지원
    'secure'   => $isHttps,
    'httponly' => true,
]);

// PHP 5.6~7.2 — path에 직접 주입하는 호환 방식
setcookie('dx_remember', $value,
    time() + 2592000,
    '/; SameSite=Lax',  // path에 주입
    '',                  // domain 없음
    $isHttps,
    true
);


CA3. 삭제 시 Secure=false 버그 수정


문제 (코드 레벨)

// 코어 Auth.php — 발급
setcookie('dx_remember', $userId.':'.$token, time()+2592000, '/', '', $isHttps, true);
//                                                                     ↑Secure=HTTPS

// 코어 Auth.php — 삭제 (버그)
setcookie('dx_remember', '', time()-3600, '/', '', false, true);
//                                              ↑Secure=false 항상!


HTTPS 환경에서 실제로 발생하는 현상

브라우저 Cookie 저장소:
  dx_remember (Secure)    = "42:abc..." ← 로그인 시 발급된 쿠키
  dx_remember (Non-Secure)= ""          ← 삭제 요청 (다른 쿠키!)

결과:
  삭제 요청이 적용되지 않음
  브라우저에는 여전히 Secure Cookie 유지
  → 로그아웃해도 자동 로그인 쿠키 30일간 유지


이 플러그인의 수정

dx_after_logout 훅(priority 8)에서 올바른 속성으로 덮어씁니다.

// 이 플러그인 — 발급과 동일한 Secure 속성으로 삭제
_dx_ca_set_cookie('dx_remember', '', time() - 86400);
// → Secure=$isHttps (현재 HTTPS 상태 자동 반영)
// → SameSite=Lax
// → HttpOnly=true
// → Path=/


CA4. csrf_refresh.php 세션 쿠키 속성 통일


문제

csrf_refresh.php는 글쓰기 중 Heartbeat(30초마다)로 세션 수명을 연장할 때 세션 쿠키를 직접 재발급합니다.

// csrf_refresh.php
@setcookie(session_name(), session_id(), time() + 86400, '/', '', $isHttps, true);
// SameSite 없음 — 30초마다 이 쿠키로 덮어쓰여짐

30초마다 SameSite 없는 세션 쿠키가 재발급되어 브라우저의 세션 쿠키 속성이 덮어씌워집니다.


이 플러그인의 수정

dx_after_csrf_refresh 훅(코어에 추가 필요)에서 올바른 속성으로 재설정합니다.

// _dx_ca_refresh_session_cookie()
setcookie(session_name(), session_id(), time()+86400, array(
    'samesite' => 'Lax',
    'secure'   => $isHttps,
    'httponly' => true,
    'path'     => '/',
    'domain'   => '',    // Domain 미지정 강제
));

코어 연동 필요: csrf_refresh.phpdx_run_hook('dx_after_csrf_refresh', []) 추가가 필요합니다.



CA5. __Host- Cookie Prefix 지원


__Host- Prefix란

브라우저가 다음 3가지 조건을 강제합니다:

__Host-로 시작하는 Cookie는:
  ① Secure 속성 필수 (HTTP에서 발급 자체 거부)
  ② Domain 속성 금지 (있으면 브라우저가 저장 거부)
  ③ Path=/ 필수

결과:
  Subdomain에서 절대 Cookie 덮어쓰기 불가
  → Cookie Shadowing 공격 완전 방어


Subdomain Cookie Shadowing 공격이란

공격자가 attacker.example.com 을 탈취
  ↓
Set-Cookie: DXSESSID=악성값; Domain=example.com; Path=/
  ↓
example.com의 세션 쿠키를 공격자 값으로 덮어씀
  ↓
Session Fixation 공격 성공

__Host-DXSESSID 사용 시:
  Domain 속성 있으면 브라우저가 저장 자체를 거부
  → 덮어쓰기 불가능


활성화 방법

plugin.php에서:

define('DX_COOKIE_HOST_PREFIX', true);  // false → true로 변경


중요 주의사항:

  • HTTPS 환경에서만 동작 (HTTP에서는 브라우저가 거부)
  • 변경 시 기존 로그인 세션 전부 무효화 → 유지보수 시간에 변경
  • 기존 설치: Migration 후 변경 권장


CA6. 로그아웃 시 모든 인증 Cookie 완전 제거

기업 납품 원칙 (기획서 §4.19)

로그아웃 시 삭제해야 할 Cookie:
  ① 세션 Cookie (코어 Auth::logout() → Security Guard 플러그인)
  ② Remember Me Cookie (이 플러그인)

삭제 원칙:
  발급 시와 동일한 Path / Domain / Secure / SameSite / HttpOnly 속성 사용


이 플러그인의 보장

dx_after_logout 훅 (priority 8)
  ↓
_dx_ca_clear_remember($userId)
  ↓
_dx_ca_set_cookie('dx_remember', '', time()-86400)
  ↓
Secure=$isHttps (HTTPS 자동 감지)
SameSite=Lax
HttpOnly=true
Path=/
Domain='' (미지정)
  ↓
CA:REMEMBER_CLEARED_LOGOUT 로그 기록


CA7. Cookie Injection 방어 — 입력값 검증

공격 원리

공격자가 직접 조작한 Cookie 값을 전송:
  Cookie: dx_remember=1:INVALID\r\nSet-Cookie: admin=1
                        ↑ 헤더 인젝션 시도


검증 항목 (매 요청 dx_extend_top priority 1)

① 길이: 최대 128자 (userId 10자 + ':' + token 64자 + 여유)
② 제어문자: \x00~\x1f, \r, \n, ;, ,, \\ 없음
③ 형식: "양의정수:64자리소문자16진수"
④ userId: 양의 정수이며 변환 손실 없음
⑤ token: 정확히 [0-9a-f]{64} 패턴


비정상 쿠키 발견 시

1. 즉시 삭제 (_dx_ca_clear_remember())
2. $_COOKIE['dx_remember'] 제거 (현재 요청에서 차단)
3. CA:COOKIE_INJECTION_BLOCKED 로그 기록
4. Auth.php에 도달하기 전에 차단 완료


정상 token 패턴 예시

[0-9a-f]{64}
예: a8f9c2d1e0b3f456789abcdef0123456789abcdef0123456789abcdef012345


CA8. 보안 감사 로그

기업 보안감사에서 Cookie 관련 이벤트 추적이 가능합니다.

이벤트 타입 발생 시점
CA:REMEMBER_ISSUED Remember Me 쿠키 발급 (SameSite 포함)
CA:REMEMBER_CLEARED Remember Me 쿠키 삭제
CA:REMEMBER_CLEARED_LOGOUT 로그아웃 시 올바른 속성으로 쿠키 삭제
CA:REMEMBER_SAMESITE_APPLIED 로그인 후 SameSite 속성 적용
CA:SESSION_COOKIE_REFRESHED csrf_refresh 후 세션 쿠키 속성 통일
CA:COOKIE_INJECTION_BLOCKED 비정상 쿠키 형식 감지 및 차단
CA:COOKIE_AUDIT_WARN HTTP 전송 인증 쿠키 감지
CA:HOST_PREFIX_SET __Host- Prefix 세션 이름 변경 완료


6. 훅 실행 타이밍 전체 흐름

[모든 요청]
      
index.php DxExtend::runTop()
  └── dx_extend_top 
        ├── priority  1: dx-security-cookie [CA7] Cookie Injection 검증   플러그인
                      (Auth보다 먼저  비정상 쿠키 차단)
        ├── priority  1: dx-security-guard (session_version 검증)
        ├── priority  2: dx-security-hijacking (Session Guard)
        ├── priority  3: dx-security-hijacking (관리자 재인증)
        ├── priority  5: dx-security-csrf (CSRF Pipeline)
        └── priority 10: dx-security-cookie [CA8] Cookie 감사   플러그인

[로그인 성공]
  Auth::login()  dx_after_login
        ├── priority 1,2: dx-security-guard (세션 ID 재생성)
        ├── priority   5: dx-security-hijacking (Risk 초기화)
        ├── priority   8: dx-security-cookie [CA2] SameSite 적용   플러그인
        └── priority  10: dx-security-csrf (CSRF 토큰 Rotation)

[로그아웃]
  Auth::logout()  dx_after_logout
        ├── priority 1: dx-security-guard (세션 파기)
        ├── priority 5: dx-security-hijacking (Remember 쿠키 삭제)
        ├── priority 8: dx-security-cookie [CA3][CA6] 올바른 속성으로 삭제   플러그인
        └── priority 10: dx-security-csrf (CSRF 토큰 폐기)

[csrf_refresh (Heartbeat)]
   dx_after_csrf_refresh (코어 추가 필요)
        └── priority 1: dx-security-cookie [CA4] 세션 쿠키 속성 통일   플러그인


7. 보안 로그 읽는 법

data/security.log에 기록됩니다.


로그 형식

[날짜 시각][CA:이벤트타입][IP:주소][UA:유저에이전트] 메시지


로그 예시 및 해석

# 정상 로그인 — SameSite 적용 완료
[2026-09-01 09:00:01][CA:REMEMBER_SAMESITE_APPLIED][IP:121.131.x.x][UA:Mozilla/5.0...]
user_id=42 login — SameSite=Lax applied

# 로그아웃 — 올바른 속성으로 삭제 (Secure=yes)
[2026-09-01 18:30:22][CA:REMEMBER_CLEARED_LOGOUT][IP:121.131.x.x][UA:Mozilla/5.0...]
user_id=42 proper-secure-delete applied

# Cookie Injection 시도 차단
[2026-09-01 14:22:10][CA:COOKIE_INJECTION_BLOCKED][IP:45.33.x.x][UA:python-requests/2.28]
reason=INVALID_TOKEN_FORMAT val_len=200

# Cookie 형식 오류 (공격 도구가 비정상 형식 사용)
[2026-09-01 16:45:03][CA:COOKIE_INJECTION_BLOCKED][IP:58.29.x.x][UA:curl/7.68.0]
reason=INVALID_CHARS val_len=85

# HTTP 환경에서 인증 쿠키 감지 경고
[2026-09-01 20:11:44][CA:COOKIE_AUDIT_WARN][IP:121.131.x.x][UA:Mozilla/5.0...]
issues=SESSION_ON_HTTP https=no

⚠️ Cookie 값 원문은 절대 로그에 기록하지 않습니다. (COOKIE-008 준수)



8. Cookie Inventory — 기업 보안감사 대응

기업 보안감사 질문

"시스템에서 사용하는 모든 Cookie를 목록화할 수 있습니까?"
"각 Cookie의 보안 속성이 정책을 준수합니까?"
"민감 정보를 Cookie에 저장하지 않습니까?"


Cookie Inventory 출력

// 관리자 코드 또는 보안감사 전용 페이지에서
$inventory = dx_cookie_inventory();

foreach ($inventory as $cookie) {
    echo $cookie['name'] . ': ';
    echo 'Secure=' . $cookie['secure'] . ' ';
    echo 'HttpOnly=' . $cookie['httponly'] . ' ';
    echo 'SameSite=' . $cookie['samesite'];
    echo PHP_EOL;
}


출력 예시 (DXCMS v9.0.0 + 이 플러그인)

Cookie 목적 등급 Secure HttpOnly SameSite Domain Path 만료
DXSESSID 세션 식별 C0 ✅ HTTPS Lax 없음 / 24시간
dx_remember 자동 로그인 C1 ✅ HTTPS Lax (이 플러그인 추가) 없음 / 30일


9. 보안 강점 요약 — 기업 납품 요구사항 준수 현황

기업 납품 MUST NOT 요구사항 (COOKIE-001~008)

요구사항 내용 코어 이 플러그인 상태
COOKIE-001 인증 Cookie HttpOnly 제거 금지 ✅ 유지 PASS
COOKIE-002 HTTPS 운영환경 Secure 제거 금지 ✅ 삭제버그 수정 PASS
COOKIE-003 SameSite=None 임의 사용 금지 PASS
COOKIE-004 Domain=상위도메인 임의 설정 금지 ✅ Domain='' 강제 PASS
COOKIE-005 Session ID를 localStorage로 이동 금지 PASS
COOKIE-006 Session ID를 URL에 포함 금지 ✅ use_only_cookies PASS
COOKIE-007 민감정보 Cookie 평문 저장 금지 ✅ Opaque Token PASS
COOKIE-008 Cookie Token 로그 평문 기록 금지 ✅ 준수 PASS


기업 납품 평가 배점 (기획서 §4.31)

평가 영역 배점 코어 이 플러그인 합계
Secure 10 10 10
HttpOnly 10 10 10
SameSite 10 7 (세션만) +3 (remember 추가) 10
Domain 제한 10 10 10
Path 제한 5 5 5
Cookie Lifetime 10 8 8
Cookie Prefix 10 0 10 (opt-in) 10
Session Cookie 보호 10 10 10
Remember Me 보호 10 7 (버그있음) +3 (버그수정) 10
Cookie 중앙관리 5 0 5 5
Cookie Inventory 5 0 5 5
자동 보안 테스트 5 0 3 3
총점 100 67 +29 96


10. 방어하지 못하는 영역

취약점 이유 추가 대책
XSS로 Cookie 탈취 HttpOnly가 있어도 간접 방법 존재 XSS 플러그인(8번), CSP
HTTP 환경의 Secure Cookie 미동작 환경적 한계 HTTPS 강제 적용
__Host- 미지원 구버전 브라우저 IE 미지원 CA5를 사용하지 않으면 영향 없음
Cookie 도용 후 즉각 감지 수동적 방어 Session Guard(플러그인 2)와 병행


11. __Host- Prefix 활성화 방법

활성화 조건 확인

필수: HTTPS 운영 환경
권장: 신규 설치 또는 유지보수 시간대
주의: 기존 로그인 세션 전부 무효화됨


활성화 절차

// 1. plugin.php에서 상수 변경
define('DX_COOKIE_HOST_PREFIX', true);  // false → true

// 2. 저장 후 관리자 페이지에서 플러그인 재활성화

// 3. 기존 사용자에게 공지:
//    "보안 업데이트로 자동 로그아웃됩니다. 다시 로그인하세요."


활성화 후 세션 쿠키 이름

변경 전: PHPSESSID (또는 DXSESSID)
변경 후: __Host-DXSESSID


브라우저 지원 현황

브라우저 __Host- 지원
Chrome 49+
Firefox 75+
Safari 12+
Edge 79+
IE 모든 버전

IE 사용자가 있는 환경에서는 DX_COOKIE_HOST_PREFIX=false 유지를 권장합니다.



12. 개발자 연동 가이드 — 표준 함수 사용법

이 플러그인은 Cookie 발급·삭제를 위한 표준 함수를 제공합니다. 새로 개발하는 플러그인에서는 코어의 setcookie()를 직접 호출하는 대신 이 함수들을 사용하세요.


Remember Me 쿠키 발급

// 기존 방식 (코어) — SameSite 없음
setcookie('dx_remember', $userId.':'.$token, time()+2592000, '/', '', $isHttps, true);

// 권장 방식 (이 플러그인) — Policy Registry 자동 적용
dx_set_remember_cookie($userId, $token);          // 기본 30일
dx_set_remember_cookie($userId, $token, 604800);  // 7일로 단축


Remember Me 쿠키 삭제

// 기존 방식 (코어) — Secure=false 버그
setcookie('dx_remember', '', time()-3600, '/', '', false, true);

// 권장 방식 (이 플러그인) — 올바른 속성으로 삭제
dx_clear_remember_cookie($userId);


Cookie Inventory 출력

// 관리자 보안 페이지에서
$inventory = dx_cookie_inventory();

echo '<table>';
echo '<tr><th>Cookie</th><th>목적</th><th>Secure</th><th>HttpOnly</th><th>SameSite</th></tr>';
foreach ($inventory as $c) {
    echo '<tr>';
    echo '<td>' . $c['name'] . '</td>';
    echo '<td>' . $c['purpose'] . '</td>';
    echo '<td>' . $c['secure'] . '</td>';
    echo '<td>' . $c['httponly'] . '</td>';
    echo '<td>' . $c['samesite'] . '</td>';
    echo '</tr>';
}
echo '</table>';


Registry에 새 Cookie 등록

플러그인에서 새 Cookie를 발급할 때 Registry에 등록하면 보안감사 자동 포함됩니다.

// 다른 플러그인에서 Registry 확장
add_action('dx_extend_top', function() {
    if (!isset($GLOBALS['_dx_cookie_registry'])) return;

    $GLOBALS['_dx_cookie_registry']['my_plugin_pref'] = array(
        'grade'    => 3,              // C3 — 기능 Cookie
        'purpose'  => '내 플러그인 UI 설정',
        'name'     => 'dx_myplugin_pref',
        'httponly' => false,          // JS가 읽어야 함
        'secure'   => 'auto',
        'samesite' => 'Strict',
        'path'     => '/',
        'domain'   => '',
        'max_age'  => 31536000,       // 1년
        'sensitive'=> false,
    );
});


13. 자주 묻는 질문

Q. 코어에 이미 HttpOnly, Secure, SameSite가 있는데 이 플러그인이 필요한가요?

세션 Cookie 속성은 코어가 잘 처리하고 있습니다. 이 플러그인은 3가지 핵심 문제를 해결합니다: ① dx_remember 쿠키에 SameSite 없음, ② 삭제 시 Secure=false 하드코딩 버그, ③ csrf_refresh.php가 SameSite 없이 세션 쿠키 재발급. 기업 납품 보안감사에서 이 3가지는 반드시 지적됩니다.


Q. dx_remember 삭제 버그가 실제로 문제가 되나요?

HTTPS 사이트에서 로그아웃해도 Remember Me 쿠키가 브라우저에 30일간 남습니다. 공용 컴퓨터에서 로그아웃 후 자동 로그인이 여전히 가능한 상태가 됩니다. 이 플러그인 설치 후 즉시 수정됩니다.


Q. __Host- Prefix를 활성화하면 Remember Me도 변경되나요?

현재 구현에서 __Host- Prefix는 세션 Cookie(session_name())에만 적용됩니다. dx_remember는 별도 마이그레이션이 필요하므로 현재 버전에서는 적용하지 않습니다. 향후 버전에서 __Host-DXREMEMBER 지원이 추가될 예정입니다.


Q. Cookie Injection 검증이 정상 사용자를 차단하지 않나요?

정상 쿠키는 코어 Auth.phpSecure::randomHex(64)로 생성한 64자리 소문자 16진수 토큰입니다. 이 형식을 정확히 검증하므로 정상 사용자는 차단되지 않습니다. 이상한 형식의 쿠키(조작·인젝션 시도)만 차단됩니다.


Q. csrf_refresh.php에 직접 훅을 추가해야 하나요?

CA4 기능의 완전한 동작을 위해서는 csrf_refresh.php 파일에 dx_run_hook('dx_after_csrf_refresh', []) 한 줄 추가가 필요합니다. 코어 파일이므로 업데이트 시 덮어씌워질 수 있음을 고려하세요. 훅을 추가하지 않아도 나머지 CA1~CA8은 모두 정상 동작합니다.


DX Security — Cookie Attribute 보안 v1.0.0 — DesignOneX
https://designonex.com
 

라이선스

디자인원엑스 라이선스 참고
https://designonex.com/notice/view/1787577858493247

첨부파일 1개 회원전용

댓글0

로그인 후 댓글을 작성할 수 있습니다.
Plugin 43
45
전체 회원
1,366
전체 게시글
2,731
전체 댓글
30
오늘 방문
53,422
전체 방문
0
현재 접속
인기글 7일 이내
최신글
최신댓글
내 플레이리스트
플레이리스트가 비어있습니다
스튜디오 게시판에서
플레이리스트에 담기 버튼을
눌러보세요
목록
목록