Slopsquatting: When Your AI Assistant Invents Packages and Attackers Register Them First
Tuần này trên Dev.to có một bài khá thú vị: một bạn chạy model local để sinh code, và model tự bịa ra 162 Python package không tồn tại. Điều đáng sợ là khi chạy lại từ đầu, 161 cái tên vẫn quay lại y hệt. Nghĩa là package do AI bịa ra không hề ngẫu nhiên. Chúng lặp lại và đoán trước được. Đây chính là điều kiện để kẻ tấn công kiếm lợi: họ cho model chạy hàng nghìn prompt, gom các tên bị bịa ra lặp lại nhiều nhất, rồi đăng ký chúng lên PyPI hoặc npm kèm payload độc hại. Kiểu tấn công này có tên là slopsquatting, họ hàng của typosquatting nhưng nguy hiểm hơn, vì người gõ lệnh cài không gõ sai chữ nào. Họ chỉ tin AI. Bài này mình chia sẻ cách team mình phòng thủ thực tế: script kiểm tra dependency, cấu hình lock file và một bước chặn trong CI. Tấn công diễn ra như thế nào Kịch bản rất đời thường. Bạn hỏi AI: "parse file HEIC sang JPEG trong FastAPI thế nào?". AI trả lời rất tự tin, kèm dòng pip install fastapi-heic-converter. Package này nghe rất hợp lý nhưng chưa bao giờ tồn tại. Nếu có ai đó đã đăng ký cái tên ấy trước bạn, thì setup.py hoặc build hook của nó sẽ chạy ngay trên máy bạn lúc cài. flowchart LR A[Attacker chạy hàng nghìn prompt] --> B[Gom tên package bị hallucinate lặp lại] B --> C[Đăng ký tên lên PyPI hoặc npm] D[Developer hỏi AI] --> E[AI gợi ý pip install tên bịa] C --> F[Package độc hại đã có sẵn] E --> F F --> G[setup.py hoặc postinstall chạy] G --> H[Lộ token, SSH key, file .env] Có ba điểm làm slopsquatting nguy hiểm hơn typosquatting: Tên nghe rất hợp lý, thường ghép từ framework thật cộng với chức năng, ví dụ flask-jwt-helper hay react-native-secure-storage-pro. Coding agent tự cài luôn. Khi agent có quyền chạy shell, nó thấy ModuleNotFoundError là gõ pip install ngay, chẳng ai kịp liếc qua. Tên lặp lại giữa các lần chạy, nên attacker biết chắc mình đang nhắm vào đâu. Script kiểm tra dependency trước khi cài Cách phòng thủ rẻ nhất là đừng tin bất kỳ tên package nào chưa được kiểm chứng. PyPI có JSON API công khai tại https://pypi.org/pypi//json, đủ để biết package có tồn tại không, có từ bao giờ, có bao nhiêu release. Mình viết một script nhỏ chỉ dùng thư viện chuẩn, chạy được với Python 3.9+: #!/usr/bin/env python3 # check_deps.py - kiểm tra package trong requirements.txt có đáng tin không import json import re import sys import urllib.error import urllib.request from datetime import datetime, timezone MIN_AGE_DAYS = 90 MIN_RELEASES = 3 def check(name): url = f'https://pypi.org/pypi/{name}/json' try: with urllib.request.urlopen(url, timeout=10) as r: data = json.load(r) except urllib.error.HTTPError as e: if e.code == 404: return 'MISSING', 'không tồn tại trên PyPI' raise releases = data['releases'] uploads = [ f['upload_time_iso_8601'] for files in releases.values() for f in files ] if not uploads: return 'SUSPICIOUS', 'không có file release nào' first = min(datetime.fromisoformat(u.replace('Z', '+00:00')) for u in uploads) age = (datetime.now(timezone.utc) - first).days if age < MIN_AGE_DAYS or len(releases) < MIN_RELEASES: return 'SUSPICIOUS', f'mới {age} ngày, {len(releases)} release' return 'OK', f'{age} ngày, {len(releases)} release' def parse(path): for line in open(path, encoding='utf-8'): line = line.split('#')[0].strip() if not line or line.startswith('-'): continue yield re.split(r'[=!~;\[ ]', line)[0] if __name__ == '__main__': bad = 0 for pkg in parse(sys.argv[1] if len(sys.argv) > 1 else 'requirements.txt'): status, info = check(pkg) print(f'{status:
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to