기존에 개발한 프로그램은 사용자가 업로드한 코드나 파일을 분석하여 다양한 보안 취약점(SQL 인젝션, XSS, 디렉토리 트래버설, 민감한 정보 노출, 취약한 암호화 알고리즘 등)을 탐지하고, 취약한 코드에 대한 하이라이팅을 제공하는 웹 애플리케이션이었다. 그러나 여러 가지 문제점이 존재했다.
하지만 문제점이 너무 많다.
기존 문제점
SQL 인젝션, XSS, 디렉토리 트래버설, 하드코딩, 취약한 암호화 알고리즘 등의 탐지를 단순한 정규표현식 기반 패턴 매칭으로 수행하여 복잡한 취약점을 탐지할 수 없었다.보다 정교한 로직과 알고리즘이 필요했다.
특정 키워드를 기반으로 한 단순한 언어 감지 방식을 사용하여 신뢰도가 낮았다.
예를 들어, C언어는 #include, int main 등의 키워드로 감지하는 방식이었다.
자바스크립트, SQL, PHP, JSP, ASP 등의 언어 감지는 어려웠다.
로컬 환경에서만 작동하며 서버 형태로 배포되지 않았다.
단순히 공격 코드만 탐지했으며, 코드가 실제로 취약한지 분석하는 기능이 부족했다.
즉, SQL 인젝션이 가능한 코드인지 여부를 판별하는 것이 아니라, 직접적인 공격 코드가 입력 된 경우에만 탐지할 수 있었다.
따라서 이 프로그램을 뜯어 고치기로했다.
다양한 알고리즘 및 오픈소스 라이브러리를 활용하여 코드 분석을 고도화하기로 결정.
정규식 탐지를 보조적으로 사용하고, Pygments, Guesslang을 활용하여 더 정확한 탐지를 수행. 단순한 패턴 매칭이 아닌, 코드의 실제 취약점을 분석하여 문제점을 진단하도록 개선.
언어 감지는 세 단계로 나누어 수행하도록 변경했다.
여러가지 후보군이 있었다.
파이썬. C#. C언어의 경우에는 감지할수 있는 방법인 정규식으로도 충분히 감지가 가능했다.
하지만 자바스크립트. sql문. php. jsp . asp등은 탐지하기가 어려웠다. 이를 오픈소스라이브러리 2종류 (1. Pygments 2. guesslang)을 이용해 감지하는걸로 변경하기로함
탐지 방식은
1차 -> 정규식으로 탐지 2차 -> 조금 가볍고 빠른 pygments를 이용해 탐지. 3차 -> guesslang을 이용해 탐지 .
문제 발생!
Guesslang은 TensorFlow 기반으로 작동하기 때문에, TensorFlow의 버전 제한(3.6~3.9)으로 인해 기존 환경(3.11.2)과 호환되지 않았다.
Python 3.9 환경으로 가상환경을 재설정하여 문제를 해결하고, TensorFlow와 Guesslang을 성공적으로 설치하였다.
Tensorflow는 파이썬 3.6 ~ 3.9 까지만 지원함으로. 기존 가상환경 버전과 호환이 되지 않아서 설치가 안됨 . 따라서 3.9로 버전관리 실행!
기존 가상환경 ( python 3.11.2) 버전을 지우고 새롭게 3.9 환경으로 가상환경 설정 !
tensorflow가 아주 잘 깔리는 모습을 볼 수 있음.
# 1차: 정규식을 이용한 언어 감지
def detect_language_regex(code):
patterns = {
'Python': [r'def ', r'import ', r'class ', r'if __name__ == '],
'C': [r'#include', r'int main', r'printf', r'scanf'],
'Java': [r'public class ', r'void main', r'System.out.println'],
'JavaScript': [r'function ', r'console.log', r'var ', r'let ', r'const '],
'C++': [r'#include', r'int main', r'cout', r'cin'],
'SQL': [r'SELECT ', r'FROM ', r'INSERT INTO ', r'UPDATE ', r'DELETE FROM ']
}
for language, keywords in patterns.items():
if any(re.search(keyword, code) for keyword in keywords):
return language
return "Unknown"
# 2차: Pygments를 이용한 언어 감지
def detect_language_pygments(code):
try:
lexer = guess_lexer(code)
detected_language = lexer.name
if "Python" in detected_language or isinstance(lexer, PythonLexer):
return "Python"
return detected_language
except ClassNotFound:
return "Unknown"
# 3차: Guesslang을 이용한 언어 감지
def detect_language_guesslang(code):
guess = Guess()
detected_language = guess.language_name(code)
return detected_language if detected_language else "Unknown"
이렇게 1차. 2차 . 3차로 나뉘어 언어감지를 시도해보자
자. sql문은 잘 읽어내는 모습이다.
그럼 이것도 잡아낼 수 있을까 ?
아쉽게도 json은 text로만 감지를 하는것 같다.
bash 스크립트 문도 잘 잡아내는 모습이다. 자 이제 그럼 정규식을 제외한 나머지 라이브러리로만 감지를 해보자.
먼저 pygments 라이브러리만 사용했을때다
아깐 감지하던 SQL 코드를 감지 못하는 모습... 실망스럽다
기초적인 파이썬 코드는 잘 감지한다.
엥 ? 기본적인 자바 코드도 감지를 못한다
C++ 코드를 아두이노 코드로 인식한다.
음. pygments 하나만 쓰는건 역시 안될것같다.
탐지율이 제일 높았던건 guesslang이였다.
ruby. go. swift 등등 다양한 언어를 감지할 수 있어서 역순으로 조합했다.
1순위 -> guesslang. 2순위 -> pygments. 3순위 -> 정규식을 이용한 간단한 식.
언어 감지 테스트 결과
SQL, Python, Bash, JavaScript 등의 언어를 정확하게 감지함.
JSON 파일은 텍스트로만 인식되는 한계가 있었음.
Pygments 단독 사용 시 SQL 탐지가 실패하는 경우가 있었음.
C++ 코드를 아두이노 코드로 잘못 인식하는 등의 오류가 발생.
guesslang에서 언어 탐지를 못할경우 = return값이 Unknown인 경우 -> pygments. 여기서도 리턴값이 Unknown 혹은 ClassNotFound인 경우 정규식을 사용하는 코드인데. 사실상 guesslang에서 탐지를 못하는 경우는 없기때문에 언어감지 로직 문제는 해결됐다.
이를 해결하기 위해 Monaco Editor를 도입하여 코드 블록 형태의 편집기를 추가하였다.
적용사진
엥? 하이라이트가 표시가 안된다.
홈페이지 전체를 CSS노가다로 예쁘게 바꿔보자.
기존 UI가 단순하여 가독성이 떨어지는 문제가 있었다.
이를 해결하기 위해 Monaco Editor를 도입하여 코드 블록 형태의 편집기를 추가하였다.
개선된 UI 기능
코드 하이라이팅 지원.
자동완성 기능 추가.
코드 분석 결과를 직관적으로 표시.
어떤걸 쓸까 고민하다가. python에서 보안 취약점을 감지하는데는 Bandit이라는 라이브러리를 제공하는것을 파악했다.
추가적으로 다른언어의 취약점을 분석할때는 semgrep이라는 라이브러리를 사용할수 있다. (윈도우 환경에서 실행 안됨. WSL 혹은 docker로 연결해야함)
신기하게도 두개 모두다 import 할 필요없이 CLI 환경에서 subprocess.run을 이용해 사용한다.
둘다 json 형태로 분석결과를 가져오고. 나는 이를 받아오는 결과 코드를 짰다.
코드 분석 버튼을 눌렀을때 입력값을 확인하자
음. 예시코드에 한글이 아닌 특수문자들이 들어가서 오류가 뜬다.
sys.stdout.reconfigure(encoding='utf-8')
sys.stdin.reconfigure(encoding='utf-8')
sys.stderr.reconfigure(encoding='utf-8')
를 app.py에 추가해 강제 인코딩을 utf-8로 출력해보자.
먼저 python만 탐지 가능하지만 . 여러가지 취약점을 분석해주는 bandit이다.
bandit 먼저 해보자
bandit에서 취약점을 탐지하고 -> 해결법을 하나하나 알려주기엔 무리가 있다 판단해 gemini Api를 이용해 해결책을 제시해달라고 올려보았다.
코드에 어떤 부분이 취약한지는 먼저 설명을 해주고. 이후에 더 나은 코드를 알려주는 방식이다.
추가적으로 . 업로드가 작동하지 않았는데. 작동하게 만들어보자 .
기존 코드에서.
Detected change in 'A:\seccode\backend\uploads\2.py', reloading 되며 업로드가 ERR_CONNECTION_RESET 문제가 뜨며 이루어지지 않았다. 코드 수정을 통해 정상적으로 파일을 업로드하고 분석할 수 있게되었다. 추가적으로 파일업로드 시. 소스코드 입력창에도 자동 입력되게 만들어 가시성을 높였다.
이제. 다른 언어에 대한 취약점도 탐지해보자 .PHP 언어는 밴딧을 통해 탐지가 가능하다.
다른 언어는 확장성 문제로 해결이 어려워 일단은 파이썬에 한정지어 개발을 마무리 짓는다.
언어 감지 로직 개선
다양한 언어(Bash, JavaScript, Java, Go, Rust, Kotlin 등)를 지원하도록 개선.Guesslang, Pygments, 정규식을 조합하여 높은 탐지율을 달성.
Python 코드 보안 분석 기능 구현
Bandit을 활용하여 50가지 이상의 취약점을 탐지 가능.
Gemini API를 활용한 취약점 해결책 제공 기능 추가.
파일 업로드 기능 개선
업로드된 코드가 자동으로 Monaco Editor에 입력되도록 변경.
UI 개선 및 사용성 향상.
이번 개선을 통해 기존 프로그램의 한계를 극복하고 보다 정교한 보안 분석 기능을 추가할 수 있었다. 하지만 Semgrep과 CodeQL을 활용하지 못하여 Python과 일부 PHP 코드 외의 언어에 대한 취약점 하이라이팅이 어려운 점은 아쉬움으로 남는다.
향후 업데이트를 통해 다른 언어의 보안 분석 기능을 확장하고, 서버 배포 예정.