← λͺ©λ‘μœΌλ‘œ

πŸ” 컀밋 리뷰 상세

μ‹œκ°„ 2026-03-06 16:39:07
ν”„λ‘œμ νŠΈ DevGuardian
컀밋 38781d87
μž‘μ„±μž κΉ€μž¬μ˜
브랜치 main

AI 뢄석 κ²°κ³Ό

1. 버그 κ°€λŠ₯μ„±

파일λͺ…: ai_analyzer.py

라인 번호: 33~37

심각도: [쀑]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

analyze_jenkins_error ν•¨μˆ˜ λ‚΄μ—μ„œ result["ai_text"]을 직접 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. resultκ°€ 성곡 여뢀에 따라 ꡬ쑰가 λ‹¬λΌμ§ˆ 수 μžˆμœΌλ―€λ‘œ, result["ai_text"]에 μ ‘κ·Όν•˜κΈ° 전에 result의 쑴재 여뢀와 ai_text ν‚€μ˜ 쑴재 μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” 것이 ν•„μš”ν•©λ‹ˆλ‹€. 특히 result["success"]κ°€ False인 경우 ai_textκ°€ 없을 수 μžˆμœΌλ―€λ‘œ, 이 λΆ€λΆ„ 검증이 ν•„μš”ν•©λ‹ˆλ‹€.
예) ai_text = result.get("ai_text", "") 둜 λŒ€μ²΄ ꢌ고.

파일λͺ…: main.py

라인 번호: 216~224

심각도: [쀑]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

save_review ν•¨μˆ˜λ₯Ό 호좜 μ‹œμ— commit_id값을 f"#{jenkins_info.get('build_number', '')}" ν˜•μ‹μœΌλ‘œ μ „λ‹¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 경우 build_number 값이 없을 경우 #만 λ“€μ–΄κ°€λŠ” λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, jenkins_info.get('build_number', '')κ°€ ""이면 #만 λ‚¨λŠ” 문제λ₯Ό 사전에 λ°©μ§€ν•˜κΈ° μœ„ν•΄ 쑰건 검사λ₯Ό μΆ”κ°€ν•˜λŠ” 것을 κΆŒκ³ ν•©λ‹ˆλ‹€.

2. λ³΄μ•ˆ 취약점

파일λͺ…: main.py

라인 번호: 202~204

심각도: [상]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

jenkins_info.get('project', 'unknown')와 같은 μ‚¬μš©μž μž…λ ₯ 값을 파일 μ΄λ¦„μœΌλ‘œ 직접 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. project 값이 ../처럼 νŠΉμ • λ¬Έμžμ—΄μ„ 포함할 경우 μƒμœ„ 디렉토리 접근이 κ°€λŠ₯ν•˜λ―€λ‘œ, λ³΄μ•ˆμ— μ·¨μ•½ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ project 값이 ../../../etc/passwdκ°€ 될 경우, μ‹œμŠ€ν…œ νŒŒμΌμ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 파일λͺ… 생성 μ‹œμ— μž…λ ₯ κ°’ κ²€μ¦μ΄λ‚˜ μ •κ·œν™”κ°€ ν•„μš”ν•˜κ³ , μ˜ˆμƒμΉ˜ λͺ»ν•œ λ¬ΈμžλŠ” μ œκ±°ν•˜κ±°λ‚˜ μΉ˜ν™˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

3. μ„±λŠ₯ 이슈

파일λͺ…: main.py

라인 번호: 217~225

심각도: [쀑]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

λ‘œκ·ΈνŒŒμΌμ„ 생성할 λ•Œ strip_markdown(analysis["ai_result"]) 호좜과 μ—¬λŸ¬ f.write()λ₯Ό 반볡적으둜 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 방식은 파일 μ“°κΈ° μ‹œ IO λΆ€ν•˜κ°€ 클 수 있으며, 특히 ai_resultκ°€ 큰 경우 μ„±λŠ₯ μ €ν•˜λ‘œ μ΄μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. μ—¬λŸ¬ f.write() ν˜ΈμΆœμ„ ν•œ 번의 f.write()둜 ν†΅ν•©ν•˜λŠ” 것을 κ³ λ €ν•΄λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 예)

content = f"[AI Jenkins λΉŒλ“œ 뢄석]\nμ‹œκ°„: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\nν”„λ‘œμ νŠΈ: {jenkins_info.get('project', '')}\n..."
f.write(content)

4. μ½”λ“œ μ»¨λ²€μ…˜ μœ„λ°˜

파일λͺ…: main.py

라인 번호: 204

심각도: [ν•˜]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

print() μ‚¬μš©μ„ ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€. 특히 λ‘œκΉ…μ΄ μ•„λ‹Œ 디버깅 λͺ©μ μœΌλ‘œλ§Œ μ‚¬μš©λ˜λŠ” printλŠ” ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” λ¬Έμ œκ°€ λ˜λ―€λ‘œ, logging λͺ¨λ“ˆ μ‚¬μš©μ„ κΆŒκ³ ν•©λ‹ˆλ‹€.
예)

import logging
logging.info("πŸ”§ Jenkins λΉŒλ“œ μ‹€νŒ¨ μˆ˜μ‹ : %s #%s", jenkins_info.get('project'), jenkins_info.get('build_number'))

파일λͺ…: ai_analyzer.py

라인 번호: 20~25

심각도: [ν•˜]

μ„€λͺ… 및 κ°œμ„  μ œμ•ˆ:

call_llm(prompt) ν•¨μˆ˜μ˜ 인자둜 ν”„λ‘¬ν”„νŠΈλ₯Ό κ·ΈλŒ€λ‘œ μ „λ‹¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜λͺ…이 call_llm이고, μ΄λŠ” λ‹¨μˆœνžˆ μž…λ ₯ 데이터λ₯Ό λ°›λŠ” 것이 μ•„λ‹ˆλΌ AI 호좜 역할을 ν•˜κ²Œ λ©λ‹ˆλ‹€. λ‹€λ§Œ, prompt에 μ§μ ‘μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” 데이터가 jenkins_info.get(...) ν˜•μ‹μœΌλ‘œ κ°€μ Έμ˜€λ―€λ‘œ, μž…λ ₯κ°’ μžμ²΄κ°€ 잘λͺ»λ˜μ—ˆμ„ λ•Œ μ˜ˆμ™Έ 처리 없이 κ·ΈλŒ€λ‘œ μ‚¬μš©λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μž…λ ₯값에 λŒ€ν•œ 기본적인 νƒ€μž… 확인 및 μœ νš¨μ„± 검증을 κΆŒκ³ ν•©λ‹ˆλ‹€.


μš”μ•½

이상 μ—†μŒ: μœ„μ˜ λ¬Έμ œλ“€μ„ μ œμ™Έν•˜κ³ λŠ” μ½”λ“œ μ»¨λ²€μ…˜ 및 둜직 λ©΄μ—μ„œ 크게 λ¬Έμ œλŠ” μ—†μŠ΅λ‹ˆλ‹€.