클라우드뱅크
2025.03.17 — 현재·Backend Engineer · 선임
금융기관 인증·조회 백엔드를 처음부터 구축했고, 기존 펌뱅킹에는 API·SAP 연동 경로를 추가해 고객 환경에 배포했습니다.
Java 21, Java 17, Spring Boot, PostgreSQL, SAP JCo, SFTP, Spring Cloud OpenFeign, Playwright
맡은 일
- SAP와 연계되는 온프레미스 펌뱅킹 솔루션 개발
- 계좌 잔액·거래내역 등을 조회하는 금융기관 인증·조회 백엔드 신규 구축, 아키텍처와 구현 담당
금융기관 인증·조회 백엔드 신규 구축
기관마다 다른 인증·조회 요청과 응답을 Java로 구현하고, 기관별 차이는 Adapter와 Signer로 나눴습니다. 주요 흐름은 합성 데이터와 미리 저장한 응답으로 반복 실행하고, 서명 결과는 고정 입력·시각의 골든 벡터로 비교했습니다.
실제 금융기관 환경에서 인증서 로그인과 계좌 조회 동작을 확인했습니다. 기존 브라우저 자동화 경로를 유지하면서 직접 통신 경로로 옮기는 작업은 진행 중입니다.
SFTP 중심 FEP에 API 경로 추가
SFTP 파일 송수신과 SAP 전달 중심의 FEP에 HTTP API 조회와 SAP RFC 중계 경로를 추가했습니다. 첫 API 경로에서는 요청·응답 DTO와 Client·Service를 분리하고, SAP 조회 조건을 API 요청으로 바꾼 뒤 페이지 결과를 모아 SAP 응답으로 돌려주는 Handler를 구현했습니다.
후속 API 기관은 OAuth 인증과 보고서 생성·상태 조회·다운로드 절차가 달랐습니다. 해당 경로를 추가하면서 API 전용 기관은 SFTP scheduler에서 제외하고, SAP 채널과 기관의 허용 조합을 호출 전에 검사하도록 구성했습니다. 두 API 경로는 고객 환경에 배포돼 지금도 연동에 쓰이고 있습니다.
신규 전송의 상태 경계
신규 대량 금융 전송 기능에서 경쟁, 기존 전송 이력과 응답 불확실성을 사전에 구분해야 했습니다. 팀에서 상태 선점·중복 이력 차단·응답별 후속 처리 요구사항을 합의하고, 코드와 회귀 테스트를 구현·검토해 운영 환경에 배포했습니다.
중복 요청이 실제 전송으로 이어진 사고
전송 데이터가 늘면서 반복문 안의 건별 검증 조회가 길어졌고, 응답을 받지 못한 사용자가 같은 거래를 다시 요청하자 두 요청이 큐에 적재됐습니다. 재요청을 정상적인 실패 경로로 보고 큐 적재 전에 처리 상태를 변경했으며, 소비자가 전송 직전에 데이터를 다시 조회하도록 수정했습니다. 검증 데이터는 한 번에 조회하고 UPDATE는 batch 처리했으며, 운영 배포 후 2주 동안 같은 사고는 관찰되지 않았습니다.
설치형 전환
인증 처리를 고객사 내부에서 마쳐야 하는 단계에서는 연산 책임과 배포 산출물의 경계를 나눴습니다. 전체 인증·조회 로직을 설치형으로 옮기는 구현안은 별도 모듈과 native 바이너리로 구성하고 로컬 통제 환경에서 확인했습니다.
DB 데드락 대응
안정화 모니터링 중 결과 수신 처리가 금융기관 응답을 저장하지 못하는 DB 데드락을 발견했습니다. 송신·응답 로그와 InnoDB trace, 실행계획에서 독립된 두 트랜잭션의 record lock 순환 대기를 확인했습니다. 외부 중계망과 금융기관을 대체하는 테스트 서비스로 장애를 재현하고, 충돌하던 보조 인덱스를 제거한 뒤 UPDATE가 복합키를 사용하도록 변경했습니다. 운영 배포 후 2주 동안 같은 데드락과 응답 갱신 실패는 관찰되지 않았습니다.
컬처메이커스
2022.07.18 — 2025.03.14·Backend Engineer · 매니저
챌린지 플랫폼의 역할·이벤트 소속 검사를 공통 요청 경계로 분리했습니다. AWS 인프라를 구축·운영하며 대회마다 응답 시간과 호출 경로를 확인했습니다.
Java 17, Spring Boot 3, PostgreSQL, Redis, AWS
맡은 일
- 챌린지 플랫폼 기능 개발과 도메인 재설계
- 백오피스와 권한 체계 개발
- 대회 기술 지원과 평가·집계 출력 자동화
- AWS 인프라 구축·운영·비용 관리
- Jira, Confluence, GitHub와 AWS 알림을 Slack 중심으로 연결하는 ChatOps 적용
흩어져 있던 권한 검사
권한 검사가 컨트롤러마다 흩어져 기능 코드와 뒤섞여 있었습니다. @AuthZ로 요구 정책을 표시하고, interceptor에서 로그인 사용자와 URL의 eventId를 조합해 컨트롤러 실행 전에 검사했습니다. 역할별 허용·거절과 잘못된 요청을 테스트한 뒤 운영에 반영했습니다.
Race condition을 이용한 제출 제한 우회
DB에서 제출 횟수를 조회·증가·판정하는 사이 동시 요청이 같은 횟수를 기준으로 통과해 제한을 초과할 수 있었습니다. 팀 단위 Redis Lua 카운터로 증가와 한도 검사를 한 번에 실행하도록 바꾸고, 동시 요청에서도 제출 제한이 유지되는지 테스트했습니다.
AWS 운영과 호출 경로 추적
ECS Fargate 전환 뒤 CloudWatch 로그는 유지하면서 관측을 두 갈래로 나눴습니다. Actuator·Prometheus·Grafana에서는 응답 시간 추세를 보고, Pinpoint에서는 요청 호출 경로를 추적했습니다. 구축 뒤 대회마다 응답 시간을 중심으로 서비스 상태를 확인했습니다.
웨일즈랩
2020.07.06 — 2022.02.14·Backend Engineer · 공동창업
2인으로 공동창업해 기술을 맡았고, 팀 내에서 시큐어코딩 실습 제품을 개발해 베타 공개했으며 공공 경진대회 예선 플랫폼과 40문제를 만들었습니다.
Java, Servlet, JSP, Spring Boot, MySQL, Python
이 제품은 회사보다 먼저 있었습니다. 케이쉴드 주니어 2기 교육에서 팀 프로젝트로 만들던 시큐어코딩 실습을 기반으로 2인이 회사를 세웠습니다.
창업 당시 최신 보안 흐름을 반영하기 어려운 정체된 콘텐츠와 일방향 온라인 강의를 문제로 보고, SW 전공 학생을 초기 대상으로 설정했습니다.
맡은 일
- 학습자 코드를 실제 웹 기능으로 실행하는 시큐어코딩 교육 플랫폼과 공격·방어 실습 시스템 개발
- 취약점의 원인과 방어 과정을 직접 경험하게 만드는 시나리오 기반 교육 콘텐츠 제작
- 풀이 공개, 댓글·반응과 다른 학습자의 생성 페이지 공격을 연결한 참여형 학습 기능 개발
- 소프트웨어 개발보안 경진대회 운영, 예선 40문제 출제와 온라인 플랫폼 개발
- 제품 기획과 사업계획, IR 자료 작성에 참여
실습 시스템의 구조와 담당 범위
학습자가 쓴 방어 함수를 취약점별 웹 기능에 넣고 그 기능을 직접 공격하게 하려면, 코드를 채점하는 대신 실행해야 했습니다. Java와 Python은 실행 방식이 달랐고, 학습자마다 코드와 판정 상태를 따로 유지하면서 서로의 풀이를 열어 공격할 수도 있어야 했습니다. Java는 문제별 JSP template에 학습자 함수와 검증 block을 조립하는 방식, Python은 학습자 함수와 공격 입력을 실행 스크립트로 구성하는 방식이었습니다.
개념 학습→방어 코드 작성→공격 실행→결과 확인·수정의 흐름을 팀 내에서 구현하고 케이쉴드 주니어 수료생에게 베타 공개했습니다.
경진대회 수주와 운영
회사가 KISA 발주 제8회 소프트웨어 개발보안 경진대회를 컬처메이커스와 컨소시엄으로 수주했습니다. 대회 운영을 맡고 예선 문제를 출제했으며, 온라인 플랫폼도 직접 만들었습니다.
예선 플랫폼은 대회 시간, 참가 트랙과 문제당 한 번의 제출을 서버에서 강제했습니다. 코드 실행과 판정은 기존 시큐어코딩 실습 제품의 API를 재사용하고, 대회용 실행 서버는 운영 서비스와 분리했습니다.
특허 공동 발명
이 실습 구조는 「시큐어 코딩 시스템 및 방법」으로 출원·공개됐고, 공동 출원인이자 공동 발명자 5인 중 1인으로 참여했습니다.