Investigating the application of differential fuzzing to support the identification and suppression of equivalent mutants: An experimental study
이 실험적 연구는 차분 퍼징(differential fuzzing)이 다양한 실제 소프트웨어 프로젝트 전반에서 동등한 뮤턴트(equivalent mutants)를 효율적으로 식별하고 억제하기 위한 실용적이고 언어에 구애받지 않는 접근 방식임을 입증하며, 전통적인 테스트 스위트를 강화하기 위한 실행 가능한 입력을 생성하는 동시에 완벽에 가까운 뮤테이션 점수를 달성한다는 것을 보여준다.
원본 논문은 CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) 라이선스로 제공됩니다. 이것은 아래 논문에 대한 AI 생성 설명입니다. 저자가 작성하거나 승인한 것이 아닙니다. 기술적 정확성을 위해서는 원본 논문을 참조하세요. 전체 면책 조항 읽기
소프트웨어 테스팅은 컴퓨터 프로그램이 올바르게 작동하는지 확인하는 과정이지만, 프로그램은 복잡하고 입력값은 무한하기 때문에 가능한 모든 실수를 찾아내는 것은 거의 불가능합니다. 이를 해결하기 위해 연구자들은 뮤테이션 테스팅(mutation testing)이라는 기법을 사용하는데, 이는 기존의 테스트가 오류를 잡아낼 수 있는지 확인하기 위해 코드에 의도적으로 작고 현실적인 오류를 주입하는 방식입니다. 만약 테스트가 오류를 발견하지 못한다면, 이는 테스트 스위트가 충분히 강력하지 않다는 것을 의미합니다. 그러나 이 방법은 고질적인 장애물에 직면해 있습니다. 일부 가짜 오류들은 너무 미묘해서 프로그램의 동작을 전혀 변화시키지 않으며, 이로 인해 탐지가 불가능해집다는 점입니다. 이러한 오류들을 동등한 뮤턴트(equivalent mutants)라고 하며, 이를 식별하려면 보통 인간 전문가가 코드를 한 줄 한 줄 읽으며 상당한 시간을 소비해야 합니다. 이는 이 테스팅 방식의 광범위한 사용을 가로막아 온 느리고 비용이 많이 드는 과정입니다.
동시에, 퍼징(fuzzing)이라 불리는 또 다른 테스팅 방법은 보안 결함을 찾는 표준 도구로 자리 잡았습니다. 퍼징은 프로그램이 중단되는지 확인하기 위해 방대한 양의 무작위 또는 잘못된 데이터를 프로그램에 입력하는 방식으로 작동합니다. 프로그램이 멈추게 만드는 버그를 찾는 데는 효과적이지만, 전통적인 퍼징은 프로그램의 계산 방식이나 동작을 변화시키면서도 충돌(crash)을 일으키지 않는 미묘한 오류들은 놓치는 경우가 많습니다. 상파울루 대학교의 연구진은 이 두 세계를 결합하는 방법을 탐구하는 새로운 연구를 진행했습니다. 그들은 디퍼런셜 퍼징(differential fuzzing)이라 불리는 기법을 조사했는데, 이는 원본 프로그램과 미세한 오류가 포함된 버전을 나란히 실행하여 동일한 데이터를 입력하고 두 버전의 결과를 비교하는 방식입니다. 만약 두 버전이 서로 다른 출력을 생성한다면, 오류가 포착됩니다. 연구진은 이 접근 방식이 그 까다로운 동등한 뮤턴트들을 자동으로 식별할 수 있는지, 그리고 인간보다 더 빠르게 수행할 수 있는지를 확인하고자 했습니다.
이 아이디어를 테스트하기 위해 연구팀은 네 가지 다른 프로그래밍 언어(C++, C, Go, Python)로 작성된 네 가지 유명 오픈 소스 소프트웨어 프로젝트의 특정 함수 여섯 개를 선정했습니다. 이 프로젝트에는 암호화폐 프로토콜인 비트코인 코어(Bitcoin Core), 암호화 라이브러리인 OpenSSL, 결제 채널 네트워크인 LND, 그리고 날짜 및 시간 라이브러리인 Arrow가 포함되었습니다. 모든 프로그래밍 언어에 대해 오류를 생성할 수 있는 도구를 사용하여, 연구진은 이 함수들의 유효한 변형 1,090개를 생성했습니다. 자동화된 테스팅을 시작하기 전, 연구진은 명백히 동등한 오류들을 제거하기 위해 오류들을 수동으로 검사하였으며, 남은 도전적인 사례들을 통해 자동화 시스템이 나머지를 구별할 수 있는지 확인했습니다. 그 후 연구진은 표준 유닛 테스트부터 오류당 5분간 실행되는 시간 제한 퍼징 세션에 이르기까지 다섯 가지 다른 테스트 시나리오를 실행했습니다.
결과에 따르면, 충돌만을 감시하는 전통적인 퍼징이 가장 효과가 낮은 방법이었으며, 오류를 거의 잡아내지 못했습니다. 반면, 디퍼런셜 퍼징 접근 방식은 놀라울 정도로 강력한 성능을 보여주었습니다. 각 오류를 테스트하는 데 5분의 시간 제한이 주어졌을 때, 이 방법은 6개 함수 중 5개에서 오류의 동작을 성공적으로 식별하고 확인하여 98%에서 100% 사이의 성공률을 달elle 성했습니다. 처음에 어려움을 겪었던 한 함수에 대해서는, 예상 키워드 목록을 추가하는 간단한 조치가 시스템이 입력을 더 잘 이해하도록 도와 결국 완벽한 점수에 도달하게 만들었습니다. 또한 연구는 이러한 오류를 찾는 데 걸린 시간이 놀라울 정도로 짧았음을 밝혔는데, 평균적으로 시스템은 약 30초 만에 차이를 찾아냈으며, 이는 사람이 단 하나의 사례를 분석하는 데 통상적으로 걸리는 15분보다 훨씬 빠른 속도였습니다.
연구진은 단순히 오류를 찾는 것을 넘어, 퍼징 과정 중에 사용된 데이터가 숨겨진 가치를 지니고 있다는 사실을 발견했습니다. 퍼징 도구가 생성한 입력값의 집합인 시드 코퍼스(seed corpus)에는 기존의 유닛 테스트가 놓쳤던 특정 테스트 케이스들이 포함되어 있었습니다. 이러한 입력값들은 전통적인 테스트 스위트가 감지하지 못한 뮤턴트를 제거할 수 있었습니다. 이는 보안 팀이 이미 생성하고 있는 데이터를 일반적인 소프트웨어 품질을 높이기 위한 자원으로 재사용할 수 있음을 시사하며, 보안 테스팅의 부산물을 일반적인 소프트웨어 품질 관리를 위한 자원으로 전환하는 것입니다. 또한 연구는 가장 탐지하기 어려운 오류를 찾는 데 걸리는 시간을 분석했는데, 대부분은 빠르게 발견되었지만 일부는 훨씬 더 많은 시간을 필요로 했으며, 어떤 작업은 조금 더 오래 걸리고 어떤 작업은 매우 오래 걸리는 것처럼 난이도가 크게 달라지는 패턴을 보였습니다.
연구진은 디퍼런셜 퍼징이 이러한 까다로운 오류의 분류를 지원하는 실용적이고 언어에 구애받지 않는 방법을 제공한다고 결론지었습니다. 이 방식은 복잡한 새로운 도구나 언어별 설정이 필요하지 않은데, 단순히 원본 코드와 수정된 버전을 비교하기 때문입니다. 생존한 오류들을 모두 분류하려고 애쓰는 대신, 이를 수동 검토 대상 후보로 취급함으로써 이 방법은 인간의 노력을 획기적으로 줄여줍니다. 연구는 이 접근 방식이 기존 워크플로우에 통합되어 진정으로 동등한 오류들을 효율적으로 걸러내고, 인간 전문가가 여전히 불확실한 소수의 사례에만 집중할 수 있게 한다고 제안합니다. 이러한 결과는 프로그램 동작의 단순한 자동 비교가 오랫동안 광범위한 산업적 도입을 어렵게 만들었던 비용과 시간 문제를 해결할 수 있음을 나타냅니다.
연구 분야의 논문에 파묻히고 계신가요?
연구 키워드에 맞는 최신 논문의 일일 다이제스트를 받아보세요 — 기술 요약 포함, 당신의 언어로.