mnb/mnb-secure-core
Composer 安装命令:
composer require mnb/mnb-secure-core
包简介
mnb-secure-core v1.0 reusable no-framework PHP security core for custom applications.
关键字:
README 文档
README
Package / library name: mnb-secure-core
Composer package: mnb/mnb-secure-core
Version: 1.0
Author: Nagendra babu Macharla
Type: reusable no-framework PHP security library
mnb-secure-core is a reusable PHP security core for custom applications that do not use a framework. It gives a project-ready security foundation for school ERP, CRM, billing, admin panels, APIs, file tools, reporting dashboards, and other PHP applications.
This single README is the complete setup and reference document for the package. The earlier multi-file documentation has been merged here so the ZIP stays clean and easy to read.
1. Security concepts covered
- Trust Zones and Data Boundaries
- Secure Request Receiving Strategy
- Authentication Strategy
- Authorization Strategy
- Data Protection Strategy
- Web Application Security Controls
- API Security and Rate Limiting
- File Upload, Download, and Document Security
- Caching Strategy
- Environment and Secret Management
- Logging, Audit, and Monitoring
- Backup, Recovery, and Incident Response
- Vulnerability Blocking Matrix
- Secure Database Connect, Retrieval, Update, Delete, Search, and Alter
- Penetration Testing, Security Verification, and Remediation
- Error Handling, Safe Error Responses, and Hidden Technical Logs
- Memory Management and Resource Safety
- Throughput and Performance Capacity Management
- Hide Server IP and Origin Identity Protection
2. Requirements
- PHP 8.1 or higher
opensslPHP extensionfileinfoPHP extensionzipPHP extension recommended for ZIP backups- Writable private storage directory outside public web access
- HTTPS in production
- Composer optional; the package also includes a simple standalone autoloader
Check PHP locally:
php -v php -m | grep -E "openssl|fileinfo|zip"
3. Recommended folder placement
my-php-app/
├── public/
│ └── index.php
├── app/
├── config/
│ └── security.php
├── storage/
│ ├── private/
│ ├── quarantine/
│ ├── cache/
│ ├── logs/
│ ├── audit/
│ └── backups/
└── libraries/
└── mnb-secure-core/
Copy this package into:
my-php-app/libraries/mnb-secure-core
Then include the library autoloader in your application bootstrap:
require __DIR__ . '/../libraries/mnb-secure-core/autoload.php';
Composer users can load it through Composer after placing it in their project as a path repository or private package:
{
"repositories": [
{
"type": "path",
"url": "libraries/mnb-secure-core"
}
],
"require": {
"mnb/mnb-secure-core": "1.0.0"
}
}
4. Copy config and environment file
Copy:
mnb-secure-core/config/security.php -> my-php-app/config/security.php
mnb-secure-core/.env.example -> my-php-app/.env
Example .env:
APP_ENV=local APP_DEBUG=true APP_URL=http://localhost APP_KEY=CHANGE_ME_WITH_bin_mnb-secure_key_generate FORCE_HTTPS=false TRUSTED_HOSTS=localhost,127.0.0.1 # Origin/server identity protection # PHP can help block direct IP Host requests and remove app-level fingerprint headers. # For real origin IP hiding, put the site behind a CDN/reverse proxy and firewall the origin. ORIGIN_PROTECTION_ENABLED=true BLOCK_DIRECT_IP_HOST=true CDN_OR_PROXY_ENABLED=false REQUIRE_CDN_OR_PROXY_IN_PRODUCTION=true SESSION_SECURE=false SESSION_HTTP_ONLY=true SESSION_SAME_SITE=Lax STORAGE_PRIVATE_PATH=../storage/private STORAGE_QUARANTINE_PATH=../storage/quarantine CACHE_PATH=../storage/cache LOG_PATH=../storage/logs AUDIT_PATH=../storage/audit BACKUP_PATH=../storage/backups
Generate a secure app key:
php libraries/mnb-secure-core/bin/mnb-secure key:generate
Create protected storage folders:
mkdir -p storage/private storage/quarantine storage/cache storage/logs storage/audit storage/backups
Keep storage/private, storage/audit, and storage/backups outside public/.
5. Basic bootstrap pattern
<?php require __DIR__ . '/../libraries/mnb-secure-core/autoload.php'; use Mnb\SecurityCore\Env\EnvLoader; use Mnb\SecurityCore\Core\SecurityKernel; EnvLoader::load(__DIR__ . '/../.env'); $config = require __DIR__ . '/../config/security.php'; $security = new SecurityKernel($config);
6. Web request protection pattern
use Mnb\SecurityCore\Http\MiddlewarePipeline; use Mnb\SecurityCore\Http\Middleware\TrustedHostMiddleware; use Mnb\SecurityCore\Http\Middleware\HttpsMiddleware; use Mnb\SecurityCore\Http\Middleware\RequestSizeMiddleware; use Mnb\SecurityCore\Http\Middleware\SecurityHeadersMiddleware; use Mnb\SecurityCore\Http\Request; use Mnb\SecurityCore\Http\Response; $request = Request::fromGlobals(); $pipeline = new MiddlewarePipeline([ new TrustedHostMiddleware($config['app']['trusted_hosts'] ?? []), new HttpsMiddleware((bool)($config['app']['force_https'] ?? false)), new RequestSizeMiddleware((int)($config['limits']['request_max_bytes'] ?? 2097152)), new SecurityHeadersMiddleware($config['security_headers'] ?? []), ]); $response = $pipeline->handle($request, function (Request $request): Response { return Response::text('Secure page'); }); $response->send();
7. API token and rate-limit pattern
use Mnb\SecurityCore\Auth\OpaqueTokenService; use Mnb\SecurityCore\Core\SecurityKernel; use Mnb\SecurityCore\Http\Request; $security = new SecurityKernel($config); $tokens = new OpaqueTokenService($security->tokenStore()); $issued = $tokens->issue('user-1001', ['api:read'], ttlSeconds: 3600); $request = Request::fromGlobals(); $plainToken = $request->bearerToken(); $record = $plainToken ? $tokens->validate($plainToken, $request->ip(), (string)$request->header('user-agent', '')) : null; if (!$record || !in_array('api:read', $record['scopes'] ?? [], true)) { http_response_code(401); exit('Unauthorized'); } $limiter = $security->rateLimiter(); $result = $limiter->attempt('api:' . $request->ip(), 120, 60); if (!$result->allowed) { http_response_code(429); header('Retry-After: ' . $result->retryAfter); exit('Too many requests'); }
8. CSRF pattern
use Mnb\SecurityCore\Auth\Csrf; $csrf = new Csrf('_csrf_token'); $token = $csrf->token(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $postedToken = $_POST['_csrf'] ?? ''; if (!$csrf->verify($postedToken)) { http_response_code(419); exit('Invalid CSRF token'); } }
Use CSRF protection for browser form submissions. Use bearer tokens or signed API credentials for API clients instead of CSRF tokens.
9. Authorization and ownership pattern
use Mnb\SecurityCore\Authz\TenantContext; use Mnb\SecurityCore\Authz\PermissionGuard; use Mnb\SecurityCore\Authz\PolicyRegistry; $context = new TenantContext( tenantId: 'school-1', userId: 'user-1001', roles: ['admin'], permissions: ['student.view', 'student.update'] ); $permissions = new PermissionGuard(); $permissions->require($context, 'student.update');
Recommended rules:
- Authorize before reading, creating, updating, deleting, exporting, or altering data.
- Always validate tenant, owner, school, branch, or organization boundaries.
- Deny by default when a permission or ownership rule is missing.
- Audit denied high-risk operations.
10. Data protection pattern
use Mnb\SecurityCore\Data\Encryption; use Mnb\SecurityCore\Data\DataMasker; $crypto = new Encryption($_ENV['APP_KEY']); $cipherText = $crypto->encrypt('Sensitive value'); $plainText = $crypto->decrypt($cipherText); $maskedEmail = (new DataMasker())->email('student@example.com');
Protect secrets and sensitive data using encryption, masking, and field-level filtering. Never log raw passwords, tokens, session IDs, API keys, cookies, private file paths, or full database error traces.
11. Secure database pattern
The database security layer is built around these controls:
- PDO with safe connection options
- Identifier allow-lists for table and column names
- Parameterized values for user data
- Tenant and permission checks before CRUD
- Guarded search builder
- Guarded schema changes
- Audit logs for sensitive operations
Example:
use Mnb\SecurityCore\Database\DatabaseConfig; use Mnb\SecurityCore\Database\PdoConnectionFactory; use Mnb\SecurityCore\Database\SecureDatabase; use Mnb\SecurityCore\Database\TableSecurityPolicy; $dbConfig = DatabaseConfig::fromArray([ 'driver' => 'mysql', 'host' => '127.0.0.1', 'database' => 'app_db', 'username' => 'app_user', 'password' => 'secret', ]); $connection = (new PdoConnectionFactory())->create($dbConfig); $policy = new TableSecurityPolicy( table: 'students', resourceType: 'student', selectableColumns: ['id', 'school_id', 'name', 'class_id', 'status'], insertableColumns: ['name', 'class_id', 'status'], updatableColumns: ['name', 'class_id', 'status'], searchableColumns: ['name'], orderableColumns: ['id', 'name'] ); // Pair SecureDatabase with a PolicyRegistry and AuditLogger as shown in examples/secure-database.php. $rows = $connection->fetchAll('SELECT id, name FROM students WHERE school_id = ? LIMIT 50', [$context->schoolId]);
Database operation rules:
| Operation | Security rule |
|---|---|
| Connect | Use least-privilege DB user and safe PDO options |
| Retrieve | Enforce allowed columns, tenant scope, permission checks |
| Create | Validate fields and deny unknown columns |
| Update | Require object-level authorization and allowed fields |
| Delete | Prefer soft delete; hard delete requires separate permission |
| Search | Allow-list searchable columns and cap limits |
| Alter | Use schema guard with explicit permission and allow-list |
12. Redis and database-backed storage options
File-based cache, rate limits, and token storage are simple and good for one server. For high traffic or multiple web servers, use Redis or a database-backed store.
use Mnb\SecurityCore\Core\SecurityKernel; $security = new SecurityKernel($config); $cache = $security->cache(); // file, redis, or database based on config/security.php $limiter = $security->rateLimiter(); $tokenStore = $security->tokenStore();
Relevant config keys:
$config['cache']['driver']; // file, redis, database $config['rate_limiter']['driver']; // file, redis, database $config['token_store']['driver']; // file, redis, database $config['redis']; // host, port, password, database, timeout
Database-backed stores create their lightweight tables automatically when first used. Redis stores need the PHP ext-redis extension and a reachable Redis server.
13. File upload, download, and private document pattern
use Mnb\SecurityCore\Files\FileUploadPolicy; use Mnb\SecurityCore\Files\SecureFileManager; use Mnb\SecurityCore\Files\LocalPrivateStorage; use Mnb\SecurityCore\Files\CompositeMalwareScanner; use Mnb\SecurityCore\Files\HeuristicMalwareScanner; use Mnb\SecurityCore\Files\ClamAvMalwareScanner; $policy = new FileUploadPolicy( allowedExtensions: ['pdf', 'png', 'jpg', 'jpeg'], allowedMimePrefixes: ['application/pdf', 'image/png', 'image/jpeg'], maxBytes: 5 * 1024 * 1024, ); $scanner = new CompositeMalwareScanner([ new HeuristicMalwareScanner(), new ClamAvMalwareScanner(failClosedWhenUnavailable: false), ]); $manager = new SecureFileManager( new LocalPrivateStorage(__DIR__ . '/../storage/private'), $policy, __DIR__ . '/../storage/quarantine', $scanner ); $result = $manager->storeFromPath( $_FILES['document']['tmp_name'], $_FILES['document']['name'], 'documents' );
File security checklist:
- Validate extension and MIME type.
- Rename uploaded files to safe random names.
- Store private files outside
public/. - Scan files before use where malware scanning is available.
- Never execute uploaded files.
- Download private files through an authorization controller.
- Add
Content-Disposition: attachmentfor risky file types.
14. Security headers
Recommended production headers:
Content-Security-PolicyX-Frame-Optionsor CSPframe-ancestorsX-Content-Type-Options: nosniffReferrer-PolicyPermissions-PolicyStrict-Transport-Securitywhen HTTPS is stable
Use SecurityHeaders or SecurityHeadersMiddleware to attach headers at the response boundary.
15. Hide server IP and origin identity protection
A PHP library cannot fully hide a public server IP by itself. If DNS points directly to the server, attackers may still find the origin. Real origin IP protection needs deployment controls:
- Put the site behind a CDN, reverse proxy, or load balancer.
- Proxy the DNS record where your DNS provider supports it.
- Firewall the origin server so only trusted CDN/proxy IP ranges can reach HTTP/HTTPS ports.
- Remove or minimize
Server,X-Powered-By, framework, generator, and version headers. - Block requests where the
Hostheader is a direct IP address. - Keep
APP_DEBUG=falseand use safe public error responses in production.
mnb-secure-core now includes ServerIdentityHider and ServerIdentityProtectionMiddleware to help with the application-level part: block direct IP Host requests and strip fingerprint headers from application responses.
use Mnb\SecurityCore\Http\Middleware\ServerIdentityProtectionMiddleware; use Mnb\SecurityCore\Http\MiddlewarePipeline; $pipeline = new MiddlewarePipeline([ new ServerIdentityProtectionMiddleware($config['origin_protection'] ?? []), // other middleware... ]);
Recommended production config:
'origin_protection' => [ 'enabled' => true, 'block_direct_ip_host' => true, 'cdn_or_proxy_enabled' => true, 'require_cdn_or_proxy_in_production' => true, 'strip_headers' => ['Server', 'X-Powered-By', 'X-Generator', 'X-Runtime', 'X-Version'], ],
Important server-level settings:
# Apache ServerTokens Prod ServerSignature Off Header unset X-Powered-By
# Nginx server_tokens off; proxy_hide_header X-Powered-By;
; php.ini expose_php = Off display_errors = Off
Use the production checker to warn when direct IP host access is allowed or origin protection is disabled.
15. Cache strategy
The cache layer is intended for safe, bounded, non-sensitive data.
Rules:
- Do not cache passwords, raw tokens, OTPs, private documents, or full PII records.
- Prefix cache keys by app/module/tenant where needed.
- Use TTLs for all temporary cache entries.
- Use cache for rate-limit counters, low-risk lookups, and computed summaries.
- Clear affected cache after updates or deletes.
16. Environment and secret management
Use .env only for local configuration and server-specific secrets. Never commit real secrets.
Recommended secret rules:
- Rotate application keys when exposure is suspected.
- Use different keys per environment.
- Keep production
.envoutside public web roots. - Do not print environment values in error pages.
- Use
SecretScannerbefore packaging or deployment.
17. Logging, audit, and monitoring
Use two different logging styles:
- Safe application logs for operational debugging.
- Tamper-evident audit logs for security-sensitive actions.
Audit these events:
- Login success/failure
- Password changes
- Permission denied events
- Sensitive record view/update/delete
- File upload/download
- Export actions
- API token creation/revocation
- Schema migration or guarded ALTER operations
- Backup creation/restoration
Never log raw passwords, tokens, cookies, API keys, encryption keys, or private document contents.
18. Error handling strategy
The error handling layer separates public messages from internal diagnostic details.
Public response rules:
- Show clean messages to users.
- Do not expose file paths, stack traces, SQL, route names,
.envvalues, token values, or server internals. - Use consistent status codes.
- Log technical details server-side only.
Example:
use Mnb\SecurityCore\Errors\SafeErrorHandler; use Mnb\SecurityCore\Errors\ErrorResponseFactory; use Mnb\SecurityCore\Logging\FileLogger; $logger = new FileLogger(__DIR__ . '/../storage/logs/app.log'); $factory = new ErrorResponseFactory(debug: false); $handler = new SafeErrorHandler($factory, $logger); $handler->register();
Recommended public statuses:
| Exception type | Public HTTP status |
|---|---|
| ValidationException | 422 |
| AuthorizationException | 403 |
| NotFoundException | 404 |
| BusinessRuleException | 409 |
| SecurityException | 400 or 403 |
| Unknown Throwable | 500 |
19. Backup, recovery, and incident response
Backup rules:
- Store backups outside
public/. - Encrypt backups when possible.
- Keep retention limits.
- Test restoration, not only backup creation.
- Audit backup create/download/delete actions.
Incident response basics:
- Detect suspicious activity.
- Preserve logs and evidence.
- Contain exposed accounts, tokens, or files.
- Patch the root cause.
- Rotate secrets.
- Restore clean data if needed.
- Retest and document remediation.
20. Memory management and resource safety
Use memory guards for large files, exports, imports, conversions, and batch operations.
Rules:
- Cap upload size and request size.
- Process large rows/files in chunks.
- Avoid loading entire large files into memory when streaming is possible.
- Track memory before and after heavy operations.
- Reject unsafe workloads before processing.
Risk examples:
| Risk | Control |
|---|---|
| Large CSV import | Chunk processor and row limits |
| Large PDF/document conversion | Upload size cap and worker process |
| Large export | Streamed output and query pagination |
| Repeated API bursts | Rate limiter and throughput monitor |
21. Throughput and performance capacity management
Throughput controls help prevent accidental overload and abuse.
Use them to plan:
- Expected requests per second
- Average response time
- Concurrent users
- Worker capacity
- Queue pressure
- Upload and conversion limits
- API burst limits
Example CLI commands:
php bin/mnb-secure throughput:check php bin/mnb-secure throughput:plan 80 150 25 500 900
22. Vulnerability blocking matrix
| Vulnerability | Main controls |
|---|---|
| SQL injection | Parameterized queries, identifier allow-lists, SecureQueryBuilder |
| XSS | Input validation, output escaping, CSP, safe response builders |
| CSRF | CSRF tokens on browser form requests |
| Broken access control / IDOR | PermissionGuard, TenantGuard, PolicyRegistry, ownership checks |
| API abuse | Bearer tokens, scopes, rate limiter, audit logs |
| File upload execution | MIME/extension validation, random names, private storage, no execute permissions |
| Path traversal | Storage abstraction and normalized safe paths |
| Secret leakage | Env separation, SecretScanner, safe error logger |
| Sensitive log leakage | Log redaction and public/internal error separation |
| Cache poisoning | Key namespacing, TTLs, no sensitive cache entries |
| Backup exposure | Private backup storage, audit logs, retention controls |
| Memory exhaustion | Request limits, upload limits, MemoryGuard, chunk processing |
| Throughput overload | Rate limits, throughput monitor, capacity planner |
| Unauthorized schema alter | Migration/schema guard with explicit allow-list and permission |
| Origin IP / server fingerprint exposure | ServerIdentityProtectionMiddleware, trusted hosts, CDN/proxy/firewall checklist |
23. Concept to file map
| Concept | Main files/classes |
|---|---|
| Trust Zones and Data Boundaries | src/Trust/*, src/Data/DataClassifier.php |
| Secure Request Receiving | src/Http/Request.php, src/Http/Middleware/* |
| Authentication | src/Auth/* |
| Authorization | src/Authz/*, src/Authz/Policies/* |
| Data Protection | src/Data/*, src/Env/SecretScanner.php |
| Web Security Controls | src/Security/WebSecurityControls.php, src/Http/Middleware/SecurityHeadersMiddleware.php |
| API Security and Rate Limiting | src/Api/*, src/RateLimit/* |
| Upload/Download Security | src/Files/* |
| Caching | src/Cache/*, src/Contracts/CacheInterface.php |
| Environment and Secrets | src/Env/*, .env.example, config/security.php |
| Logging and Audit | src/Logging/* |
| Backup and Recovery | src/Recovery/* |
| Vulnerability Matrix | src/Security/VulnerabilityMatrix.php |
| Secure Database | src/Database/* |
| Penetration Testing | src/Pentest/* |
| Safe Error Handling | src/Errors/*, src/Exceptions/* |
| Memory Management | src/Memory/* |
| Throughput Management | src/Throughput/* |
| Hide Server IP / Origin Identity | src/Security/ServerIdentityHider.php, src/Http/Middleware/ServerIdentityProtectionMiddleware.php |
24. Demos
Run all CLI demos:
php demos/run-all-demos.php
Run the browser demo:
php -S 127.0.0.1:8090 -t demos/web/public
Open:
http://127.0.0.1:8090
Demo map:
| Concept | Demo file |
|---|---|
| Trust Zones and Data Boundaries | demos/01-trust-zones-data-boundaries.php |
| Secure Request Receiving | demos/02-secure-request-receiving.php |
| Authentication | demos/03-authentication.php |
| Authorization | demos/04-authorization.php |
| Data Protection | demos/05-data-protection.php |
| Web Security Controls | demos/06-web-application-security-controls.php |
| API Security and Rate Limiting | demos/07-api-security-rate-limiting.php |
| File Upload/Download Security | demos/08-file-upload-download-document-security.php |
| Caching Strategy | demos/09-caching-strategy.php |
| Environment and Secrets | demos/10-environment-secret-management.php |
| Logging and Audit | demos/11-logging-audit-monitoring.php |
| Backup and Incident Response | demos/12-backup-recovery-incident-response.php |
| Vulnerability Matrix | demos/13-vulnerability-blocking-matrix.php |
| Secure Database | demos/14-secure-database-connect-retrieval-update-delete-search-alter.php |
| Pentest and Verification | demos/15-penetration-testing-security-verification.php |
| Error Handling | demos/16-error-handling-custom-errors-logs-hidden-frontend.php |
| Memory Management | demos/17-memory-management-resource-safety.php |
| Throughput Management | demos/18-throughput-performance-capacity-management.php |
| Hide Server IP / Origin Identity | demos/19-hide-server-ip-origin-protection.php |
25. CLI commands
From package root:
php tests/run-tests.php php demos/run-all-demos.php php bin/mnb-secure key:generate php bin/mnb-secure matrix:export php bin/mnb-secure throughput:check php bin/mnb-secure throughput:plan 80 150 25 500 900
26. Testing checklist
Before using this library in production, verify:
- Authentication accepts valid users and rejects invalid credentials.
- Session cookies are secure, HTTP-only, and SameSite protected.
- CSRF-protected forms reject missing or invalid tokens.
- Authorization blocks missing permissions.
- Tenant/ownership boundaries block cross-tenant access.
- SQL injection payloads do not alter query structure.
- XSS payloads are escaped or rejected.
- API endpoints require valid tokens and scopes.
- Rate limits return 429 when thresholds are exceeded.
- Uploads reject unsafe extensions and MIME types.
- Private downloads require authorization.
- Cache does not store sensitive data.
- Logs redact secrets.
- Public errors do not show stack traces, paths, SQL, or
.envvalues. - Backups are private and restoration is tested.
- Memory and throughput guards block unsafe large workloads.
- Production security checks pass before deployment.
27. Penetration testing workflow
Only test systems you own or are authorized to test.
Recommended workflow:
- Define target scope.
- List modules, roles, and sensitive objects.
- Run authentication, authorization, CSRF, XSS, SQLi, upload, API, and rate-limit tests.
- Record findings with severity and reproduction steps.
- Patch the issue.
- Retest the exact payload/request.
- Mark finding as remediated only after proof.
Suggested finding format:
Title:
Severity:
Affected module:
Affected role/user:
Steps to reproduce:
Expected result:
Actual result:
Technical impact:
Business impact:
Recommended fix:
Retest result:
28. Production checklist
Before deployment:
APP_ENV=productionAPP_DEBUG=false- HTTPS enabled
- HSTS enabled only after HTTPS is stable
- Trusted hosts configured
- Direct IP Host requests blocked
- CDN/reverse proxy enabled when you want to hide the origin server IP
- Origin firewall allows only trusted proxy/CDN IP ranges
- Real
APP_KEYgenerated and protected - Production
.envnot committed - Private storage outside public root
- Logs outside public root
- Backups outside public root
- Upload execution disabled
- Database user has least privilege
- Error pages hide technical details
- Security headers enabled
- Rate limits enabled
- Audit logging enabled
- Backup and restore tested
- Penetration testing completed and remediated
29. Starter integration template
Use templates/no-framework-app/ as a copy/paste reference for integrating the security core into a custom PHP app.
Typical flow:
- Copy the template into a new app.
- Point the template autoloader to
libraries/mnb-secure-core/autoload.php. - Copy
config/security.php. - Create
.envfrom.env.example. - Create storage folders.
- Run tests and demos.
- Add application-specific policies and controllers.
30. Package structure
mnb-secure-core/
├── autoload.php
├── bin/mnb-secure
├── composer.json
├── config/security.php
├── demos/
├── examples/
├── src/
├── storage/
├── templates/no-framework-app/
├── tests/run-tests.php
└── README.md
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: proprietary
- 更新时间: 2026-06-12