build(security): add migration and CI security gates
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import struct
|
||||
import base64
|
||||
import uuid
|
||||
import xml.etree.ElementTree as ET
|
||||
from typing import Optional
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from defusedxml import ElementTree as ET
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
||||
from fastapi.responses import PlainTextResponse
|
||||
from pydantic import BaseModel
|
||||
@@ -38,17 +40,20 @@ class BindConfirmRequest(BaseModel):
|
||||
def _verify_signature(token: str, timestamp: str, nonce: str, encrypted: str, signature: str) -> bool:
|
||||
items = sorted([token, timestamp, nonce, encrypted])
|
||||
raw = "".join(items)
|
||||
return hashlib.sha1(raw.encode()).hexdigest() == signature
|
||||
# The WeCom callback protocol mandates SHA-1; compare_digest avoids timing leaks.
|
||||
expected = hashlib.sha1(raw.encode(), usedforsecurity=False).hexdigest()
|
||||
return hmac.compare_digest(expected, signature)
|
||||
|
||||
|
||||
def _decrypt_msg(encrypted: str) -> str:
|
||||
"""Decrypt WeChat Work callback message. Returns plaintext XML."""
|
||||
key = base64.b64decode(settings.WECOM_ENCODING_AES_KEY + "=")
|
||||
ciphertext = base64.b64decode(encrypted)
|
||||
from Crypto.Cipher import AES
|
||||
cipher = AES.new(key, AES.MODE_CBC, iv=key[:16])
|
||||
plaintext = cipher.decrypt(ciphertext)
|
||||
decryptor = Cipher(algorithms.AES(key), modes.CBC(key[:16])).decryptor()
|
||||
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
|
||||
pad_len = plaintext[-1]
|
||||
if pad_len < 1 or pad_len > 32 or plaintext[-pad_len:] != bytes([pad_len]) * pad_len:
|
||||
raise ValueError("Invalid callback padding")
|
||||
plaintext = plaintext[:-pad_len]
|
||||
msg_len = struct.unpack(">I", plaintext[16:20])[0]
|
||||
return plaintext[20:20 + msg_len].decode("utf-8")
|
||||
|
||||
Reference in New Issue
Block a user