Skip to content

v1.11.8

Choose a tag to compare

@github-actions github-actions released this 02 Sep 07:20
· 53 commits to main since this release

Relio v1.11.8 — 검색어의 %_를 와일드카드가 아닌 글자로 처리

고객 검색창에 50%를 입력하면 50이 들어간 모든 고객이 나오고, _는 아무 글자 하나와 일치했으며, % 한 글자만 넣으면 목록 전체가 반환되었습니다. 입력한 그대로 찾을 방법이 없었습니다.

1. 원인

모든 자유 검색 질의가 사용자가 입력한 문자열을 SQL 안에서 그대로 이어 붙였습니다.

lower(c.name) LIKE '%'||lower($4)||'%'

PostgreSQL의 LIKE에서 %는 임의의 문자열, _는 임의의 한 글자를 뜻합니다. 검색어에 포함된 이 두 글자가 패턴의 일부로 해석되어, 사용자가 찾으려던 글자가 아니라 와일드카드로 동작했습니다. 관리자 Audit Log 검색도 ILIKE로 같은 문제를 가지고 있었습니다.

검색어 수정 전 수정 후
50% 50이 들어간 모든 레코드 이름에 50%가 든 레코드
AB_C ABxC, AB1C 등도 일치 AB_C가 든 레코드
% 목록 전체 %가 든 레코드
back\slash 백슬래시가 이스케이프 문자로 소비됨 back\slash가 든 레코드

SQL Injection은 아닙니다. 값은 처음부터 Bind Parameter로 전달되었고, 문제는 전달된 값이 패턴 문법으로 읽힌 것입니다.

2. 수정

  • crm.SearchPattern이 Go 쪽에서 패턴을 만듭니다. 백슬래시와 %, _를 이스케이프한 뒤 앞뒤에 %를 붙입니다
  • 자유 검색 7개 질의 — 고객, 영업기회, 리드, 제품, 담당자, 협업자, 관리자 Audit Log — 가 모두 LIKE $n ESCAPE '\'를 선언합니다
  • 빈 검색어는 빈 패턴을 그대로 돌려줍니다. 각 질의 앞의 $n='' 무필터 가드가 그대로 유지되므로, 검색어 없이 목록을 여는 동작은 이전과 동일합니다
  • 대소문자 구분 없는 검색과 앞뒤 공백 제거 동작도 이전과 동일합니다

3. 재발 방지

새로 추가되는 검색이 조용히 같은 문제를 들여오지 않도록, internal/ 전체의 Go 원본을 훑어 ESCAPE 없는 LIKE·ILIKE를 발견하면 실패하는 Test를 두었습니다.

검증

  • 단위 Test 3개 추가: 이스케이프 결과, 공백 검색어가 빈 패턴을 유지하는지, ESCAPE 없는 검색 질의 회귀 가드
  • Go 전체 Test/Vet (go test -race ./..., go vet ./...), gofmt
  • TypeScript Typecheck와 React Production Build
  • 환경변수 계약(check-env-contract.sh)과 외부 정적 Asset 차단(check-static-assets.sh)

업그레이드

DB Migration은 없습니다. 화면과 API 계약도 그대로이며, 저장된 데이터에는 영향이 없습니다.

검색 결과만 좁아집니다. 지금까지 %_가 든 검색어로 더 넓은 결과를 얻고 있었다면, 이번 Release 이후에는 입력한 문자열이 그대로 포함된 레코드만 나옵니다.

오프라인 이미지

항목
Asset relio-v1.11.8.tar.gz
Docker Image relio:v1.11.8
SHA-256 c286ac3837e733b944c5c7e3c63202216cefd15a8319e95dd4b7faf3025b2fce
압축 크기 36M
Architecture linux/amd64

이 Release가 직접 제공하는 Asset은 위 Docker Image tar.gz 하나뿐입니다.

오프라인 서버에서 로드

gunzip -c relio-v1.11.8.tar.gz | docker load
docker image inspect relio:v1.11.8

실행

# 최초 1회만 생성하고 비밀번호 관리 도구에 보관하세요.
ENCRYPTION_KEY="$(openssl rand -hex 32)"

docker run -d \
  --name relio \
  -p 8080:8080 \
  -e POSTGRES_DSN="postgres://relio:password@postgres:5432/relio" \
  -e BOOTSTRAP_ADMIN="admin" \
  -e BOOTSTRAP_ADMIN_PASSWORD="ChangeMe-Immediately" \
  -e ENCRYPTION_KEY="$ENCRYPTION_KEY" \
  -v relio-data:/var/lib/relio \
  relio:v1.11.8

Relio Application이 받는 환경변수는 필수 3개(POSTGRES_DSN, BOOTSTRAP_ADMIN, BOOTSTRAP_ADMIN_PASSWORD)와 선택 1개(ENCRYPTION_KEY)뿐입니다.

ENCRYPTION_KEY를 설정하면 Personal Key와 SSO Client Secret이 재기동, 이미지 교체, relio-data Volume 재생성 후에도 유지됩니다. 설정하지 않으면 자격증명을 여는 Key가 Volume 안에만 존재하므로 /var/lib/relio를 PostgreSQL과 같은 복구 시점으로 반드시 보존해야 합니다.

검증

Release 전에 Source Test, TypeScript Typecheck, Frontend Build, Go Vet, 환경변수 계약, 외부 정적 Asset 차단, 비 Root 실행, 완전 격리 Network 신규 설치 Smoke Test, 이전 Release 업그레이드 Test, Docker Save/Load 재검증을 통과합니다.