보안 모범 사례
Connect Base 애플리케이션의 보안을 강화하기 위한 가이드입니다.
API 키 보안
1. 환경 변수 사용
typescript
// ❌ 하드코딩 금지
const cb = new ConnectBase({ secretKey: 'cb_sk_actual_secret_key_here' })
// ✅ 환경 변수 사용
const cb = new ConnectBase({
secretKey: process.env.CONNECT_BASE_SECRET_KEY
})2. .gitignore 설정
# .gitignore
.env
.env.local
.env.production
.env.*.local
*.pem
*.key3. 클라이언트와 서버 분리
| 환경 | 사용 키 | 노출 위험 |
|---|---|---|
| 브라우저 / 모바일 앱 | cb_pk_* | 노출되어도 권한이 제한적 |
| Node.js 서버 / Cloud Function | cb_sk_* | 노출되면 전체 권한 탈취 |
입력 검증
클라이언트 측 검증 (UX 개선용)
typescript
import { z } from 'zod'
const userSchema = z.object({
login_id: z.string().min(3).max(30),
password: z.string().min(8),
nickname: z.string().min(1).max(50)
})
const validated = userSchema.parse(formData)
await cb.auth.signUpMember(validated)서버 측 검증 (보안)
서버리스 함수에서 외부 입력을 처리할 때:
typescript
// fn_user_action.js
export default async function handler(request, context) {
const { user_id, action } = request.body
if (typeof user_id !== 'string' || !user_id.startsWith('member_')) {
return { error: 'invalid user_id', status: 400 }
}
if (!['like', 'unlike', 'report'].includes(action)) {
return { error: 'invalid action', status: 400 }
}
// ... 검증된 입력으로 처리
}XSS 방지
typescript
// React 는 기본적으로 XSS 방지 (JSX 의 자동 escape)
// dangerouslySetInnerHTML 사용 시 DOMPurify 로 sanitize
import DOMPurify from 'dompurify'
const sanitized = DOMPurify.sanitize(userInput)
return <div dangerouslySetInnerHTML={{ __html: sanitized }} />인증 보안
안전한 비밀번호 정책
회원가입 폼에서 클라이언트 측 검증:
typescript
import { z } from 'zod'
const passwordSchema = z.string()
.min(12, '최소 12자 이상')
.regex(/[A-Z]/, '대문자 포함')
.regex(/[a-z]/, '소문자 포함')
.regex(/[0-9]/, '숫자 포함')
.regex(/[^A-Za-z0-9]/, '특수문자 포함')세션 / 토큰 관리
SDK 는 access_token 만료 시 자동으로 refresh_token 으로 갱신을 시도합니다.
앱 코드에서는 콜백만 등록하면 됩니다.
typescript
const cb = new ConnectBase({
publicKey: 'cb_pk_...',
// 토큰이 갱신될 때마다 호출 (localStorage 에 저장 등)
onTokenRefresh: ({ accessToken, refreshToken }) => {
localStorage.setItem('cb_access_token', accessToken)
localStorage.setItem('cb_refresh_token', refreshToken)
},
// refresh_token 까지 만료된 경우 (재로그인 필요)
onTokenExpired: () => {
localStorage.removeItem('cb_access_token')
localStorage.removeItem('cb_refresh_token')
window.location.href = '/login'
}
})네트워크 보안
HTTPS 강제
Connect Base API 는 HTTPS 만 허용합니다. SDK 의 기본 baseUrl (https://api.connectbase.world)을 그대로 사용하세요.
자체 호스팅 서버에서 SDK 를 사용한다면 reverse proxy 에서 HTTPS 강제 리다이렉트:
typescript
// Express 예시
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
return res.redirect(`https://${req.header('host')}${req.url}`)
}
next()
})CSP 헤더 설정
typescript
// Content Security Policy
app.use((_, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self' 'unsafe-inline'; " +
"style-src 'self' 'unsafe-inline'; " +
"img-src 'self' data: https://cdn.connectbase.world; " +
"connect-src 'self' https://api.connectbase.world https://socket.connectbase.world"
)
next()
})보안 헤더 (helmet)
typescript
import helmet from 'helmet'
app.use(helmet())데이터 보호
민감 데이터 마스킹
typescript
function maskEmail(email: string): string {
const [local, domain] = email.split('@')
return local.slice(0, 2) + '***@' + domain
}
function maskPhone(phone: string): string {
return phone.slice(0, 3) + '-****-' + phone.slice(-4)
}로그에서 민감 데이터 제외
typescript
const SENSITIVE_FIELDS = ['password', 'publicKey', 'secretKey', 'access_token', 'refresh_token', 'ssn', 'credit_card']
function sanitizeForLogging(data: Record<string, unknown>): Record<string, unknown> {
const sanitized = { ...data }
for (const field of SENSITIVE_FIELDS) {
if (field in sanitized) {
sanitized[field] = '[REDACTED]'
}
}
return sanitized
}
console.log('Request:', sanitizeForLogging(requestData))필드 레벨 암호화
특히 민감한 컬럼(주민번호, 카드번호 등)은 컬럼 생성 시 encrypted: true 로 설정하세요.
데이터 암호화 → 필드 레벨 암호화 를 참고하세요.
감사 및 모니터링
콘솔 로그 활용
콘솔의 로그(Logs) 메뉴에서 다음을 확인할 수 있습니다:
- API 호출 이력
- 인증 시도 (성공/실패)
- 함수 실행 로그
- 에러 발생 빈도
에러 트래커 (cb.errorTracker)
클라이언트 에러를 자동 수집해 콘솔로 전송합니다.
typescript
const cb = new ConnectBase({
publicKey: 'cb_pk_...',
errorTracker: {
// 콘솔에서 발급한 트래커 설정
enabled: true
}
})보안 체크리스트
개발 단계
- 환경 변수로 시크릿 관리 (
.gitignore확인) - 입력 검증 구현 (zod 등)
- 에러 메시지에 민감 정보 노출 방지
- 의존성 보안 취약점 스캔 (
npm audit)
배포 전
- 클라이언트 빌드에
cb_sk_*미포함 확인 - 콘솔 CORS 허용 도메인 검토
- 모든 환경(dev/staging/prod)별 별도 키 사용
- HTTPS 강제
운영 중
- 정기적인 키 로테이션
- 콘솔 로그 모니터링 (이상 패턴 탐지)
- 보안 업데이트 적용
- 침투 테스트 수행