Summary
SkillSpector has no dedicated detection for insecure deserialization, an RCE-class weakness (CWE-502; OWASP Agentic-Skills ASI05 – Unexpected Code Execution). A skill that deserializes untrusted input is not flagged for that class of vulnerability today, in any language.
Repro (current behavior)
A skill whose only payload is PHP object injection:
<?php $o = unserialize($_GET["p"]); ?>
scans as SAFE / risk 0 — the deserialization sink is invisible.
A Python skill that unpickles a network response:
def f(u):
return pickle.loads(requests.get(u).content)
scans as SAFE / risk 7 (only an unrelated least-privilege note), despite being a textbook RCE gadget.
Proposed detection
Layered, matching the existing analyzer families:
- Python (deep).
behavioral_ast AST10 — flag pickle/marshal/dill/jsonpickle/joblib/pandas.read_pickle, plus argument-aware yaml.load / torch.load / numpy.load so the hardened forms (SafeLoader, weights_only=True, default allow_pickle=False) are not false-positived. behavioral_taint_tracking TT6 — external/file input → deserialization sink (HIGH), the analogue of TT5.
- Breadth (regex, language-gated).
static_patterns_deserialization DS1–DS4 for the non-Python scripts a skill may bundle — PHP unserialize (DS1), Ruby Marshal/restore (DS2), Ruby YAML/Psych/Oj (DS3), JS node-serialize/serialize-to-js/funcster (DS4).
Scope is limited to the languages SkillSpector already supports (Python, JS/TS, Ruby, PHP). Java/.NET are intentionally out of scope.
After
The PHP fixture → DS1 flagged; the Python fixture → AST10 + TT6 (CAUTION); a skill bundling all four languages → DO_NOT_INSTALL / 90.
I have a branch implementing this and will open a PR referencing this issue.
Summary
SkillSpector has no dedicated detection for insecure deserialization, an RCE-class weakness (CWE-502; OWASP Agentic-Skills ASI05 – Unexpected Code Execution). A skill that deserializes untrusted input is not flagged for that class of vulnerability today, in any language.
Repro (current behavior)
A skill whose only payload is PHP object injection:
scans as SAFE / risk 0 — the deserialization sink is invisible.
A Python skill that unpickles a network response:
scans as SAFE / risk 7 (only an unrelated least-privilege note), despite being a textbook RCE gadget.
Proposed detection
Layered, matching the existing analyzer families:
behavioral_astAST10 — flagpickle/marshal/dill/jsonpickle/joblib/pandas.read_pickle, plus argument-awareyaml.load/torch.load/numpy.loadso the hardened forms (SafeLoader,weights_only=True, defaultallow_pickle=False) are not false-positived.behavioral_taint_trackingTT6 — external/file input → deserialization sink (HIGH), the analogue of TT5.static_patterns_deserializationDS1–DS4 for the non-Python scripts a skill may bundle — PHPunserialize(DS1), RubyMarshal/restore(DS2), RubyYAML/Psych/Oj(DS3), JSnode-serialize/serialize-to-js/funcster(DS4).Scope is limited to the languages SkillSpector already supports (Python, JS/TS, Ruby, PHP). Java/.NET are intentionally out of scope.
After
The PHP fixture → DS1 flagged; the Python fixture → AST10 + TT6 (CAUTION); a skill bundling all four languages → DO_NOT_INSTALL / 90.
I have a branch implementing this and will open a PR referencing this issue.