5기 Jay
1시간 전•

11월 4일

오늘 공부한 시간: 2h

1. API 키, 환경변수

1) .env 파일이 깃허브에 올라가 있지 않은지 확인

- .gitignore 파일을 열어서 .env, .env.local, .env.production이 들어 있는지 본다

- 예전에 올라간 적이 있는지도 확인: git log --all -- .env

2) 프론트엔드에 API 키가 들어가 있지 않은지 확인

- F12 → Sources → Ctrl+F로 sk- 또는 key 검색

- .env에서 NEXT_PUBLIC_이 붙은 변수는 공개돼도 괜찮은 것만 남긴다

3) AI 채팅창에 키를 붙여넣은 적은 없는지 체크

4) 노출된 것 같으면 바로 폐기하고 새로 발급

5) 키는 무제한으로 두지 말고 기간을 걸어 둔다

2. 데이터베이스 접근 권한

1) RLS 설정

- RLS는 데이터 한 줄 한 줄에 걸어 두는 잠금장치

- 꺼져 있으면 공개키만 있어도 회원 정보 전체가 그대로 조회된다

- Supabase → Table Editor에서 Unrestricted가 떠 있는지 확인

2) 관리자 키 노출 여부

- service_role, serviceAccountKey.json은 관리자의 마스터키

- 이게 있으면 RLS를 전부 우회해서 테이블 전체를 열 수 있다

- 코드 전체와 개발자도구 Sources에서 service_role을 검색해 보고, 하나라도 나오면 즉시 키를 바꾼다

- AI 프롬프트: 프론트엔드 코드에서 service_role 키를 쓰는 부분을 전부 찾아줘. 찾으면 서버 쪽으로 옮기고, 프론트에서는 anon 키만 쓰게 바꿔줘

3) RLS 정책 관리

- Supabase → Authentication → Policies → 테이블 선택

- 핵심은 "지금 요청한 사람이 이 줄의 주인인가" 검사 (auth.uid() = user_id)

- 조회, 추가, 수정, 삭제마다 정책을 따로 만든다

SELECT(조회): posts_select_own

INSERT(추가): posts_insert_own

UPDATE(수정): posts_update_own

DELETE(삭제): posts_delete_own

4) 파일 저장소 공개 여부

- 버킷(파일이 저장된 묶음)이 공개로 되어 있으면 URL만으로 모든 파일에 접근할 수 있다

- 파일 이름을 순서대로 지어 두면 숫자만 바꿔 가며 전부 내려받을 수 있다

- 해결 방법

① 버킷을 비공개로 바꾸기

② 파일 이름을 UUID(무작위 문자열)로 짓기

③ 서명된 URL(유효시간이 붙은 임시 주소) 쓰기

- 확인 방법: Storage → 버킷 목록에서 Public 표시 확인. 시크릿 모드에서 파일 주소를 붙여 넣었을 때 열리면 전부 공개 상태다

3. 인증, 인가

1) 인증은 신분증, 인가는 허가(접근할 수 있는 범위)

2) 서버에서 권한까지 검사하기

- 예를 들어 "로그인 기능 만들어줘"로 끝내면 안 되고, 인가가 잘 됐는지 확인해야 한다

① 권한 없는 일반 계정을 하나 만든다

② 그 계정으로 관리자 화면 주소를 입력한다

③ 열리면 인가가 없는 것

3) 내 것만 열리게 소유자 검사하기

- 이런 식으로 남의 데이터에 접근했을 때 안 열려야 정상

- 이 데이터의 주인이 지금 로그인한 사람인지를 확인하는 것

- AI 프롬프트: 데이터를 조회·수정·삭제하는 모든 곳에서, 그 데이터의 주인이 지금 로그인한 사용자와 같은지 서버에서 확인하고 다르면 거절해줘

4) 차단은 화면이 아니라 서버에서

- 인증, 인가 처리를 프론트엔드에서만 하면 안 된다

- 화면에서만 감추면 메뉴만 안 보이고 주소를 치면 그대로 열린다

- 서버에서 막으면 요청 자체가 거절돼서 주소를 알아도 못 들어간다

- AI 프롬프트: 화면에서 숨기는 것과 별개로, 관리자용 기능 하나하나에 서버에서 관리자 권한을 확인하는 코드를 넣어줘

5) 로그인 관리 다섯 가지

① 로그인 시도 횟수 제한

② 토큰에 만료 시간 걸기 (토큰은 로그인했다는 출입증이라 만료가 없으면 평생 유효)

③ 관리자 토큰을 브라우저에 저장하지 않기 (localStorage.setItem("adminToken", token) 같은 코드 X)

④ 기본 관리자 계정 바로 바꾸기 (admin/admin, test1234/test1234 X)

⑤ 관리자 계정에는 2단계 인증 걸기 (이메일 인증 또는 문자 인증)

4. 암호화, 개인정보처리방침

1) HTTPS(주소창 자물쇠) 켜기

- 암호화된 통신 규약

- 안 켜져 있으면 로그인할 때 입력한 아이디와 비밀번호가 그대로 노출된다

2) 비밀번호는 해시로 저장

- 암호화는 되돌릴 수 있지만(복호화) 해시는 되돌릴 수 없다

- 서비스를 만든 우리도 고객 비밀번호를 알 수 없게 하는 것

- 해시를 직접 만들지 말고 bcrypt 같은 검증된 방식만 쓰기

- AI 프롬프트: 비밀번호를 그대로 저장하는 곳이 있는지 전부 찾아서 bcrypt 해시로 바꿔주세요. 그리고 로그인을 Supabase Auth로 옮기는 방법도 알려주세요

3) 법으로 암호화가 정해진 정보

- 비밀번호는 해시(되돌릴 수 없게)

- 고유식별번호(주민등록번호, 여권번호), 생체정보, 계좌번호·카드번호는 암호화해서 저장

4) 쓰지 않을 정보는 아예 받지 않기

- AI 프롬프트: 우리 서비스가 수집하는 개인정보 항목을 전부 뽑아주세요. 없어도 되는 항목을 표시해 주고, 꼭 필요한 항목은 저장할 때 암호화되는지 확인해 주세요

5) 개인정보처리방침

- 만드는 것뿐 아니라 보이는 곳에 게시하는 것까지가 의무

- 이메일 주소 하나만 받아도 해당된다

- 들어가야 할 내용: 수집 항목, 이용 목적, 보유 기간, 제3자 제공, 처리위탁, 파기 절차, 이용자 권리, 보호책임자 연락처

- AI API, 클라우드 DB, 이메일 발송, 분석 도구를 쓰고 있으면 처리위탁에 해당하니 꼭 적어야 한다

- AI 프롬프트: 우리 코드가 부르는 외부 서비스를 전부 목록으로 뽑아주세요. AI API, 데이터베이스, 이메일 발송, 분석 도구까지요. 처리방침 위탁 항목에 적을 수 있게 정리해 주세요

+ OWASP TOP 10

- 웹 애플리케이션 보안 취약점을 정리한 리포트

- AI 프롬프트: 이 보안 문서 참고해서 우리 서비스의 보안 취약점 찾아줘

오늘 잘한 점:

0
0

여기에 파일을 드롭하세요