HoRain云--Python安全编程实战:加密、JWT与常见漏洞防护
安全是后端的底线。密码明文存储、SQL注入、JWT伪造、反序列化漏洞都可能造成严重后果。本文讲解Python安全编程的核心要点。一、密码存储永远不要明文存储密码。使用bcrypt或argon2。python复制下载import bcrypt # 加密 password user_password.encode() hashed bcrypt.hashpw(password, bcrypt.gensalt(rounds12)) # 校验 if bcrypt.checkpw(password, hashed): print(密码正确)argon2更现代python复制下载from argon2 import PasswordHasher ph PasswordHasher() hash ph.hash(password) try: ph.verify(hash, password) except Exception: print(密码错误)不要用MD5、SHA1、SHA256直接哈希密码容易被彩虹表攻击。二、对称加密AES-GCM提供加密和认证。python复制下载from cryptography.hazmat.primitives.ciphers.aead import AESGCM import os key AESGCM.generate_key(bit_length256) aesgcm AESGCM(key) nonce os.urandom(12) ciphertext aesgcm.encrypt(nonce, bsecret data, bassociated) plaintext aesgcm.decrypt(nonce, ciphertext, bassociated)Fernet更简单python复制下载from cryptography.fernet import Fernet key Fernet.generate_key() f Fernet(key) token f.encrypt(bsecret) print(f.decrypt(token))三、非对称加密python复制下载from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import hashes private_key rsa.generate_private_key( public_exponent65537, key_size2048) public_key private_key.public_key() ciphertext public_key.encrypt( bsecret, padding.OAEP(mgfpadding.MGF1(algorithmhashes.SHA256()), algorithmhashes.SHA256(), labelNone) ) plaintext private_key.decrypt( ciphertext, padding.OAEP(mgfpadding.MGF1(algorithmhashes.SHA256()), algorithmhashes.SHA256(), labelNone) )四、哈希与HMACpython复制下载import hashlib import hmac # SHA256 hashlib.sha256(bdata).hexdigest() # HMAC消息认证 mac hmac.new(bsecret_key, bmessage, hashlib.sha256).hexdigest() # 验证 expected hmac.new(bsecret_key, bmessage, hashlib.sha256).hexdigest() hmac.compare_digest(mac, expected) # 防时序攻击五、JWTpython复制下载import jwt from datetime import datetime, timedelta SECRET your-secret-key # 生成 payload { sub: user123, exp: datetime.utcnow() timedelta(hours1), iat: datetime.utcnow(), roles: [user] } token jwt.encode(payload, SECRET, algorithmHS256) # 验证 try: decoded jwt.decode(token, SECRET, algorithms[HS256]) print(decoded[sub]) except jwt.ExpiredSignatureError: print(token已过期) except jwt.InvalidTokenError: print(token无效)安全要点密钥足够长256位指定algorithms防算法混淆攻击校验exp、iss、aud不要把敏感信息放payload可解码六、SQL注入防护python复制下载# 危险字符串拼接 def get_user_bad(username): sql fSELECT * FROM users WHERE name {username} cursor.execute(sql) # 输入 OR 11 可绕过 # 安全参数化查询 def get_user_safe(username): sql SELECT * FROM users WHERE name %s cursor.execute(sql, (username,))ORM也需注意python复制下载# 危险 User.query.filter(fname {name}) # 安全 User.query.filter(User.name name) # 排序字段白名单 ALLOWED_SORT {id, name, created_at} sort request.args.get(sort, id) if sort not in ALLOWED_SORT: sort id七、命令注入防护python复制下载import subprocess # 危险 subprocess.run(fls {user_input}, shellTrue) # 安全列表参数不用shell subprocess.run([ls, user_input], shellFalse) # 或校验输入 import shlex subprocess.run([ls] shlex.split(user_input))八、反序列化漏洞python复制下载# 危险pickle可执行任意代码 import pickle data pickle.loads(untrusted_data) # 危险 # 安全用JSON import json data json.loads(untrusted_data)YAML同理python复制下载# 危险 yaml.load(data) # 旧版本 # 安全 yaml.safe_load(data)九、常见Web漏洞9.1 XSSpython复制下载from markupsafe import escape # 模板自动转义Jinja2默认 # {{ user_input }} # 手动转义 safe escape(user_input)9.2 CSRFpython复制下载# Flask-WTF from flask_wtf.csrf import CSRFProtect csrf CSRFProtect(app)9.3 SSRFpython复制下载import ipaddress from urllib.parse import urlparse def is_safe_url(url): parsed urlparse(url) if parsed.scheme not in (http, https): return False try: ip ipaddress.ip_address(parsed.hostname) if ip.is_private or ip.is_loopback: return False except ValueError: pass return True9.4 路径穿越python复制下载import os def safe_join(base, path): base os.path.abspath(base) target os.path.abspath(os.path.join(base, path)) if not target.startswith(base os.sep): raise ValueError(非法路径) return target十、密钥管理python复制下载# 不要硬编码 # SECRET_KEY hardcoded # 危险 # 用环境变量 import os SECRET_KEY os.environ[SECRET_KEY] # 或用密钥管理服务 from pydantic_settings import BaseSettings class Settings(BaseSettings): secret_key: str db_password: str class Config: env_file .env.env文件加入.gitignore。十一、依赖安全bash复制下载# 检查漏洞 pip install safety safety check # 或 pip install pip-audit pip-audit十二、安全清单密码用bcrypt/argon2传输用HTTPS数据库参数化查询不信任用户输入校验和转义JWT指定算法校验过期不用pickle反序列化不可信数据密钥用环境变量定期更新依赖最小权限原则记录安全日志十三、总结安全是持续的过程不是一次性的任务。掌握加密、JWT、参数化查询、输入校验能避免大多数常见漏洞。记住永远不要信任用户输入。