
보이지 않는 양방향 유니코드 문자를 코드에서 스캔합니다 (Trojan Source 공격 방지, CVE-2021-42574)
숨겨진 유니코드 양방향 문자는 소스 코드를 실제 실행과 다르게 보이게 만들 수 있습니다. 이는 CVE-2021-42574 — 트로이 소스 공격입니다.
공격자는 텍스트 방향을 뒤집는 문자를 삽입합니다. 코드 리뷰에서는 다음과 같이 보입니다:
access_level = "admin"
하지만 컴파일러는 다음과 같이 봅니다:
access_level = "user"
이 문자들은 보이지 않습니다. 편집기에 표시되지 않고, 리뷰어도 발견하지 못합니다. bidi-guard는 찾아냅니다.
pip install bidi-guard
# 현재 디렉터리 재귀적으로 스캔
bidi-guard scan .
# 특정 파일 스캔
bidi-guard scan src/auth.py
모든 양방향 유니코드 문자를 찾아 정확한 위치, 컨텍스트 및 심각도를 표시합니다.
name: BiDi Guard
on: [push, pull_request]
jobs:
bidi-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install bidi-guard
- run: bidi-guard ci .
.pre-commit-config.yaml에 추가:
repos:
- repo: https://github.com/Moshe-ship/bidi-guard
rev: v0.1.0
hooks:
- id: bidi-guard
16개의 모든 유니코드 양방향 제어 문자:
높음 또는 심각으로 표시된 문자는 표시되는 텍스트를 적극적으로 재배열할 수 있습니다 — 이는 트로이 소스 공격에 사용되는 문자들입니다.
from bidi_guard import scan_file, Finding
findings = scan_file("src/auth.py")
for f in findings:
print(f"{f.char_name} at line {f.line}:{f.col} — severity: {f.severity}")
이 문자들은 보이지 않습니다. 말 그대로 보이지 않습니다:
grep "RLO" file.py # 아무 것도 찾지 못함
cat file.py # 완전히 정상적으로 보임
bidi-guard는 grep이 찾을 수 없는 것을 보여줍니다: 정확한 문자, 그 위치, 주변 컨텍스트, 심각도 수준, 그리고 그 기능을 알려줍니다. 또한 문자를 제거하여 자동으로 수정할 수도 있습니다.
MIT — Musa the Carpenter
사우디 AI 커뮤니티가 제공합니다 — 먼저 아랍인을 위해, 그리고 전 세계를 위해.
| 명령어 | 설명 |
|---|
scan | 파일에서 bidi 문자를 스캔하고 컨텍스트와 함께 결과 표시 |
ci | CI 모드 — 위험한 문자가 발견되면 0이 아닌 종료 코드 반환 |
fix | 파일에서 모든 bidi 문자 제거 (기본적으로 대화형) |
explain | 각 bidi 문자의 기능을 시각적 예제와 함께 설명 |
init | 프로젝트를 위한 .bidi-guard.yml 설정 파일 생성 |
| 코드 포인트 | 이름 | 약어 | 심각도 |
|---|
| U+200E | 왼쪽에서 오른쪽 표시 | LRM | 낮음 |
| U+200F | 오른쪽에서 왼쪽 표시 | RLM | 낮음 |
| U+061C | 아랍 문자 표시 | ALM | 낮음 |
| U+200D | 너비 없음 연결자 | ZWJ | 낮음 |
| U+200C | 너비 없음 비연결자 | ZWNJ | 낮음 |
| U+2066 | 왼쪽에서 오른쪽 고립 | LRI | 중간 |
| U+2067 | 오른쪽에서 왼쪽 고립 | RLI | 높음 |
| U+2068 | 첫 번째 강한 고립 | FSI | 높음 |
| U+2069 | 팝 방향 고립 | PDI | 중간 |
| U+202A | 왼쪽에서 오른쪽 포함 | LRE | 중간 |
| U+202B | 오른쪽에서 왼쪽 포함 | RLE | 높음 |
| U+202C | 팝 방향 서식 | 중간 | |
| U+202D | 왼쪽에서 오른쪽 덮어쓰기 | LRO | 높음 |
| U+202E | 오른쪽에서 왼쪽 덮어쓰기 | RLO | 심각 |
| U+2028 | 줄 구분자 | LS | 중간 |
| U+2029 | 단락 구분자 | PS | 중간 |