T09 · Insecure Skill Coding Practices
- Location
handler.py:333- Finding
Unvalidated Handler Input Causes Invocation Failure
- Content
View full analysis
Vulnerability Details
File Location:
handler.py:333-334
Vulnerability Type: Improper input type validation
Risk Level: LowVulnerable Code
python contract_text = skill_input.get("contract_text", "") if not contract_text or not contract_text.strip():Technical Analysis
The public
handle()entry point assumes thatskill_inputis a dictionary and that itscontract_textmember is a string. It invokes.get()and.strip()before validating either type.Although the lower-level
scan()function checks whether its input is a string, execution does not reach that validation whencontract_textis a truthy non-string value. Similarly, passing a non-dictionary asskill_inputfails at the.get()call.No input schema or equivalent type enforcement is declared in
skill.json. Consequently, malformed or adversarial input can raise an uncaughtAttributeErrorand terminate the invocation.Attack Path
- An attacker or malformed integration invokes the Skill with a non-string value, such as
{"contract_text": 1}. handle()retrieves the integer throughskill_input.get().- Because the integer is truthy, evaluation proceeds to
contract_text.strip(). - The integer has no
.strip()method, causing an uncaughtAttributeError. - The current Skill invocation fails instead of returning a structured validation error.
A similar failure occurs if the top-level input is not a dictionary, because
.get()is called without first validatingskill_input.Impact Assessment
Exploitation can cause application-level denial of service for the affected invocation and may produce repeated failures if an upstream caller retries malformed requests. The flaw does not grant additional privileges and provides no demonstrated path to command execution, data disclosure, network access, persistence, or cross-session compromise. Its scope is limited to availability and error handli ...[truncated 83 chars]
- An attacker or malformed integration invokes the Skill with a non-string value, such as
- Remediation
View remediation
Remediation Suggestions
Validate both the top-level input and the contract text before invoking type-specific methods:
python def handle(skill_input: dict) -> dict: if not isinstance(skill_input, dict): return { "ok": False, "error": "Invalid input: an object is required." } contract_text = skill_input.get("contract_text", "") if not isinstance(contract_text, str): return { "ok": False, "error": "Invalid contract text: a string is required." } if not contract_text.strip(): return { "ok": False, "error": "No contract text was provided." } results = scan(contract_text) output = format_results(results) # Continue constructing the successful response.Also apply a documented maximum input length to limit excessive CPU and memory consumption, declare an input schema if supported by the Skill platform, and add tests for non-dictionary input,
None, integers, lists, nested objects, and oversized strings.
