실무에서 꼭 필요한 보안 지식

중요한 보안

  • https://주소/...?cd=고객 코드 에서 로그인한 사용자가 아닌 다른 사용자의 개인정보가 조회가능해서 1천만건의 개인정보가 유출되는 사고가 있었음
  • 그 외 개인정보 유출사고는 많음
  • 이런 사고가 발생할 가능성을 낮추려면 서버 개발자는 기본적인 보안에 신경써야함

인증과 인가

  • 서버 개발에서 가장 기본적인 보안은 인증(authentication)과 인가(authroization)
    • 인증은 누구인지 확인
    • 인가는 접근 권한 확인

데이터 암호화

HMAC을 이용한 데이터 검증

  • 클라이언트가 보낸 메시지의 위변조 확인이 필요, 이때 HMAC(Hash-based Message Authentication Code) 사용
    • 메시지의 무결성과 인증을 보장하기 위해 암호화하는 기술
  • 메시지 발신자와 수신자는 비밀키를 공유
  • 발신자는 메시지를 비밀키로 해싱해서 생성한 MAC을 메시지 원본과 함께 수신자에게 전송
  • 수신자는 메시지를 비밀키를 이용해 MAC을 생성, 발신자가 전송한 MAC과 같으면 유효, 아니면 유효하지 않은것으로 판단
  • 아래는 HMAC의 예시 코드
public static class HMAC {
  private String secretKey;
  public HMAC(String secretKey) {
    this.secretKey = secretKey;
  }
  public String hmac(String message) {
    try {
      Mac mac = Mac.getInstance("HmacSHA256");
      SecretKeySpec secretKeySpec = 
        new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
      mac.init(secretKeySpec);
      byte[] hash = mac.doFinal(message.getBytes("UTF-8"));
      return Base64.getEncoder().encodeToString(hash);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

방화벽으로 필요한 트래픽만 허용하기

  • 서버가 외부에 노출되면 다양한 공격이 들어옴
    • 서버는 필요한 만큼만 네트워크 접근을 허용하고 나머지는 차단해야함
  • 가장 기본적인 네트워크 접근 차단은 방화벽을 통해 이루어짐
    • 방화벽은 두 방향으로 제어
      • 인바운드 : 외부에서 내부로 유입
      • 아웃바운드 : 내부에서 외부로 유출
  • 인바운드에서는 필수 트래픽을 제외하고 모두 차단하는것을 권함
    • 443 (ssh)
  • 아웃바운드도 가능한 필수만 허용하고 차단하는것이 좋음

감사 로그(audit log)남기기

  • 대표적 감사 로그 기록 대상
    • 사용자 로그인/로그아웃
    • 암호 초기화 등 설정 변경 내역
    • 환자 기록을 조회한 의료진 정보
    • 계약서의 수정 이력

데이터 노출 줄이기

  • 백오피스에서 고객 정보 목록에서 개인정보 항목은 마스킹되어있어야함
  • 고객 정보 목록 조회는 소수의 인원에게만 권한을 부여하는것도 방법
  • 로그에 비밀번호 평문이 들어가거나 하면 안됨

비정상 접근 처리

  • 사용자가 평소와 다른 패턴을 보이면 비정상 접근으로 판단하고 알려주는 서비스가 존재
    • 이에 해당하는 대표적 3가지 패턴
      • 평소와 다른 장소에서 로그인
      • 평소와 다른 기기에서 로그인
      • 로그인이 여러번 실패
  • 브루트 포스(brute force)공격
    • 특정 암호를 풀기위해 가능한 모든값을 대입하는것
  • 그 외 아래상황도 비정상 접근으로 처리
    • 동일한 URL또는 API 반복 접근
    • 권한 없는 URL이나 API 접근시도

시큐어 코딩

String id = request.getParameter("id");
String query = "select id, name from member where id = '" + id + "'";
ResultSet rs = stmt.executeQuery(query);
  • 위 코드는 사용자의 입력을 SQL 구문으로 사용
  • id에 or 1=1 or id를 입력하면 or 조건으로 쿼리가 연결되어 결과적으로 모든 데이터를 조회함
  • 이게 전형적인 SQL 인젝션(injection) 공격에 해당
  • 인젝션을 막는 가장 쉬운 방법은 Prepared Statement를 사용하는것
  • 그 외 신경써야할 항목
    • 입력 값 검증
    • 개인 정보/민감 정보 암호화
    • 에러 메시지에 시스템 정보 미노출
    • 보안 통신
    • CORS(Cross Origin Resource Sharing)
    • CSRF(Cross-Site Request Forgery)

개인 보안

  • 개발자는 다양한 서버에 연결이 가능함
    • 이때문에 개발자 PC가 해킹 당하면 큰 사고로 이어질수 있음
  • 물리적 보안도 중요
    • 자리를 비울때는 화면보호기를 실행해야함