| """Tests for security fixes - cryptographic random number generation and SSL context.""" |
|
|
| import os |
| import ssl |
| import sys |
|
|
| |
| sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) |
|
|
| import pytest |
|
|
|
|
| def test_wecom_crypto_uses_secrets(): |
| """Test that WXBizJsonMsgCrypt uses secrets module instead of random.""" |
| from astrbot.core.platform.sources.wecom_ai_bot.WXBizJsonMsgCrypt import Prpcrypt |
|
|
| |
| prpcrypt = Prpcrypt(b"test_key_32_bytes_long_value!") |
|
|
| |
| random_strings = [prpcrypt.get_random_str() for _ in range(10)] |
|
|
| |
| assert all(len(s) == 16 for s in random_strings) |
|
|
| |
| assert len(set(random_strings)) == 10 |
|
|
| |
| for s in random_strings: |
| decoded = s.decode() |
| assert decoded.isdigit() |
| assert 1000000000000000 <= int(decoded) <= 9999999999999999 |
|
|
|
|
| def test_wecomai_utils_uses_secrets(): |
| """Test that wecomai_utils uses secrets module for random string generation.""" |
| from astrbot.core.platform.sources.wecom_ai_bot.wecomai_utils import ( |
| generate_random_string, |
| ) |
|
|
| |
| random_strings = [generate_random_string(10) for _ in range(20)] |
|
|
| |
| assert all(len(s) == 10 for s in random_strings) |
|
|
| |
| for s in random_strings: |
| assert s.isalnum() |
|
|
| |
| assert len(set(random_strings)) >= 19 |
|
|
|
|
| def test_azure_tts_signature_uses_secrets(): |
| """Test that Azure TTS signature generation uses secrets module.""" |
| import asyncio |
|
|
| from astrbot.core.provider.sources.azure_tts_source import OTTSProvider |
|
|
| |
| config = { |
| "OTTS_SKEY": "test_secret_key", |
| "OTTS_URL": "https://example.com/api/tts", |
| "OTTS_AUTH_TIME": "https://example.com/api/time", |
| } |
|
|
| async def test_nonce_generation(): |
| async with OTTSProvider(config) as provider: |
| |
| provider.time_offset = 0 |
| provider.last_sync_time = 9999999999 |
|
|
| |
| signatures = [] |
| for _ in range(10): |
| sig = await provider._generate_signature() |
| signatures.append(sig) |
|
|
| |
| nonces = [sig.split("-")[1] for sig in signatures] |
|
|
| |
| assert all(len(n) == 10 for n in nonces) |
|
|
| |
| for n in nonces: |
| assert all(c in "abcdefghijklmnopqrstuvwxyz0123456789" for c in n) |
|
|
| |
| assert len(set(nonces)) == 10 |
|
|
| asyncio.run(test_nonce_generation()) |
|
|
|
|
| def test_ssl_context_fallback_explicit(): |
| """Test that SSL context fallback is properly configured.""" |
| |
| |
| |
|
|
| |
| ssl_context = ssl.create_default_context() |
| ssl_context.check_hostname = False |
| ssl_context.verify_mode = ssl.CERT_NONE |
|
|
| |
| assert ssl_context.check_hostname is False |
| assert ssl_context.verify_mode == ssl.CERT_NONE |
|
|
| |
| |
|
|
|
|
| def test_io_module_has_ssl_imports(): |
| """Verify that io.py properly imports ssl module.""" |
| from astrbot.core.utils import io |
|
|
| |
| assert hasattr(io, "ssl") |
|
|
| |
| assert hasattr(io.ssl, "CERT_NONE") |
|
|
|
|
| def test_secrets_module_randomness_quality(): |
| """Test that secrets module provides high-quality randomness.""" |
| import secrets |
|
|
| |
| random_numbers = [secrets.randbelow(100) for _ in range(1000)] |
|
|
| |
| unique_values = len(set(random_numbers)) |
|
|
| |
| |
| assert unique_values >= 60 |
|
|
| |
| chars = "abcdefghijklmnopqrstuvwxyz0123456789" |
| random_chars = [secrets.choice(chars) for _ in range(1000)] |
|
|
| |
| unique_chars = len(set(random_chars)) |
| assert unique_chars >= 20 |
|
|
|
|
| if __name__ == "__main__": |
| pytest.main([__file__, "-v"]) |
|
|