맞는데 왜 틀릴까..?

전체 글 306

[Effective Java] Item 76. 가능한 한 실패 원자적으로 만들라

실패 원자적 (failure-atomic) : 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다. 메서드를 실패 원자적으로 만드는 방법 1. 불변 객체로 설계 불변 객체는 태생적으로 실패 원자적이다. 메서드가 실패하면 새로운 객체가 만들어지지는 않을 수 있으나 기존 객체가 불안정한 상태에 빠지는 일은 없다. 2. 작업 수행에 앞서 매개변수의 유효성 검사 가변 객체의 메서드를 실패 원자적으로 만드는 가장 흔한 방법 객체의 내부 상태를 변경하기 전에 잠재적 예외의 가능성 대부분을 걸러낼 수 있다. 계산을 수행해 보기 전에는 인수의 유효성을 검사해 볼 수 없다면, 실패할 가능성이 있는 모든 코드를 객체의 상태를 바꾸는 코드보다 앞에 배치 ex) TreeMap TreeMap은 내부에..

Java/Effective Java 2023.08.12

[Effective Java] Item 75. 예외의 상세 메시지에 실패 관련 정보를 담으라

예외를 잡지 못해 프로그램이 실패하면 자바 시스템은 그 예외의 스택 추적 정보를 자동으로 출력한다. 스택 추적은 예외 객체의 toString 메서드를 호출해 얻는 문자열로, 보통 예외 클래스 이름 뒤에 상세 메시지가 붙는 형태다. 예외 상세 메시지 예외의 toString 메서드에 실패 원인에 관한 정보를 가능한 한 많이 담아 반환하는 일은 중요하다. 실패 순간을 포착하려면 발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담아야 한다. ex)IndexOutOfBoundsException의 상세 메시지는 범위의 최솟값, 최댓값, 그 범위를 벗어난 인덱스의 값을 모두 담는다. 보안과 관련한 정보는 주의해서 다뤄야 한다. 스택 추적 정보는 많은 사람이 볼 수 있으므로 상세 메시지에 비밀번호나 암..

Java/Effective Java 2023.08.12

[Secure Coding] 출력을 적절하게 인코딩하거나 이스케이핑하라

적절한 입력 정제(sanitization)는 데이터베이스와 같은 서브시스템으로 악성 코드가 삽입되는 것을 방지할 수 있다. 데이터 출력을 목적으로 하는 여러 서브시스템 공격 HTML renderer는 출력을 디스플레이하기 위한 일반적인 시스템 중의 하나다. 출력 서브시스템으로 보내진 데이터는 신뢰할 수 있는 소스에서 온 것처럼 보일 수 있지만 출력 정제가 불필요하다고 가정하는 것은 위험하다. 이러한 데이터가 비신뢰-소스에서 시작되어 우회했을지도 모르고, 악의적인 내용을 포함할 수도 있기 때문이다. 출력 서브시스템으로 전달되는 데이터를 적절히 정제하지 못하면 여러 가지 형태의 공격을 허용하게 된다. HTML renderer는 HTML 인젝션과 XSS 공격을 당하기 쉽다. 이런 공격을 방지하기 위한 출력 정..

Java/Secure Coding 2023.08.11

[Effective Java] Item 74. 메서드가 던지는 모든 예외를 문서화하라

메서드가 던지는 예외는 그 메서드를 올바로 사용하는 데 아주 중요한 정보다. 따라서 각 메서드가 던지는 예외 하나하나를 문서화하는 데 충분한 시간을 쏟아야 한다. 자바독 @throws 태그 검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용하여 정확히 문서화하자. 공통 상위 클래스 하나로 뭉뚱그려 선언하지는 말자. 극단적인 예로 메서드가 Exception이나 Throwable을 던진다고 선언해서는 안된다. 메서드 사용자에게 각 예외에 대처할 수 있는 힌트를 주지 못할뿐더러, 같은 맥락에서 발생할 여지가 있는 다른 예외들까지 삼켜버릴 수 있어 API 사용성을 크게 떨어뜨린다. JWT Access 토큰을 재발급해주는 메서드 main은 오직 JVM만이 호출하므로..

Java/Effective Java 2023.08.11

[Effective Java] Item 73. 추상화 수준에 맞는 예외를 던지라

메서드가 저수준 예외를 처리하지 않고 바깥으로 전파해 버리면 수행하려는 일과 관련 없어 보이는 예외가 튀어나올 수 있다. 이는 내부 구현 방식을 드러내어 윗 레벨 API를 오염시킨다. 다음 릴리스에서 구현 방식을 바꾸면 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지게 할 수도 있다. 저수준 예외 저수준 예외는 주로 하위 레벨의 컴포넌트나 라이브러리에서 발생하는 예외를 의미한다. 이 예외들은 주로 프로그램의 내부 동작, 하위 레벨의 리소스 접근, 네트워크 통신 등과 관련이 있다. 프로그램의 외부 요인으로 발생하거나, 하위 레벨에서 발생한 문제로 인해 발생하는 경우가 많아 애플리케이션 개발자가 직접 제어하기 어려울 수 있다. 파일을 열다가 발생한 입출력 예외 네트워크 연결 중에 발생한 소켓 예외 프로..

Java/Effective Java 2023.08.11

[Secure Coding] 마구잡이 파일 업로드를 방지하라

웹 응용프로그램을 포함하여 파일 업로드를 허용하는 자바 응용프로그램들은 공격자가 악성 파일을 업로드하거나 전달할 수 없도록 보장해야 한다. 만약 코드를 포함한 제한되어야 할 파일이 대상 시스템에서 수행된다면, 응용계층의 방어책을 무력화시킬 수 있다. XSS 공격 HTML 파일을 업로드하도록 허용하는 응용프로그램은 악성 코드의 수행을 허용한다. 만약 출력에 대한 이스케이핑 루틴이 없을 경우에, 공격자는 크로스-사이트(XSS) 스크립팅 페이로드를 가지고 있는 HTML 파일을 보내서 공격을 수행할 수 있다. 공격 과정 1. HTML 파일 업로드 웹 응용프로그램이 사용자가 업로드한 HTML 파일을 저장하고, 다른 사용자들이 이 파일을 볼 수 있도록 한다. 이때 파일은 일반적인 텍스트 파일처럼 저장되는 것이 아니..

Java/Secure Coding 2023.08.07

[Secure Coding] 보안에 민감한 메서드들이 검증된 매개변수를 가지고 호출되도록 보장하라

보안에 민감한 메서드들을 호출하는 응용 코드는 메서드에게 전달되는 매개변수들을 검증해야만 한다. 어떤 보안에 민감한 메서드들에게는 null 값이 무난한 것으로 해석될 수도 있으나 디폴트 설정을 덮어쓸지도 모른다. 그렇게 되면 권한상승 또는 아무 코드나 수행할 수도 있게 된다. 부적절한 코드 - 보안에 민감한 메서드의 매개변수로 null을 사용 지금은 deprecated 되었지만 부적절한 코드 예를 한번 살펴보자. AccessController.doPrivileged 자바에서 특정 코드 블록을 보안 권한 검사를 우회하고 특권(privileged) 상태로 실행할 수 있는 메서드다. AccessController.doPrivileged( new PrivilegedAction(){ public Void run(..

Java/Secure Coding 2023.08.06

[Effective Java] Item 72. 표준 예외를 사용하라

자바 라이브러리는 대부분 API에서 쓰기에 충분한 수의 예외를 제공한다. 표준 예외를 재사용하면 얻는 게 많다. 많은 프로그래머에게 이미 익숙해진 규약을 따르기 때문에 내가 만든 API를 다른 사람이 익히고 사용하기 쉬워진다. 예외 클래스 수가 적을수록 메모리 사용량도 줄고 클래스를 적재하는 시간도 적게 걸린다. 표준 예외 IllegalArgumentException 호출자가 인수로 부적절한 값을 넘길 때 던지는 예외 ex) 반복 횟수를 지정하는 매개변수에 음수를 건넬 때 IllegalStateException 대상 객체의 상태가 호출된 메서드를 수행하기에 적합하지 않을 때 던지는 예외 ex) 제대로 초기화되지 않은 객체를 사용하려 할 때 NullPointerException null 값을 허용하지 않는..

Java/Effective Java 2023.08.06

[Effective Java] Item 71. 필요 없는 검사 예외 사용은 피하라

검사 예외를 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다. 검사 예외의 과한 사용 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 그 예외를 붙잡아 처리하거나 더 바깥으로 던져 문제를 전파해야만 한다. 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없다. API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우에 검사 예외를 사용하고, 둘 다 아니면 비검사 예외를 사용하자 아래와 같은 ..

Java/Effective Java 2023.08.06