T09 · Insecure Skill Coding Practices
- Location
scripts/check_license.py:13- Finding
Hardcoded License Credential Allows Authorization Bypass
- Content
View full analysis
Vulnerability Details
File Location:
scripts/check_license.py, lines 13-37
Vulnerability Type: Hardcoded credential and ineffective client-side license validation
Risk Level: Highpython # Public key/salt; replace with your own value in an actual deployment SALT = "PaidSkillDemoClawHub2024" def hash_license(license_key: str, salt: str = SALT) -> str: """Calculate the license key hash.""" return hashlib.sha256((license_key + salt).encode()).hexdigest() def check_license() -> Tuple[bool, str]: """ Check the license key. Returns: (whether valid, message) """ license_key = os.environ.get("SKILL_LICENSE_KEY", "").strip() if not license_key: return False, "License key is not configured; set the SKILL_LICENSE_KEY environment variable." # Authorized hashes are stored here; an actual implementation could validate dynamically with a server. # Example: the hash of license "demo-license-123" is: expected_hash = hash_license("demo-license-123") # Check the license supplied by the user. user_hash = hash_license(license_key) if user_hash == expected_hash: return True, "License validation succeeded."Technical Analysis
The accepted plaintext license key,
demo-license-123, is embedded directly in source code distributed to users. The salt and complete validation algorithm are also public. Hashing the key does not protect it because the application must compare the user-supplied value against data available locally, and in this implementation the valid plaintext value is explicitly disclosed.Validation is entirely client-side and does not use a digital signature, trusted remote entitlement service, expiration claim, revocation mechanism, or binding to a customer, account, or device. Anyone with access to the Skill package can therefore recover the accepted credential without cryptanalysis ...[truncated 1515 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove all accepted plaintext license keys, shared secrets, and reusable entitlement values from distributed source code.
- For offline validation, issue digitally signed license documents containing relevant claims such as customer identity, product identifier, enabled features, issuance time, expiration time, and a unique license identifier.
- Embed only the verification public key in the Skill. Keep the signing private key exclusively in a secured licensing service and never distribute it with the package.
- Use a modern, established signature scheme and library, such as Ed25519, rather than implementing custom cryptography.
- If online validation is appropriate, submit the license through an authenticated HTTPS licensing API. Apply strict TLS verification, request timeouts, safe error handling, rate limiting, replay protection, and a documented fail-closed policy.
- Add revocation and renewal support. If validation responses are cached, digitally sign them and enforce a short expiration period.
- Bind entitlements to the intended account or installation where required by the commercial model, while minimizing collection of device identifiers and other personal data.
- Compare security-sensitive values using constant-time comparison where direct comparisons remain necessary, although constant-time comparison alone does not correct the disclosed credential.
- Clearly mark demonstration credentials and validation code as non-production, and prevent the template from being published as a real paid Skill without replacing the demonstration mechanism.
- Add automated tests confirming that unknown, expired, revoked, altered, and incorrectly scoped licenses are rejected.
