T09 · Insecure Skill Coding Practices
- Location
scripts/query.sh:25- Finding
Unrestricted JSON Filter Merging Allows Request Constraint Bypass
- Content
View full analysis
Vulnerability Details
File Location:
scripts/query.sh, lines 25–29
Vulnerability Type: Unvalidated request-field override
Risk Level: Lowpython if len(sys.argv) > 8 and sys.argv[8]: extra = json.loads(sys.argv[8]) if not isinstance(extra, dict): raise SystemExit("filtersJson must be a JSON object") body.update(extra)Technical Analysis
The script constructs core request fields from positional arguments, including
level1CategoryId,pageNo,pageSize,period,sortField, andsortDirection. It then parses caller-providedfiltersJsonand merges it into the request withbody.update(extra).Although the code verifies that the supplied JSON is an object, it does not restrict its keys or validate their values. Python's
dict.update()replaces existing values when duplicate keys are present. Consequently, the additional filter object can override core request fields after their initial conversion and can introduce fields not documented by the skill.For example, the following filter object overrides fields that are supposed to be controlled by dedicated positional parameters:
json { "pageSize": 100000, "level1CategoryId": 999999999, "period": "UNSUPPORTED_VALUE", "unexpectedField": "value" }This undermines the documented restriction that
pageSizemust not exceed 15 and bypasses the script's intended request structure. The remote API may independently reject invalid values, but the local script does not enforce the stated policy.This behavior does not provide local command execution: the JSON is passed to Python as a quoted argument, parsed with
json.loads(), serialized withjson.dumps(), and passed tocurlas quoted data.Attack Path
- An attacker or untrusted caller gains the ability to invoke
scripts/query.shor influence its eighth argument. - The caller supplies apparently valid positional parameters.
...[truncated 1212 chars]
- An attacker or untrusted caller gains the ability to invoke
- Remediation
View remediation
Remediation Suggestions
-
Define an explicit allowlist containing only supported optional filter fields:
python allowed_filters = { "minSales", "maxSales", "minGmv", "maxGmv", "minPrice", "maxPrice", "minCreateDate", "maxCreateDate", "deliveryModes", "crossBorderSalePermission", "productType", "salesLevel", } -
Reject unknown keys and attempts to override core request fields:
python unknown = set(extra) - allowed_filters if unknown: raise SystemExit( "Unsupported or protected filter fields: " + ", ".join(sorted(unknown)) ) body.update(extra) -
Validate all fields after constructing the final request:
- Require
pageNoto be between 1 and 10000. - Require
pageSizeto be between 1 and 15. - Restrict
period,sortField, andsortDirectionto documented enumerations. - Validate numeric ranges and ensure minimum values do not exceed maximum values.
- Restrict
deliveryModesto documented values. - Validate date and accounting-period formats.
- Reject unexpected JSON value types.
- Require
-
Keep protected fields such as
level1CategoryId, pagination, period, and sorting exclusively controlled by their dedicated positional parameters. -
Retain server-side validation because client-side validation alone cannot prevent callers from making direct API requests.
-
