보안 Java 애플리케이션 개발을위한 13 가지 규칙

보안은 소프트웨어 개발에서 가장 복잡하고 광범위하며 중요한 측면 중 하나입니다. 또한 소프트웨어 보안은 종종 간과되거나 개발주기가 끝날 때 몇 가지 사소한 조정으로 지나치게 단순화됩니다. 연간 주요 데이터 보안 침해 목록에서 결과를 확인할 수 있으며, 2019 년에는 30 억 건 이상의 노출 기록이 기록되었습니다. Capital One에 일어날 수 있다면 그것은 당신에게도 일어날 수 있습니다.

좋은 소식은 Java가 많은 보안 기능이 내장 된 오랜 개발 플랫폼이라는 것입니다. Java Security 패키지는 집중적 인 전투 테스트를 거쳤으며 새로운 보안 취약점에 대해 자주 업데이트됩니다. 2017 년 9 월에 출시 된 최신 Java EE 보안 API는 클라우드 및 마이크로 서비스 아키텍처의 취약성을 해결합니다. Java 에코 시스템에는 보안 문제를 프로파일 링하고보고하기위한 다양한 도구도 포함되어 있습니다. 

그러나 견고한 개발 플랫폼이 있더라도 경계를 유지하는 것이 중요합니다. 애플리케이션 개발은 복잡한 작업이며 취약성은 배경 소음에 숨어있을 수 있습니다. 클래스 수준 언어 기능에서 API 엔드 포인트 권한 부여에 이르기까지 애플리케이션 개발의 모든 단계에서 보안에 대해 생각해야합니다.

다음 기본 규칙은보다 안전한 Java 애플리케이션을 빌드하기위한 좋은 기반을 제공합니다.

자바 보안 규칙 # 1 : 깔끔하고 강력한 자바 코드 작성

취약성은 복잡성을 숨기는 것을 좋아하므로 기능을 희생하지 않고 코드를 가능한 한 단순하게 유지하십시오. DRY (반복하지 마십시오)와 같은 입증 된 설계 원칙을 사용하면 문제를 검토하기 더 쉬운 코드를 작성하는 데 도움이됩니다.  

항상 코드에 가능한 한 적은 정보를 노출하십시오. 구현 세부 정보를 숨기면 유지 관리가 가능하고 안전한 코드가 지원됩니다. 이 세 가지 팁은 안전한 Java 코드를 작성하는 데 큰 도움이됩니다.

  • Java의 액세스 수정자를 잘 활용하십시오 . 클래스, 메서드 및 해당 속성에 대해 서로 다른 액세스 수준을 선언하는 방법을 알면 코드를 보호하는 데 큰 도움이됩니다. 비공개로 설정할 수있는 모든 것은 비공개 여야합니다. 
  • 성찰과 성찰을 피하십시오 . 이러한 고급 기술이 장점이되는 경우도 있지만 대부분은이를 피해야합니다. 리플렉션을 사용하면 코드에 약점과 불안정성을 가져올 수있는 강력한 타이핑이 제거됩니다. 클래스 이름을 문자열로 비교하면 오류가 발생하기 쉬우 며 네임 스페이스 충돌이 쉽게 발생할 수 있습니다.
  • 항상 가능한 가장 작은 API 및 인터페이스 표면을 정의하십시오 . 구성 요소를 분리하고 가능한 가장 작은 영역에서 상호 작용하도록합니다. 애플리케이션의 한 영역이 침해에 감염 되더라도 다른 영역은 안전합니다. 

자바 보안 규칙 # 2 : 직렬화 방지

이것은 또 다른 코딩 팁이지만 자체 규칙이 될만큼 중요합니다. 직렬화는 원격 입력을 받아 완전히 부여 된 개체로 변환합니다. 생성자 및 액세스 수정자가 필요 없으며 알 수없는 데이터 스트림이 JVM에서 실행중인 코드가 될 수 있습니다. 결과적으로 Java 직렬화는 본질적으로 안전하지 않습니다.

자바 직렬화의 끝

들어 보지 못했다면 Oracle은 Java에서 직렬화를 제거 할 장기적인 계획을 가지고 있습니다. Oracle Java 플랫폼 그룹의 수석 아키텍트 인 Mark Reinhold는 모든 Java 취약점의 1/3 이상이 직렬화와 관련이 있다고 생각한다고 말했습니다.

가능한 한 Java 코드에서 직렬화 / 역 직렬화를 피하십시오. 대신 JSON 또는 YAML과 같은 직렬화 형식을 사용하는 것이 좋습니다. 절대로 직렬화 스트림을 수신하고 작동하는 보호되지 않은 네트워크 엔드 포인트를 노출하지 마십시오. 이것은 신체 상해를위한 환영 매트 일뿐입니다.

Java 보안 규칙 # 3 : 암호화되지 않은 자격 증명 또는 PII를 노출하지 마십시오.

믿기 ​​어렵지만 피할 수있는이 실수는 해마다 고통을 야기합니다.

사용자가 브라우저에 암호를 입력하면 일반 텍스트로 서버에 전송됩니다. 그것이 낮의 빛을 보는 마지막 시간이어야합니다. 당신은 해야한다 데이터베이스에 지속하기 전에 단방향 사이퍼를 통해 암호를 암호화하고, 그 값과 비교 할 때마다 다시 그것을 할.

비밀번호에 대한 규칙은 신용 카드, 주민등록번호 등 모든 개인 식별 정보 (PII)에 적용됩니다. 귀하의 신청서에 위탁 된 모든 개인 정보는 최고 수준의주의를 기울여 취급해야합니다.

데이터베이스의 암호화되지 않은 자격 증명 또는 PII는 공격자가 발견하기를 기다리는 빈틈없는 보안 허점입니다. 마찬가지로 원시 자격 증명을 로그에 쓰거나 파일 또는 네트워크로 전송하지 마십시오. 대신 암호에 대한 솔트 해시를 생성하십시오. 조사를 수행하고 권장 해싱 알고리즘을 사용하십시오.

규칙 # 4로 이동 : 암호화를 위해 항상 라이브러리를 사용하십시오. 스스로 굴리지 마십시오.

자바 보안 규칙 # 4 : 알려진 라이브러리와 테스트 된 라이브러리 사용

자체 보안 알고리즘 롤링에 대한이 질문과 답변에 눈을 즐겁게하십시오. tl; dr 교훈은 : 가능하면 알려진 신뢰할 수있는 라이브러리와 프레임 워크를 사용하는 것입니다. 이는 암호 해싱에서 REST API 인증에 이르기까지 스펙트럼 전반에 적용됩니다.

다행히도 Java와 그 생태계가 여기에 있습니다. 애플리케이션 보안의 경우 Spring Security가 사실상의 표준입니다. 다양한 옵션과 모든 앱 아키텍처에 맞는 유연성을 제공하며 다양한 보안 접근 방식을 통합합니다.

보안 문제를 해결하기위한 첫 번째 본능은 조사를하는 것입니다. 모범 사례를 조사한 다음 이러한 사례를 구현할 라이브러리를 조사하십시오. 예를 들어 JSON 웹 토큰을 사용하여 인증 및 권한 부여를 관리하려는 경우 JWT를 캡슐화하는 Java 라이브러리를 살펴본 다음이를 Spring Security에 통합하는 방법을 배웁니다.

신뢰할 수있는 도구를 사용하더라도 권한 부여와 인증을 묶는 것은 매우 쉽습니다. 천천히 움직이고 모든 일을 다시 확인하십시오.

자바 보안 규칙 # 5 : 외부 입력에 대한 편집증

사용자가 양식, 데이터 저장소 또는 원격 API에 입력 한 것이 든 외부 입력을 신뢰하지 마십시오.

SQL 주입 및 XSS (교차 사이트 스크립팅)는 외부 입력을 잘못 처리하여 발생할 수있는 가장 일반적으로 알려진 공격입니다. 잘 알려지지 않은 예 (많은 것 중 하나)는 XML 엔티티 확장이 서비스 거부 공격을 일으킬 수있는 "십억 웃음 공격"입니다.

입력을받을 때마다 온 전성을 확인하고 삭제해야합니다. 이는 처리를 위해 다른 도구 나 시스템에 제공 될 수있는 모든 경우에 특히 그렇습니다. 예를 들어, OS 명령 줄에 대한 인수가 될 수 있다면 조심하세요!

특별하고 잘 알려진 인스턴스는 다음 규칙에서 다룰 SQL 주입입니다.

Java 보안 규칙 # 6 : 항상 준비된 문을 사용하여 SQL 매개 변수를 처리합니다.

SQL 문을 작성할 때마다 실행 코드 조각을 보간 할 위험이 있습니다.

이를 알면 항상 java.sql.PreparedStatement 클래스를 사용하여 SQL을 생성 하는 것이 좋습니다 . MongoDB와 같은 NoSQL 저장소에도 유사한 기능이 있습니다. ORM 계층을 사용하는 경우 구현은 PreparedStatement내부적으로 s를 사용 합니다.

자바 보안 규칙 # 7 : 오류 메시지를 통해 구현을 밝히지 마십시오

프로덕션의 오류 메시지는 공격자에게 유용한 정보 소스가 될 수 있습니다. 특히 스택 추적은 사용중인 기술 및 사용 방법에 대한 정보를 표시 할 수 있습니다. 최종 사용자에게 스택 추적을 공개하지 마십시오.

로그인 실패 경고도이 범주에 속합니다. 일반적으로 오류 메시지는 "로그인 실패"대 "해당 사용자를 찾지 못함"또는 "잘못된 암호"로 제공되어야합니다. 잠재적으로 악의적 인 사용자에게 가능한 한 적은 도움을 제공합니다.

이상적으로는 오류 메시지가 애플리케이션의 기본 기술 스택을 나타내지 않아야합니다. 해당 정보를 가능한 한 불투명하게 유지하십시오.

자바 보안 규칙 # 8 : 보안 릴리스를 최신 상태로 유지

2019 년부터 Oracle은 Java에 대한 새로운 라이센스 체계와 릴리스 일정을 구현했습니다. 개발자에게는 안타깝게도 새로운 릴리스 주기로 인해 작업이 더 쉬워지지 않습니다. 그럼에도 불구하고 보안 업데이트를 자주 확인하고이를 JRE 및 JDK에 적용해야합니다.

Oracle 홈페이지에서 보안 경고를 정기적으로 확인하여 사용할 수있는 중요한 패치가 무엇인지 확인하십시오. 매 분기마다 Oracle은 Java의 현재 LTS (장기 지원) 릴리스에 대한 자동 패치 업데이트를 제공합니다. 문제는 Java 지원 라이센스 비용을 지불하는 경우에만 해당 패치를 사용할 수 있다는 것입니다.

조직에서 이러한 라이선스 비용을 지불하는 경우 자동 업데이트 경로를 따르십시오. 그렇지 않다면 아마도 OpenJDK를 사용하고있을 것이고 직접 패치를해야 할 것입니다. 이 경우 바이너리 패치를 적용하거나 기존 OpenJDK 설치를 최신 버전으로 간단히 교체 할 수 있습니다. 또는 Azul의 Zulu Enterprise와 같이 상업적으로 지원되는 OpenJDK를 사용할 수 있습니다.

모든 보안 패치가 필요합니까?

보안 경고를 면밀히 살펴보면 주어진 업데이트가 필요하지 않을 수 있습니다. 예를 들어 2020 년 1 월 릴리스 는 중요한 Java 업데이트로 보입니다 . 그러나 자세히 읽어 보면이 업데이트는 Java 애플릿 보안의 허점 만 패치하고 Java 서버에는 영향을주지 않습니다.

자바 보안 규칙 # 9 : 의존성 취약점 찾기

취약점에 대한 코드베이스 및 종속성을 자동으로 스캔하는 데 사용할 수있는 많은 도구가 있습니다. 당신이해야 할 일은 그것들을 사용하는 것입니다.

오픈 웹 애플리케이션 보안 프로젝트 인 OWASP는 코드 보안 향상에 전념하는 조직입니다. OWASP의 신뢰할 수있는 고품질 자동 코드 스캔 도구 목록에는 여러 Java 기반 도구가 포함되어 있습니다.

코드베이스를 정기적으로 확인하고 타사 종속성도 주시하십시오. 공격자는 오픈 소스와 비공개 라이브러리를 모두 표적으로 삼습니다. 종속성에 대한 업데이트를 확인하고 새 보안 수정이 릴리스되면 시스템을 업데이트하십시오.

자바 보안 규칙 # 10 : 사용자 활동 모니터링 및 기록

애플리케이션을 적극적으로 모니터링하지 않으면 단순한 무차별 대입 공격도 성공할 수 있습니다. 모니터링 및 로깅 도구를 사용하여 앱 상태를 주시하십시오.

모니터링이 왜 중요한지 확신하고 싶다면 애플리케이션 수신 포트에서 TCP 패킷을보고 지켜보십시오. 단순한 사용자 상호 작용을 훨씬 넘어서 모든 종류의 활동을 볼 수 있습니다. 이러한 활동 중 일부는 취약점을 검색하는 봇 및 악의적 행위자가 될 것입니다.

실패한 로그인 시도를 로깅 및 모니터링하고 원격 클라이언트가 무단으로 공격하는 것을 방지하기위한 대책을 배포해야합니다.

모니터링은 설명 할 수없는 스파이크를 경고 할 수 있으며 로깅은 공격 후 무엇이 잘못되었는지 파악하는 데 도움이 될 수 있습니다. Java 에코 시스템에는 로깅 및 모니터링을위한 다양한 상용 및 오픈 소스 솔루션이 포함되어 있습니다.

자바 보안 규칙 # 11 : 서비스 거부 (DoS) 공격주의

잠재적으로 값 비싼 리소스를 처리하거나 잠재적으로 값 비싼 작업을 수행 할 때마다 폭주하는 리소스 사용을 방지해야합니다.

오라클은 "Denial Of Service"제목 아래에 Secure Coding Guidelines for Java SE 문서에서 이러한 유형의 문제에 대한 잠재적 벡터 목록을 유지합니다.

기본적으로 압축 파일의 압축을 푸는 것과 같은 비용이 많이 드는 작업을 수행 할 때마다 리소스 사용량이 급증하는지 모니터링해야합니다. 파일 매니페스트를 신뢰하지 마십시오. 실제 디스크 또는 메모리 내 소비량 만 신뢰하고이를 모니터링하고 서버를 무릎으로 가져 오는 초과를 방지하십시오.

마찬가지로 일부 처리에서는 예기치 않은 영구 루프를 감시하는 것이 중요합니다. 루프가 의심되는 경우 루프가 진행되고 있는지 확인하는 가드를 추가하고 좀비가 된 것처럼 보이면 회로를 단락시킵니다.

Java 보안 규칙 # 12 : Java 보안 관리자 사용 고려

Java에는 실행중인 프로세스가 액세스 할 수있는 리소스를 제한하는 데 사용할 수있는 보안 관리자가 있습니다. 디스크, 메모리, 네트워크 및 JVM 액세스와 관련하여 프로그램을 분리 할 수 ​​있습니다. 앱에 대한 이러한 요구 사항을 좁 히면 공격으로 인한 피해 가능성이 줄어 듭니다. 또한 이러한 격리는 불편할 수 있으므로 SecurityManager기본적으로 활성화되지 않습니다.

SecurityManager의 강력한 의견에 대해 작업하는 것이 응용 프로그램에 대한 추가 보호 계층의 가치가 있는지 직접 결정 해야합니다. Java 보안 관리자의 구문 및 기능에 대해 자세히 알아 보려면 Oracle 문서를 참조하십시오.

자바 보안 규칙 # 13 : 외부 클라우드 인증 서비스 사용 고려

일부 응용 프로그램은 단순히 사용자 데이터를 소유해야합니다. 나머지는 클라우드 서비스 제공 업체가 이치에 맞을 수 있습니다.

주변을 검색하면 다양한 클라우드 인증 공급자를 찾을 수 있습니다. 이러한 서비스의 이점은 공급자가 귀하가 아닌 민감한 사용자 데이터를 보호 할 책임이 있다는 것입니다. 반면에 인증 서비스를 추가하면 엔터프라이즈 아키텍처가 복잡해집니다. FireBase 인증과 같은 일부 솔루션에는 스택 전체에 통합하기위한 SDK가 포함되어 있습니다.

결론

더 안전한 Java 애플리케이션을 개발하기위한 13 가지 규칙을 제시했습니다. 이 규칙은 입증 된 것입니다. 그러나 가장 큰 규칙은 이것입니다. 항상주의를 기울이고 보안을 염두에두고 소프트웨어 개발에 접근하십시오. 코드의 취약점을 찾고, Java 보안 API 및 패키지를 활용하고, 타사 도구를 사용하여 보안 문제에 대한 코드를 모니터링하고 기록합니다.

다음은 끊임없이 변화하는 Java 보안 환경을 따라 잡기위한 세 가지 고급 리소스입니다.

  • OWASP 상위 10
  • CWE 상위 25 위
  • 오라클의 보안 코드 지침

이 이야기, "보안 Java 애플리케이션 개발을위한 13 가지 규칙"은 원래 JavaWorld에 의해 출판되었습니다.