본문 바로가기

1. CSS를 이용한 보안 문제

CSS 인젝션

CSS 인젝션 공격은 공격자가 악성 CSS 코드를 삽입하여 웹 애플리케이션의 디자인을 조작하거나 사용자 데이터를 노출할 수 있는 공격입니다.

예방 방법:

  • 사용자 입력 검증: 사용자 입력이 CSS 코드로 해석되지 않도록 항상 검증하고 필터링합니다.
  • CSS 파일의 정적 로딩: 가능한 한 사용자로부터 직접 CSS를 받아서 처리하지 않도록 하세요. 정적 CSS 파일을 사용하는 것이 좋습니다.
  • 콘텐츠 보안 정책 (CSP): CSP를 설정하여 외부 CSS를 포함시키지 않도록 제한할 수 있습니다.
<meta http-equiv="Content-Security-Policy" content="style-src 'self';">

 

2. 쿠키 관련 보안 문제

쿠키 변조

사용자가 쿠키 값을 조작하여 애플리케이션의 보안에 영향을 줄 수 있습니다.

예방 방법:

  • 쿠키 암호화: 쿠키 값을 암호화하여 클라이언트 측에서 변조되더라도 의미가 없도록 합니다.
  • HTTP 전송 보안: Secure 플래그를 사용하여 HTTPS 연결을 통해서만 쿠키가 전송되도록 합니다.
Cookie cookie = new Cookie("name", "value");
cookie.setSecure(true);
  • HTTP-Only 플래그: HttpOnly 플래그를 사용하여 자바스크립트에서 쿠키에 접근할 수 없도록 합니다.
cookie.setHttpOnly(true);
  • SameSite 속성: 쿠키의 SameSite 속성을 설정하여 크로스 사이트 요청 위조(CSRF) 공격을 방지합니다.
cookie.setSameSite("Strict");

 

3. 일반적인 보안 조치

입력 검증

모든 사용자 입력은 서버 측에서 반드시 검증해야 합니다. 유효하지 않은 데이터가 시스템에 유입되지 않도록 합니다.

XSS 방지

입력된 데이터를 HTML에 삽입할 때는 HTML 엔티티 인코딩을 사용하여 스크립트 태그가 실행되지 않도록 합니다.

public static String escapeHtml(String text) {
    return text.replace("&", "&amp;")
               .replace("<", "&lt;")
               .replace(">", "&gt;")
               .replace("\"", "&quot;")
               .replace("'", "&#39;");
}

 

SQL 인젝션 방지

SQL 쿼리를 작성할 때는 프리페어드 스테이트먼트를 사용하여 입력된 데이터를 안전하게 처리합니다.

String sql = "SELECT * FROM users WHERE username = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    pstmt.setString(1, username);
    ResultSet rs = pstmt.executeQuery();
}

 

파일 업로드 보안

파일 업로드 시 파일 이름을 검증하고, 업로드 경로를 제한하여 악성 파일의 업로드를 방지합니다.

 

String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
// 파일 이름 검증 및 안전한 디렉토리로 저장

 

결론

웹 애플리케이션 보안은 여러 측면에서 접근해야 합니다. CSS, 쿠키, SQL 인젝션, XSS 등의 문제를 적절히 처리하여 보안을 강화하는 것이 중요합니다. 이러한 방어 조치를 통해 공격의 가능성을 줄이고, 사용자 데이터를 안전하게 보호할 수 있습니다.

 


정적쿼리와 동적쿼리란?

 

정적 쿼리동적 쿼리는 SQL 쿼리의 작성 방식에 따라 구분됩니다. 두 가지는 쿼리의 유연성, 보안성, 성능 등에 차이를 가져옵니다.

정적 쿼리 (Static Query)

정적 쿼리는 쿼리의 구조가 실행 시점에 고정되어 있는 쿼리입니다. 쿼리가 실행될 때마다 구조가 변하지 않으며, 모든 조건과 값이 쿼리문에 하드코딩되어 있습니다. 정적 쿼리는 일반적으로 다음과 같은 특징이 있습니다:

  • 구조 고정: 쿼리의 구조가 실행 시점에 고정되어 있습니다. 예를 들어, SELECT * FROM users WHERE id = 1과 같은 쿼리는 정적 쿼리입니다.
  • 성능: 데이터베이스의 쿼리 캐시를 활용할 수 있어 성능이 좋아질 수 있습니다.
  • 보안: 쿼리의 구조가 변경되지 않기 때문에 SQL 인젝션 공격에 상대적으로 안전합니다.

예시:

String sql = "SELECT * FROM users WHERE id = 1";
try (Statement stmt = connection.createStatement();
     ResultSet rs = stmt.executeQuery(sql)) {
    while (rs.next()) {
        // 결과 처리
    }
}

 

동적 쿼리 (Dynamic Query)

동적 쿼리는 쿼리의 구조가 실행 시점에 동적으로 변경되는 쿼리입니다. 쿼리의 조건이나 필드가 실행 시점에 결정되며, 사용자 입력이나 다른 조건에 따라 쿼리의 내용이 바뀔 수 있습니다. 동적 쿼리는 일반적으로 다음과 같은 특징이 있습니다:

  • 구조 변경 가능: 쿼리의 구조가 실행 시점에 동적으로 결정됩니다. 예를 들어, SELECT * FROM users WHERE id = ?와 같은 쿼리는 동적 쿼리입니다.
  • 유연성: 다양한 조건과 필터를 쿼리에 추가할 수 있어 유연한 데이터 검색이 가능합니다.
  • 보안: 동적 쿼리를 사용할 때는 SQL 인젝션 공격의 위험이 있으므로, PreparedStatement를 사용하여 안전하게 처리해야 합니다.

예시:

String sql = "SELECT * FROM users WHERE id = ?";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    pstmt.setInt(1, userId);
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            // 결과 처리
        }
    }
}

 

WHERE 1=1의 사용

WHERE 1=1은 조건문이 항상 참이므로, 쿼리에서 조건을 추가하거나 제거할 때 유용할 수 있습니다. 동적 쿼리를 생성할 때, 이와 같은 구문을 사용하여 기본 조건을 추가한 후, 조건을 동적으로 추가하는 방식으로 유연성을 높일 수 있습니다. 그러나 보안 관점에서는 쿼리의 구조를 단순화하고 불필요한 조건을 포함하지 않는 것이 좋습니다.

예시:

StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE 1=1");
if (username != null && !username.isEmpty()) {
    sql.append(" AND username = ?");
}
if (age > 0) {
    sql.append(" AND age = ?");
}
try (PreparedStatement pstmt = connection.prepareStatement(sql.toString())) {
    int index = 1;
    if (username != null && !username.isEmpty()) {
        pstmt.setString(index++, username);
    }
    if (age > 0) {
        pstmt.setInt(index, age);
    }
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            // 결과 처리
        }
    }
}

 

요약

  • 정적 쿼리: 쿼리의 구조가 고정되어 있으며, 성능과 보안 면에서 유리합니다.
  • 동적 쿼리: 쿼리의 구조가 실행 시점에 동적으로 결정되며, 유연성과 확장성이 좋지만 SQL 인젝션에 주의해야 합니다.
  • WHERE 1=1: 동적 쿼리에서 기본 조건을 추가하거나 쉽게 쿼리의 조건을 조합할 때 유용하지만, 보안 및 성능 관점에서 주의가 필요합니다.
반응형

코카티비-CoCaTV

생활하면서 불편한 것들, 생활하면서 다음에 또 찾게 될 것 같은 것들, 기록 해뒀습니다.