Ruby `.include?` 가 보안 hole 을 우연히 닫은 사건 — duck typing 과 jsonb `||` 의 합작

OAuth 인증 서버를 직접 운영하면 어느 시점 한 번은 redirect_uri 검증을 손볼 일이 생긴다. 이번에 그 코드를 다시 들여다보다가 같은 줄이 데이터 형태에 따라 두 가지 완전히 다른 의미로 작동하고 있었다는 걸 발견했다. 한 줄짜리 SQL UPDATE 가 그 사이에 의도치 않게 보안 hole 을 만들었다가 다른 한 줄짜리 SQL UPDATE 가 또 의도치 않게 그 hole 을 닫았는데, 동시에 정상 OAuth 흐름도 깨버렸다. 결과적으로 같은 코드 한 줄이 시간에 따라 substring 매칭이었다가 element-wise 매칭으로 dispatch 가 바뀌었다. ...

2026-05-16 09:00 · 11분 소요 · Seunghan

Rails raw SQL 컬럼명 typo로 OAuth userinfo가 다 500 — 4중 보호막이 동시에 뚫린 이야기

운영하던 OIDC IdP 서버에서 어느 날 갑자기 모든 RP(Relying Party) 로그인이 깨졌다. 사용자가 보는 화면은 평범한 401 “로그인 실패”. 클라이언트 로그를 봐도 그냥 RP Rails 백엔드가 401을 응답했을 뿐이다. 처음엔 핸드오프(Universal Link / Custom Tabs) 문제로 의심했다 — 표면 증상만 보면 그게 가장 자연스러우니까. 그런데 진단을 깊이 파보니 4중으로 깔려있어야 할 안전망이 단 하나도 작동 안 한 상태였고, 그 결과 raw SQL 한 줄의 컬럼명 오타가 며칠을 살아서 모든 사용자 인증을 깨놓고 있었다. 사고 자체보다 왜 이게 prod까지 도달했는지가 본질이라 정리해둔다. ...

2026-05-11 11:45 · 9분 소요 · Seunghan

Threads API로 내 게시물 댓글 151개 수집하기 — OAuth 토큰부터 pagination까지

커뮤니티 모집글을 Threads에 올려서 댓글이 잔뜩 달렸다. 참가자에게 DM으로 설문 링크를 돌리려면 댓글 작성자 @handle 목록이 필요한데, 수동으로 스크롤하며 복사하는 건 100개 넘어가면 현실적이지 않다. Meta가 2024년에 공식 Threads API를 열었다는 건 알고 있었지만 실제로 써본 적은 없었다. “Instagram Graph API랑 뭔가 다른 것 같은데 뭐가 다른지 모르겠다” 상태에서 시작해, 삽질하면서 151개 댓글 / 151명 유니크 작성자를 추출하기까지의 과정을 정리한다. 공식 문서에는 흩어져 있고, 커뮤니티 자료는 대부분 게시 자동화(content publish) 쪽에 치중돼 있어서 “읽기(read replies)“만 필요한 케이스를 한 페이지에 모은 게 없었다. ...

2026-04-20 09:00 · 8분 소요 · Seunghan
Apple Sso 403 Email Verified Type Mismatch

Apple Sign-In 403 에러: email_verified 타입 불일치와 복붙 버그 3종 세트

Apple Sign-In이 403 Forbidden으로 실패하는데, Google Sign-In은 정상 동작하는 상황이었다. 동일한 스택(Rails 8 + Flutter)의 다른 프로젝트에서는 Apple 로그인이 잘 되고 있어서 비교 분석했다. 결론부터 말하면, 세 가지 독립적인 버그가 동시에 존재했고, 모두 “Google SSO 코드를 복붙해서 Apple SSO를 만든” 과정에서 생겨났다. 증상 Apple 로그인: 403 Forbidden Google 로그인: 정상 성공 에러 메시지: "Email not verified by Apple" 개발 환경에서는 재현되지 않고 프로덕션에서만 발생 (Apple 테스트 계정 이슈) 배경: Apple과 Google JWT는 다르다 OAuth 2.0 / OIDC 표준은 email_verified 필드가 boolean이어야 한다고 명시하고 있다. 하지만 현실에서 Apple은 이 필드를 문자열 "true"로 반환하는 경우가 있다. 이건 Apple의 공식 문서에도 명확히 나와 있지 않은 엣지 케이스다. ...

2025-10-25 00:00 · 6분 소요 · Seunghan
Rails Flutter Server Health Check 4 Issues

Rails + Flutter 앱 서버 점검기: 한 번에 터진 4가지 문제와 해결

앱 테스트 빌드를 올리고 직접 돌려보니 한꺼번에 4가지가 안 됐다. Google 로그인 실패, AI 일정 생성이 엉뚱한 결과, 알림 버튼 누르면 크래시, 인기 여행지 섹션이 텅 비어있음. 하나씩 원인을 찾고 고친 과정을 정리한다. 1. Google SSO는 실패하는데 Apple 로그인은 성공 증상 Apple Sign-In은 정상 동작하지만 Google Sign-In만 500 에러. 클라이언트에서는 로그인 실패 토스트만 보인다. 원인 컨트롤러는 이전 커밋에서 수정했지만, Model의 from_omniauth 메서드는 그대로였다. # User 모델 — 마이그레이션 후에도 옛날 컬럼명 참조 def self.from_omniauth(auth) user = find_or_initialize_by(provider: auth.provider, uid: auth.uid) # uid 컬럼 없음 user.image = auth.info.image # image 컬럼도 없음 end DB 스키마에서는 uid → provider_uid, image → avatar_url로 마이그레이션된 상태. 컨트롤러 쿼리는 수정했지만 모델 내부 메서드가 여전히 옛 컬럼을 참조하고 있었다. ...

2025-10-15 00:00 · 5분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의