개발자 가이드

보안 수칙

서드파티 자료가 지켜야 할 보안 수칙입니다. 여기 있는 항목은 실제 사고 유형에서 나온 것입니다.

출력: XSS

  • 사용자 입력을 출력할 때는 항상 {{ }} (이스케이프)를 쓰세요.
  • {!! !!} 는 코어가 정화한 HTML(에디터 본문 getContent())에만 쓰세요. 정화되지 않은 값을 넣는 순간 XSS입니다.
  • JS 문맥에 값을 넣을 때는 @json($value) 또는 |escapejs 필터를 쓰세요. 문자열 이어붙이기로 스크립트를 만들지 마세요.

입력: 검증은 서버에서

  • 화면(JS)의 검증은 편의일 뿐입니다. 모든 검증은 proc 액션(서버)에서 다시 하세요.
  • 숫자는 (int) 캐스팅, 허용 목록이 있는 값은 in_array(..., true) 로 확인하세요.
  • 쿼리 XML의 바인딩을 쓰는 한 SQL 주입은 막히지만, filter="number"notnull 로 한 번 더 조입니다. 조건 없는 update/delete가 되지 않게 핵심 조건에 notnull을 반드시 붙이세요.

CSRF와 액션 설계

  • 데이터를 바꾸는 동작은 반드시 proc 액션 + POST로 만드세요. 코어가 CSRF 토큰을 자동 검사합니다.
  • GET(disp)에서 데이터를 바꾸면 안 됩니다. 링크 하나로 삭제가 실행되는 구조는 CSRF 검사도 우회됩니다.
  • 외부 서버가 호출하는 콜백만 standalone="true" check-csrf="false" 를 붙이고, 그 액션 안에서 자체 검증(서명·상태 토큰·서버간 재확인)을 하세요. 브라우저를 거쳐 온 값은 신뢰하지 마세요.

권한 확인

  • module.xml의 permission 속성에만 의존하지 말고, 소유자 확인이 필요한 동작(내 글 수정 등)은 액션 안에서 member_srl 을 대조하세요.
  • 관리 기능은 permission="manager" + 화면에서도 권한 분기, 두 겹으로 거세요. 화면에서 버튼만 숨기는 것은 보호가 아닙니다.

파일 업로드

  • 확장자는 허용 목록 방식으로 검사하세요 (금지 목록은 우회됩니다).
  • 크기 제한을 두고, 저장 파일명은 원본을 쓰지 말고 새로 만드세요.
  • 실행될 수 있는 파일(.php 등)이 업로드 경로에서 실행되지 않도록, 코어의 파일 모듈 경로(files/attach)를 쓰세요. 웹서버 설정이 이 경로의 PHP 실행을 차단합니다.

비밀값 보관

  • 토큰·키를 DB에 저장할 때는 해시(조회용) 또는 암호화(복호화 필요 시)로 저장하세요. 코어의 Zittme\Framework\Security 에 암호화 도구가 있습니다.
  • 임시 상태 파일을 files/cache 아래에 만들 경우, 웹으로 직접 접근되지 않는지 확인하세요. 웹서버 차단 규칙에 없는 새 경로라면 규칙을 추가해야 합니다. 실제로 이 경로가 HTTP 200으로 노출된 사고가 있었습니다.
  • 자격증명을 코드에 하드코딩하지 마세요. 모듈 설정(insertModuleConfig)에 저장하고 화면에는 마스킹해서 보여주세요.

외부 연동

  • 우리 서버가 받는 콜백: 브라우저 경유 값을 믿지 말고 서버 간 통신으로 재검증하세요 (결제 금액, 인증 결과 등).
  • 인증 코드 교환에는 상태 토큰(state)과 PKCE 같은 표준 보호를 쓰세요.
  • 응답에 불필요한 Set-Cookie가 나가지 않는지 확인하세요. 크로스사이트 콜백에서 세션 쿠키가 새로 발급되면 사용자의 기존 세션을 덮어쓸 수 있습니다.

마지막 점검 목록

  • 사용자 입력이 이스케이프 없이 출력되는 곳이 없는가
  • proc 없이 GET으로 데이터가 바뀌는 곳이 없는가
  • 조건 없는 update/delete 쿼리가 없는가
  • 업로드 확장자·크기 검사가 서버에 있는가
  • 비밀값이 평문으로 저장되거나 웹에 노출되는 경로에 있지 않은가