초보자를 위한 코드 품질 리포트(code quality report) 읽기 1편: flake8 / bandit 결과, 어디부터 보면 될까요?

시스템을 개발해두고 “검사 돌려봤더니 에러가 한가득…” 이 상황은 개발을 시작해 본 초보자에게는 너무 정상입니다. 처음으로 코드 품질 도구를 돌려서 코드 품질 리포트(code quality report)보면 거의 항상 이런 느낌이죠.
초보자를 위한 품질 커맨드에서 한번 살펴보긴 했는데.. 코드 품질 도구가 뭔지부터 궁금해지네. 그쵸? 우선 앞에서 말한거 부터 살펴보시죠.
- flake8: Python 코드를 위한 정적 코드 분석 도구(린터)로, 코드 스타일 일관성을 유지하고 일반적인 프로그래밍 오류를 감지하는 데 사용됩니다.
- bandit: 파이썬 코드에서 일반적인 보안 취약점을 찾는 데 사용되는 정적 분석(Static Analysis Security Testing, SAST) 도구です。
이런걸 처음 보면 당연히 막막합니다.
그래서 이번 포스트 시리즈의 목표는 딱 하나예요.
“실제 코드 품질 리포트를 봤을 때
놀라지 않고,
어디부터 손대야 할지
차분히 결정할 수 있게 만드는 것”
오늘 1편에서는 전반적인 그림만 먼저 잡아볼게요.
1. flake8 vs bandit – 둘이 하는 일이 다르다

1-1. flake8은 “스타일 + 기본 에러 체커”
flake8은 크게 두 가지를 봅니다.
- 스타일/형식
- 줄 길이, 공백, import 순서, 들여쓰기 등
- 기본적인 코드 에러
- 정의 안 된 이름(F821)
- 사용하지 않는 변수/import(F401 등)
- 중복 정의(F811) 등
즉, flake8은
“이 코드는 읽기 좋고,
기본적인 문법/패턴에서 위험한 부분이 없는지 봐주는 검사기”
로 이해하면 됩니다.
주로 이런 것들이 있습니다.
- f-string placeholder 문제 (F541)
- 정의 안 된 이름(F821)
- 중복 정의(F811)
- import 관련 경고(E402 등)
- 사용 안 되는 import들 잔뜩
→ 이건 대부분 “코드 정리 + 깔끔한 리팩토링” 쪽 이슈라고 보면 됩니다.
1-2. bandit은 “보안 관점에서 의심스러운 코드 찾기”
반면에 bandit은 관점이 다릅니다.
“이 코드, 보안적으로 봤을 때
위험한 패턴이 숨어 있지 않을까?”
예를 들어
- MD5 같은 약한 해시 알고리즘 사용 (B303)
mark_safe로 필터링 안 된 HTML을 그대로 출력- f-string으로 SQL을 만드는 코드 (SQL 인젝션 위험)
urllib.request.urlopen처럼 위험 가능성이 있는 네트워크 함수- 하드코딩된 비밀번호/토큰 등
이런 패턴을 보안 경고로 알려줍니다.
bandit 결과가 아래와 같다면
- High: 3
- Medium: 10
- Low: 130
이 숫자를 어떻게 읽어야 할까요?
2. 코드 품질 리포트(code quality report) High / Medium / Low – 우선순위를 어떻게 잡을까?

코드 품질 리포트(code quality report)를 볼 때 제일 중요한 것は
“모든 경고를 똑같이 대하지 말 것”
です。
대략 이렇게 생각하면 좋아요.
🔴 High (심각)
- 당장 실제 서비스에서
보안 사고나 데이터 유출로 이어질 수 있는 수준 - はい:
- 해시로 MD5 사용 (토큰 추측 쉬움)
- 필터링 안 된 사용자 입력을 그대로 HTML에 뿌리는 경우
- raw SQL에 직접 사용자 입력을 끼워 넣는 경우
👉 전략: “최대한 빨리, 브랜치를 따로 파서, 영향 분석+수정을 같이 진행”
🟠 Medium (중간)
- 지금 당장 폭발(?)하진 않지만,
상황에 따라 위험해질 수 있는 코드들 - はい:
mark_safe사용 (입력이 안전하다고 가정할 때)- 잘못 쓰면 인젝션 위험이 있는 SQL 패턴
- URL 호출 시 예외 처리/타임아웃 부족 등
👉 전략: High 처리 뒤에 차례로, “위험한 케이스부터” 순차적으로 리팩토링
🟢 Low (낮음)
- 대부분 “권장사항” 수준
- はい:
- 사용되지 않는 import
- 디버그용 코드 흔적
- 스타일에 가까운 보안 권장 패턴
👉 전략: 자동화 도구(ex. autoflake, 포매터 등)로 한 번에 정리할 후보들입니다.
3. 이번 리포트에서 특히 눈여겨봐야 할 포인트 3가지

리포트 내용을 요약하면, 실무적으로 중요한 키워드는 이 세 가지입니다.
- MD5 사용 (High)
- 사용자나 데이터에 대한 해시/토큰 생성에 MD5를 사용
- Bandit 입장에서는 거의 무조건 High 경고
- 보안 업계에서는 오래전에 “약한 해시”로 분류된 상태
mark_safe사용 (Medium)- Django 템플릿에서 문자열을 “이거는 안전하니까 이스케이프하지 마”
라고 표시하는 함수 - 입력 데이터가 정말 100% 신뢰 가능한지,
XSS 위험은 없는지 반드시 확인해야 하는 부분
- Django 템플릿에서 문자열을 “이거는 안전하니까 이스케이프하지 마”
- f-string + raw SQL (Medium, 때로는 High급)
- Python f-string으로 SQL 문자열을 직접 조립해 쓰는 패턴
- 사용자 입력이 섞이는 순간 → SQL 인젝션 위험
- Django ORM 또는 파라미터 바인딩 방식으로 바꾸는 게 원칙
그리고 추가로
urllib.request.urlopen→ B310 (주의 대상 함수)- 이 부분은 timeout을 넣어서 “대기 무한 루프”류의 문제는 줄였지만,
여전히 URL 주체/검증/예외처리 등을 함께 고려해야 하는 포인트입니다.
4. “지금 이 상태에서 내가 뭘 하면 좋을까?” – 실전 관점
품질 리포트를 토대로 실무에서 자주 쓰는 추천 대응 순서를 정리해볼게요.
1️⃣ 리포트 전체를 “유형별로” 나눠서 본다
- 스타일/구문 문제 (flake8의 F/E/W 다수)
- 보안 핵심 이슈 (bandit High)
- 보안 관련 주의/권장사항 (bandit Medium/Low)
2️⃣ 보안 High 먼저 별도 브랜치에서 처리 계획 세우기
- MD5 → SHA-256 교체 시
- 기존 토큰/데이터와의 호환성 확인
- 외부 시스템과 연동되어 있나 체크
- 이건 2편에서 자세히 다룰 예정입니다.
3️⃣ Medium 레벨에서 실질적으로 위험한 것 골라내기
mark_safe가 정말 필요한지,
그 앞단에서 데이터 정제/검증이 되어 있는지 확인- raw SQL 쪽은
- 파라미터 바인딩이 이미 적용되어 있는지
- ORM으로 바꾸기 쉬운 쿼리인지부터 나눠보기
4️⃣ Low / 스타일 문제는 자동화 도구로 묶어서 처리
- 사용하지 않는 import 정리
- 포매터(black)로 스타일 정리
- 필요하면 autoflake 같은 도구 사용
5️⃣ 각 단계는 항상 “브랜치 쪼개기 + 체크 다시 돌리기” 패턴으로
- はい:
quality/security-md5-change브랜치quality/cleanup-unused-imports브랜치 등
- 이렇게 하면 나중에 문제가 생겨도
“어느 변경 때문에 그런지” 찾기 쉬워집니다.
5. 용어 정리
- 코드 품질 리포트
flake8, bandit 같은 도구를 실행했을 때 나오는
에러/경고/정보 메시지를 통칭해서 이렇게 부를 수 있습니다. - flake8
Python 코드의 스타일과 간단한 에러를 검사하는 도구.
예: 정의 안 된 변수, 사용하지 않는 import, 코드 스타일 위반 등. - bandit
Python 코드를 보안 관점에서 분석하는 도구.
약한 해시(MD5), 위험한 함수 사용, SQL 인젝션 가능성 등을 찾아냅니다. - High / Medium / Low (severity)
bandit가 경고의 심각도를 표시하는 단계.
High는 가능한 빨리 대응해야 할 보안 이슈,
Medium은 상황에 따라 위험해질 수 있는 코드,
Low는 권장/주의 수준. - SQL 인젝션
사용자가 입력한 값이 SQL 쿼리 문자열에 그대로 끼워져서
의도치 않은 쿼리 실행이 가능한 취약점. - XSS (Cross-Site Scripting)
악성 스크립트(주로 JavaScript)가 웹 페이지를 통해 사용자 브라우저에서 실행되는 공격.






