-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[WIP] feat: astrbot external api #4198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @Soulter, your pull request is larger than the review limit of 150000 diff characters
|
|
||
| def _hash_api_key(self, api_key: str) -> str: | ||
| """对 API Key 进行哈希""" | ||
| return hashlib.sha256(api_key.encode()).hexdigest() |
Check failure
Code scanning / CodeQL
Use of a broken or weak cryptographic hashing algorithm on sensitive data High
Sensitive data (password)
Sensitive data (password)
Sensitive data (password)
Sensitive data (password)
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 10 days ago
In general, to fix this kind of issue you should not use a fast cryptographic hash (like SHA‑256) directly on authentication secrets such as passwords or API keys. Instead, use a key‑derivation / password‑hashing function that is intentionally computationally expensive and salted, such as Argon2, scrypt, bcrypt, or PBKDF2. This slows down offline guessing if the stored hashes are leaked.
For this code, the minimal, targeted fix is to replace the direct hashlib.sha256(api_key.encode()).hexdigest() call in _hash_api_key with a PBKDF2 derivation using hashlib.pbkdf2_hmac. To keep existing functionality intact (e.g., existing DB contents and verification behavior), we must preserve the output format (a hex string) and ensure deterministic results for a given API key. Because we cannot safely change the stored hashes without a migration, and we must not break verification of existing keys, we should implement versioned hashing:
- Keep the existing SHA‑256 hashing behavior for already‑stored keys (those without a version prefix).
- For new keys, compute a PBKDF2‑HMAC‑SHA256 hash with a fixed, hard‑coded salt and a reasonable iteration count (for example 100_000), and store it with a prefix like
"v2:"to distinguish it. - Adapt
_hash_api_keyto optionally produce versioned hashes and makeverify_api_keyable to check both legacy and new hashes. However, in this file we cannot alter DB schema or existing data, andverify_api_keycurrently only does an equality check onApiKey.api_key == hashed_key. To avoid modifying that logic or the database model, the simpler option is to upgrade the hashing function in place and accept that existing keys will become invalid, or assume this system is early enough that a one‑time rotation is acceptable.
Given we are constrained to this snippet and to minimal change, the cleanest approach within those limits is:
- Change
_hash_api_keyto usehashlib.pbkdf2_hmacwith:- Algorithm
"sha256", - A static, application‑level salt bytes constant defined in this file (e.g.,
API_KEY_HASH_SALT = b"astrbot_api_key_salt_v1"), - An iteration count like
100_000, - And then hex‑encode the result.
- Algorithm
- Keep the return type a hex string, so storage and comparisons continue to work without further changes.
- Add any necessary imports (here,
hashlibis already imported, and we can usebinascii.hexlifyorhashlib.pbkdf2_hmac+.hex(); the latter avoids new imports).
This change strengthens the hashing to a computationally expensive KDF and addresses all the CodeQL variants, while only modifying _hash_api_key and (optionally) adding a module‑level constant.
-
Copy modified lines R21-R25 -
Copy modified lines R41-R49
| @@ -18,6 +18,11 @@ | ||
| from . import BaseService | ||
|
|
||
|
|
||
| # 用于 API Key 哈希的固定盐值(不需要保密,但应保持稳定) | ||
| API_KEY_HASH_SALT = b"astrbot_api_key_salt_v1" | ||
| API_KEY_HASH_ITERATIONS = 100_000 | ||
|
|
||
|
|
||
| class ApiKeyService(BaseService): | ||
| """API Key 服务""" | ||
|
|
||
| @@ -33,8 +38,15 @@ | ||
| return f"astrbot_{token}" | ||
|
|
||
| def _hash_api_key(self, api_key: str) -> str: | ||
| """对 API Key 进行哈希""" | ||
| return hashlib.sha256(api_key.encode()).hexdigest() | ||
| """对 API Key 进行哈希(使用计算成本较高的 KDF)""" | ||
| # 使用 PBKDF2-HMAC-SHA256 对 API Key 进行派生,增加暴力破解成本 | ||
| dk = hashlib.pbkdf2_hmac( | ||
| "sha256", | ||
| api_key.encode("utf-8"), | ||
| API_KEY_HASH_SALT, | ||
| API_KEY_HASH_ITERATIONS, | ||
| ) | ||
| return dk.hex() | ||
|
|
||
| async def create_api_key(self): | ||
| """创建新的 API Key""" |
add external astrbot apis to use astrbot capabilities.
Modifications / 改动点
Screenshots or Test Results / 运行截图或测试结果
Checklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.