Skip to content

fix: edge_alert_fire authenticated 실행권 회수 — 관리자 알림 위조·폭주 차단 - #210

Merged
seizeh merged 2 commits into
mainfrom
fix/edge-alert-fire-grant
Sep 29, 2026
Merged

seizeh merged 2 commits into
mainfrom
fix/edge-alert-fire-grant

Conversation

@seizeh

@seizeh seizeh commented Sep 28, 2026

Copy link
Copy Markdown
Owner

무엇이

public.edge_alert_fire(엣지 알람 → 원장 위임 definer 래퍼)의 EXECUTE 가 service_role 외에 authenticated 에도 부여돼 있었다. 09-21 알람 통합(#205 계열) 때 생성 기본권한을 회수하지 않은 누락.

왜 문제인가

  • 본문에 호출자 검사가 없는 SECURITY DEFINER — 로그인 사용자 누구나 .rpc('edge_alert_fire', …) 로 임의 제목·본문의 high 우선순위 시스템 알림을 활성 관리자 전원에게 보낼 수 있었다.
  • 쿨다운은 알람 키 단위인데 키가 호출자 입력이라 스팸 억제가 되지 않는다.
  • 같은 계열 rate_limit_hit·get_password_hash 는 이미 service_role 전용 — 이 함수만 빠져 있었다.

조치

  • revoke execute … from authenticated (운영 적용 완료, 20260928031112)
  • 회수 후 실측: authenticated=false · service_role=true
  • t21 §7 권한 단언 추가(plan 17→18) — 재부여 회귀 가드, 운영 직행 18/18 통과
  • 정본 docs/supabase-db.md ops_alarms 절에 래퍼가 service_role 전용임을 명시

검증

  • 운영 DB t21 롤백 실행 18/18 ok
  • 악용 흔적 점검은 불가 영역(호출 로그 없음) — 단, ops_alarms 원장에 edge: 접두 이상 키 없음 확인

🤖 Generated with Claude Code

seizeh and others added 2 commits September 29, 2026 13:34
edge_alert_fire 는 엣지 함수(service_role)가 알람 원장에 위임하는 전용
래퍼인데(주석부터 'service_role 전용'), 09-21 통합 때 생성 기본권한으로
붙은 authenticated EXECUTE 를 회수하지 않았다. 본문에 호출자 검사가 없는
definer 라서 로그인 사용자 누구나 임의 제목·본문의 high 우선순위 알림을
전체 관리자에게 보낼 수 있었고, 알람 키가 호출자 입력이라 쿨다운은 스팸을
막지 못한다. 같은 계열 rate_limit_hit·get_password_hash 는 이미 잠겨 있었다.

- 운영 적용 완료(20260928031112), 회수 후 실측: authenticated=false·service_role=true
- t21 §7 권한 단언 추가(plan 17→18) — 운영 직행 18/18 통과
- 정본 supabase-db.md ops_alarms 절에 래퍼 권한 명시

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
t21 의 has_function_privilege 단언이 CI 에서 거짓 실패했다. pgtap 잡은
스냅샷 복원으로 DB 를 만드는데, 이미지 기본권한이 CREATE 시점에
authenticated EXECUTE 를 재부여하고 덤프 ACL 은 내장 기본값 대비 차이만
적어 이를 걷어내지 못한다 — 회수 단언이 운영에서만 참이 된다(⑫의 T/T/R
과 같은 구조, 0032 §6.4). 운영 실측: pg_default_acl 함수 기본권한에
authenticated 잔존(anon 은 09-20 정비 때 제거됨).

- t21: 단언 제거(plan 17 복원) + 불가 사유 주석. 운영 직행 17/17 통과.
- 주간 점검 ⑭ 신설: public 함수 EXECUTE 실측 ↔ 스냅샷 ACL 양방향 대조.
  고정 목록 없이 전 함수 커버 — 재부여(edge_alert_fire 사례)와 회수
  드리프트(기능 파손 후보) 모두 잡는다. 확장 함수 제외(deptype='e'),
  타입 표기는 public. 접두 정규화. 운영 실행: anon 11·authenticated 81
  전부 일치 ✅.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@seizeh
seizeh force-pushed the fix/edge-alert-fire-grant branch from 39c3fc0 to 563840a Compare September 29, 2026 04:34
@seizeh
seizeh merged commit 26bff61 into main Sep 29, 2026
3 checks passed
@seizeh
seizeh deleted the fix/edge-alert-fire-grant branch September 29, 2026 04:36
seizeh added a commit that referenced this pull request Sep 29, 2026
#212)

edge_alert_fire(#210)의 재발 구조 차단. 운영 함수 기본권한이 새 public 함수에
authenticated EXECUTE 를 자동 부여해, service 전용 함수의 revoke 누락이 조용한
보안 구멍이 되는 구조였다. 20260920045336 이 테이블 T/T/R 에 한 조치의 함수판.

두 건인 이유(프로브 실측): 스키마 항목의 authenticated 를 걷어낸 뒤에도 신설
함수에 {=X, postgres, service_role} — 스키마 단위 기본권한은 내장 기본값
(PUBLIC=EXECUTE)에 더해질 뿐 못 걷어낸다. 내장을 바꾸는 유일한 레버인
전역(무스키마) 항목으로 PUBLIC 을 마저 제거했다.

- 운영 적용 완료(20260929045320·20260929050613), 프로브 실측:
  public 신설 {postgres,service_role}(auth/anon=f), app 신설 {postgres}
- 기존 함수 ACL 불변(기본권한은 미래 객체에만) — 주간 ⑭ 전항목 일치,
  스냅샷은 바이트 불변(dump 가 ALTER DEFAULT PRIVILEGES 를 걸러냄 = CI 무영향)
- 이후 규칙: 사용자용 RPC 신설 마이그레이션에 명시 grant 필수(기존 관례
  그대로 — 누락의 실패 방향만 조용한 구멍 → 즉시 permission denied 로 반전)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant