[하루한줄] CVE-2024-47062 : Navidrome의 SQL injection 취약점

URL

https://github.com/navidrome/navidrome/security/advisories/GHSA-58vj-cv5w-v4v6

Target

  • Navidrome ≤ 0.52.5

Explain

Navidrome은 Go로 개발된 오픈소스 음악 스트리밍 서버입니다. 다양한 운영체제와 도커 이미지를 통해 웹 기반의 음악 스트리밍 기능을 지원하고 이때 URL 파라미터가 SQL 쿼리에 그대로 사용되면서 다수의 SQL Injection 취약점이 발생했습니다.

취약한 버전의 Navidrome에서는 URL에서 파싱한 파라미터를 자동적으로 LIKE를 사용해서 SQL 쿼리에 추가되기 때문에 아래와 같은 HTTP 요청을 통해 password LIKE AAA%가 삽입되고 이를 통해 password의 값을 브루트 포싱하는 것이 가능합니다.

GET /api/user?_end=36&_order=DESC&password=AAA%

또한 URL 파라미터의 이름을 따로 검사하거나 escape 하지 않기 때문에 아래와 같은 HTTP 요청으로 임의의 SQL 구문을 실행시키는 것 또한 가능합니다.

GET /api/album?_end=36&_order=DESC&_sort=recently_added&_start=0&SELECT+*+FROM+USER--=123 HTTP/1.1

추가적으로 사용자 인증 과정에서 사용되는 아래의 함수에서도 잠재적인 취약점이 발견되었습니다.

func (r *userRepository) FindByUsername(username string) (model.User, error) {
    sel := r.newSelect().Columns("").Where(Like{"user_name": username})
    var usr model.User
    err := r.queryOne(sel, &usr)
    return &usr, err
}

username에 해당하는 사용자를 찾을 때 Like를 사용하고 있는 것을 볼 수 있고 이로 인해 사용자의 이름에 % 등을 사용해서 로그인하는 것 허용합니다.

결론적으로 공격자는 해당 취약점을 악용하여 임의의 SQL 구문을 실행하고 DB에 저장된 데이터를 유출하는 등의 행위가 가능했습니다.