맞는데 왜 틀릴까..?

Java 108

[Effective Java] Item 79. 과도한 동기화는 피하라

과도한 동기화는 성능을 떨어뜨리고, 교착상태에 빠뜨리고, 예측할 수 없는 동작을 낳기도 한다. 응답 불가와 안전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하면 안 된다. 동기화된 영역 안에서는 재정의할 수 있는 메서드는 호출하면 안 되며, 클라이언트가 넘겨준 함수 객체를 호출해서도 안된다. 외계인 메서드 (Alien method) 외계인 메서드 (alien method) : 동기화된 영역을 포함한 클래스 관점에서 클라이언트가 넘겨준 함수 객체 또는 재정의할 수 있는 메서드 외계인 메서드가 하는 일에 따라 동기화된 영역은 예외를 일으키거나, 교착상태에 빠지거나, 데이터를 훼손할 수도 있다. 잘못된 코드 예시 - 동기화 블록 안에서 외계인 메서드 호출 클래스의 클라..

Java/Effective Java 2023.08.20

[Effective Java] Item 78. 공유 중인 가변 데이터는 동기화해 사용하라

synchronized는 해당 메서드나 블록을 한 번에 한 스레드씩 수행하도록 보장한다. 동기화의 두가지 용도 배타적 실행 한 스레드가 변경하는 중이라서 상태가 일관되지 않은 순간의 객체를 다른 스레드가 보지 못하게 막는다. 스레드 사이의 안정적 통신 동기화 없이는 한 스레드가 만든 변화를 다른 스레드에서 확인하지 못할 수 있다. 동기화는 일관성이 깨진 상태를 볼 수 없게 하는 것은 물론, 동기화된 메서드나 블록에 들어간 스레드가 같은 lock의 보호하에 수행된 모든 이전 수정의 최종 결과를 보게 해 준다. 동기화는 배타적 실행뿐 아니라 스레드 사이의 안정적인 통신에 꼭 필요하다. long, double 외의 변수를 일고 쓰는 동작은 원자적(atomic)이다 여러 스레드가 같은 변수를 동기화 없이 수정하..

Java/Effective Java 2023.08.13

[Effective Java] Item 77. 예외를 무시하지 말라

API 설계자가 메서드 선언에 예외를 명시하는 까닭은 그 메서드를 사용할 때 적절한 조치를 취해달라고 말하는 것이다. 해당 메서드 호출을 try문으로 감싼 후 catch 블록에서 아무 일도 하지 않으면 예외는 아주 쉽게 무시된다. catch 블록을 비워두면 예외가 존재할 이유가 없어진다. 예외를 무시해야 할 때 FileInputStream을 닫을 때 입력 전용 스트림이므로 파일의 상태를 변경하지 않았으니 복구할 것이 없으며, 스트림을 닫는다는 건 필요한 정보는 이미 다 읽었다는 뜻이니 남은 작업을 중단할 이유도 없다. 예외를 무시하기로 했다면 catch 블록 안에 그렇게 결정하기로한 이유를 주석으로 남기고 예외 변수의 이름도 ignored로 바꾸자. public class IgnoredExceptionE..

Java/Effective Java 2023.08.13

[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