Backend/Java

Backend/Java

Spring XSS

보안테스트 결과 XSS 취약점이 발견돼 조치를 하면서, 약간 고생을 해서 경험을 공유해보려 한다. XSS(Cross Site Scripting) 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법 XSS Filter 현재 백엔드 프로젝트가 Rest API로 구성돼, 대부분의 요청과 응답이 json 방식으로 요청 중이다. Spring XSS를 검색하면 가장 많이 노출되는 Lucy Filter가 있지만, @ResponseBody로 응답되는 application/json 타입은 처리하지 못한다고 해서 Jackson 라이브러리의 CharacterEscape를 설정해 , ', " 총 4개의 문자를 치환했었다. 관련된 설정은 https://jojoldu.tistory.com/470을 참고했다. 위의 설정으로..

Backend/Java

Spring Actuator로 Property 변경하기

서비스 가동중에 프로퍼티를 변경할 수 있으면, 서비스를 배포하지 않아도 되기 때문에 빠르고 유연한 서비스를 운영할 수 있다. 스프링에서 제공하는 spring actuator를 의존하는 것만으로도 쉽게 적용할 수 있다. 설정 의존성 추가 # build.gradle dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' } 프로퍼티 설정 # application.yml management: endpoints: web: exposure: include: refresh 이렇게만 설정하면 끝이다. 프로퍼티를 변경할 일이 생기면 application.yml을 변경하고 actuator에서 제공하는 엔드포인트를 호출하기만..

Backend/Java

오라클 - 마이바티스 날짜형 데이터 맵핑

코드를 보다 보니 날짜를 의미하는 데이터를 마이바티스->어플리케이션 맵핑하는 방식이 다양한 것을 봤다. 내 기억으로는 특정 마이바티스 버전부터는 자동으로 [LocalDateTime, LocalDate, LocalTime]으로 맵핑해 주는 걸로 알고 있었는데 활용하지 못한 것처럼 보여 의아했다. 이유를 알아보니 기존 레거시 코드를 그대로 옮기다 보니 그런 것도 있지만, 현재 환경이 위의 Java 타입으로 맵핑이 깔끔하게 되지는 않기 때문이었다. 데이트 타입 맵핑 장애물 오라클DB 날짜 타입 먼저 현재 환경은 오라클과 비슷한 국산DB 티베로를 사용하고 있다(이 글에서 말하려는 특징은 동일하기 때문에 오라클로 설명하겠다). 오라클 날짜 형식의 데이터는 4가지로 분류된다. DATE 연, 월, 일, 시, 분, 초..

Backend/Java

Java에서 Null을 다루는 방식

널널(null null)하게 개발하지 마세요 언어마다 약간의 차이가 있지만, 자바에서는 존재하지 않는 객체 메모리 주소를 `null`이라 표현한다. 따라서 원시타입을 제외한 객체를 가리키는 모든 변수는, 초기에 null 상태라고 볼 수 있다. null을 참조하려고 하면 자바는 NPE(Null Point Exception)라는 런타임 오류를 뱉어내는데 해결하기 쉬우면서도 어려운 오류다. null safe하게 코드를 작성하려고 노력하지만, 항상 예상하지 못한 곳에서 NPE가 발생한다. 런타임 오류기 때문에 코드가 배포돼서 서비스되기 전까지는 모르기 때문에 치명적이다. 널 레퍼런스를 처음 만든 토니 호어가 '10억 불짜리 실수'(billion dollar mistake)였다고 회고한 적 있다. 널 포인터를 체..

Backend/Java

공통 lib -> spring-boot-starter로 바꾸기(3)

2023.02.13 - [Backend/Java] - 공통 lib -> spring-boot-starter로 바꾸기(1) 2023.03.20 - [Backend/Java] - 공통 lib -> spring-boot-starter로 바꾸기(2) 조금 다른, 새로운 프로젝트 등장 프로젝트가 커져가면서, 기능을 분리해 새로운 프로젝트로 관리해야 했다. 기존에 공통 기능 프로젝트(master)와 업무 프로젝트(slave)를 잘 분리했기에 손쉽게 프로젝트를 구성할 수 있었다. 각 업무 프로젝트(slave)마다 필요한 설정이 조금씩 다를 것이다. 특별하게 필요한 설정은 각 프로젝트에서 설정해 사용하면 되지만, 문제는 master 프로젝트에서 제공하는 공통 기능이 특정 프로젝트에서는 필요 없는 상황이 생길 수도 있다..

Backend/Java

Stream에 Decorator 패턴 써먹기

"데이터 가공이 필요해요." 공통 기능(엑셀 다운로드)에서 메모리를 절약하기 위해 대용량 데이터를 조회할 경우 마이바티스 `Cursor` 타입을 매개변수로 받도록 설계했다. 여기서 문제를 명확히 하기 위해 커서 데이터가 전부 소비됐으면, 예외를 던져주기로 했다. class ExcelFile { public void write(Cursor cursor) { if (cursor.isConsumed()) throw new IllegalArgumentException("데이터가 없어요."); try (cursor) { // cursor 데이터를 엑셀 파일에 작성하는 로직 } } } 공통 기능을 사용하는 개발자는 커서 데이터 타입을 인자로 넘겨줘야 하는데, 흔히 개발자들이 DB에서 조회된 이 커서 데이터를 인자로..

Backend/Java

공통 lib -> spring-boot-starter로 바꾸기(2)

gradle로 마이그레이션 하기 현재 프로젝트는 maven으로 구성되어있다. 꼭 필요한 작업은 아니지만 maven보다는 gradle을 사용하면 이점이 많기 때문에, gradle로 전환하고 spring-starter 프로젝트로 변환하려 했었다. 마이그레이션 공식문서도 있고 툴도 있어서, 손쉽게 전환할 수 있을지 알았지만 생각보다 많은 삽질이 있었고, 그 과정을 공유해본다. maven 프로젝트 구성 프로젝트는 아래와 같이 구성되어 있다. master 프로젝트가 서브 모듈 worker를 가지는 구조로 하나의 라이브러리 프로젝트를 구성하고 있다. 그리고 이 라이브러리 프로젝트를 사용하는 별도의 빌드 프로세스를 가지는 외부 프로젝트가 있다. 멀티모듈 프로젝트1(라이브러리) -> master-worker 외부 프로..

Backend/Java

공통 lib -> spring-boot-starter로 바꾸기(1)

웹기반 공통 Library 중복되는 설정들 혹은 공통으로 관리해야 할모듈을 한 곳에서 관리하는 것은 흔한 일이다. 현재 내가 진행하고 있는 프로젝트 또한 모든 프로젝트에서 참조하는 스프링 웹 기반의 라이브러리 프로젝트가 존재하고, 여기에는 많은 스프링 Bean이 존재하고 있다. 처음에는 문제를 느끼지 못했지만, 시간이 갈수록 웹 환경에 의존적인 많은 Bean들이 다른 클라이언트 프로젝트에 맞지 않는 경우가 생겨났고, 설계가 잘못됐다고 확실히 느낄 수 있었다. 어디서부터 잘못된 걸까? 외부 jar에 정의된 스프링 Bean은 읽지 않는 것이 기본 원칙이다. 제일 헷갈린 부분이다. 내가 현업에서 사용하는 프로젝트는 외부 jar에 정의된 Bean들이 클라이언트 프로젝트 Context에서 등록돼 잘 사용하고 있다..

비비빅B
'Backend/Java' 카테고리의 글 목록