보안 수칙
서드파티 자료가 지켜야 할 보안 수칙입니다. 여기 있는 항목은 실제 사고 유형에서 나온 것입니다.
출력: 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 쿼리가 없는가
- 업로드 확장자·크기 검사가 서버에 있는가
- 비밀값이 평문으로 저장되거나 웹에 노출되는 경로에 있지 않은가