[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GZYX808TJPR527TYC16J99":3,"skill-same:01M6GZYX808TJPR527TYC16J99":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":35,"linkOnly":36,"markdownContent":37,"markdownBody":38,"frontMatter":39,"refName":40,"commitSha":41,"skillDirectory":42,"forksCount":43,"repositoryHtmlUrl":44,"repositoryHomepageUrl":6,"ownerHtmlUrl":45,"ownerBlogUrl":46,"ownerDescription":47,"updatedAt":48,"install":49,"resources":62},"01M6GZYX808TJPR527TYC16J99","review-deserialization-sinks",null,"Use when untrusted bytes reach a native deserializer such as pickle, Java ObjectInputStream, PHP unserialize, or .NET BinaryFormatter. Finds the sinks, rates exploitability, and replaces them with data-only formats.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-review-deserialization-sinks\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-review-deserialization-sinks\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"review","deserialization","review deserialization sinks","java","data","php","use","only","exploitability","as","native","with","formats","pickle","when","2026-11-10 10:12:30",false,"---\nname: review-deserialization-sinks\ndescription: Use when untrusted bytes reach a native deserializer such as pickle, Java ObjectInputStream, PHP unserialize, or .NET BinaryFormatter. Finds the sinks, rates exploitability, and replaces them with data-only formats.\n---\n\n# Review deserialization sinks\n\nDeserializers that can instantiate arbitrary classes turn attacker bytes into attacker code, via\ngadget chains that need no bug in your own code. The durable fix is to stop feeding untrusted input\nto a class-constructing format.\n\n## Procedure\n\n1. Enumerate dangerous sinks per language:\n\n       rg -n \"pickle\\.loads?|cPickle|dill\\.loads|yaml\\.load\\(|marshal\\.loads\" .          # Python\n       rg -n \"ObjectInputStream|readObject\\(|XStream|SnakeYAML|readValue\\(\" .            # Java\n       rg -n \"unserialize\\(|session_decode|igbinary_unserialize\" .                        # PHP\n       rg -n \"BinaryFormatter|NetDataContractSerializer|LosFormatter|TypeNameHandling\" . # .NET\n       rg -n \"node-serialize|serialize-javascript|unserialize\\(\" .                        # Node\n\n2. Classify each hit by reachability: is the byte stream from a request body, a cookie, a cache, a\n   queue message, or a file written by an untrusted party? A sink with no untrusted source is not\n   exploitable — say so explicitly rather than flagging it.\n\n3. Python YAML: `yaml.load(x)` without a `Loader` is remote code execution;\n   `yaml.safe_load(x)` is the fix when the document is pure data.\n\n4. Java: `ObjectInputStream.readObject` on untrusted bytes is exploitable via gadget chains in the\n   classpath (commons-collections, Spring). Prefer JSON with an explicit target class; if native\n   serialization is unavoidable, use a `ObjectInputFilter` allowlist of classes.\n\n5. PHP: `unserialize()` on cookies or request data, plus `phar:\u002F\u002F` wrappers that trigger object\n   magic methods on file functions, are the two routes. Replace with `json_decode`.\n\n6. .NET: `BinaryFormatter` is deprecated as inherently unsafe; `TypeNameHandling.All` in\n   Json.NET is the JSON equivalent of the bug. Set `TypeNameHandling.None`.\n\n7. Prove the exposure with a benign payload that would run only if deserialization executes:\n\n       # Python — this prints PWNED only if yaml.load is unsafe\n       python3 -c \"import yaml; print(yaml.load('!!python\u002Fobject\u002Fapply:os.system [\\\"echo PWNED\\\"]'))\"\n\n8. If a signed blob must be deserialized, verify a MAC over the bytes *before* deserialising, using\n   a constant-time comparison; the signature gates the parser.\n\n## Pitfalls\n\n- `yaml.safe_load` still allows `!!python\u002Fname` aliases in some bindings; test rather than assume.\n- A gadget chain needs one class on the classpath — a framework dependency you forgot is enough.\n- JSON is not automatically safe: polymorphic deserialization (`TypeNameHandling`, Java\n  `@JsonTypeInfo`) reintroduces class construction.\n- Signing without verifying, or verifying after parsing, gives no protection.\n- Cached serialized objects across a deploy can be loaded by the new class version — a deserialise\n  of a stale blob is still untrusted.\n- `phar:\u002F\u002F` deserializes on mere filesystem calls (`file_exists`), not just on `unserialize`.\n\n## Verification\n\n    python3 -c \"import yaml; print(yaml.load('!!python\u002Fobject\u002Fapply:os.system [\\\"echo PWNED\\\"]'))\" 2>&1 \\\n      | rg -q PWNED && echo \"VULNERABLE\" || echo \"safe\"\n\nPass: after the fix the probe prints `safe` (safe_load rejects the tag), and the Java\u002F.NET sink\nlist shows zero untrusted-reachable hits. Report each sink, its input source, and the replacement\nformat adopted.\n","# Review deserialization sinks\n\nDeserializers that can instantiate arbitrary classes turn attacker bytes into attacker code, via\ngadget chains that need no bug in your own code. The durable fix is to stop feeding untrusted input\nto a class-constructing format.\n\n## Procedure\n\n1. Enumerate dangerous sinks per language:\n\n       rg -n \"pickle\\.loads?|cPickle|dill\\.loads|yaml\\.load\\(|marshal\\.loads\" .          # Python\n       rg -n \"ObjectInputStream|readObject\\(|XStream|SnakeYAML|readValue\\(\" .            # Java\n       rg -n \"unserialize\\(|session_decode|igbinary_unserialize\" .                        # PHP\n       rg -n \"BinaryFormatter|NetDataContractSerializer|LosFormatter|TypeNameHandling\" . # .NET\n       rg -n \"node-serialize|serialize-javascript|unserialize\\(\" .                        # Node\n\n2. Classify each hit by reachability: is the byte stream from a request body, a cookie, a cache, a\n   queue message, or a file written by an untrusted party? A sink with no untrusted source is not\n   exploitable — say so explicitly rather than flagging it.\n\n3. Python YAML: `yaml.load(x)` without a `Loader` is remote code execution;\n   `yaml.safe_load(x)` is the fix when the document is pure data.\n\n4. Java: `ObjectInputStream.readObject` on untrusted bytes is exploitable via gadget chains in the\n   classpath (commons-collections, Spring). Prefer JSON with an explicit target class; if native\n   serialization is unavoidable, use a `ObjectInputFilter` allowlist of classes.\n\n5. PHP: `unserialize()` on cookies or request data, plus `phar:\u002F\u002F` wrappers that trigger object\n   magic methods on file functions, are the two routes. Replace with `json_decode`.\n\n6. .NET: `BinaryFormatter` is deprecated as inherently unsafe; `TypeNameHandling.All` in\n   Json.NET is the JSON equivalent of the bug. Set `TypeNameHandling.None`.\n\n7. Prove the exposure with a benign payload that would run only if deserialization executes:\n\n       # Python — this prints PWNED only if yaml.load is unsafe\n       python3 -c \"import yaml; print(yaml.load('!!python\u002Fobject\u002Fapply:os.system [\\\"echo PWNED\\\"]'))\"\n\n8. If a signed blob must be deserialized, verify a MAC over the bytes *before* deserialising, using\n   a constant-time comparison; the signature gates the parser.\n\n## Pitfalls\n\n- `yaml.safe_load` still allows `!!python\u002Fname` aliases in some bindings; test rather than assume.\n- A gadget chain needs one class on the classpath — a framework dependency you forgot is enough.\n- JSON is not automatically safe: polymorphic deserialization (`TypeNameHandling`, Java\n  `@JsonTypeInfo`) reintroduces class construction.\n- Signing without verifying, or verifying after parsing, gives no protection.\n- Cached serialized objects across a deploy can be loaded by the new class version — a deserialise\n  of a stale blob is still untrusted.\n- `phar:\u002F\u002F` deserializes on mere filesystem calls (`file_exists`), not just on `unserialize`.\n\n## Verification\n\n    python3 -c \"import yaml; print(yaml.load('!!python\u002Fobject\u002Fapply:os.system [\\\"echo PWNED\\\"]'))\" 2>&1 \\\n      | rg -q PWNED && echo \"VULNERABLE\" || echo \"safe\"\n\nPass: after the fix the probe prints `safe` (safe_load rejects the tag), and the Java\u002F.NET sink\nlist shows zero untrusted-reachable hits. Report each sink, its input source, and the replacement\nformat adopted.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-review-deserialization-sinks",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-15 02:28:10",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill review-deserialization-sinks",{"tool":55,"command":56},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill review-deserialization-sinks",{"tool":58,"command":59},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill review-deserialization-sinks","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-review-deserialization-sinks\u002FSKILL.md",true,[63,67,73],{"path":64,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":66,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"SOURCE.md","REFERENCE","参考文档",354,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-review-deserialization-sinks\u002FSOURCE.md",{"path":74,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":75,"sourceHtmlUrl":76},"TRUST.auto.yaml",2199,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-review-deserialization-sinks\u002FTRUST.auto.yaml",[78,106,129,146,159,169],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":82,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":35},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":110,"licenseFileUrl":111,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":35},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[115,116,117,118,119,120,121,122,123,124,125,126,127,128],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":110,"licenseFileUrl":133,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":35},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[137,116,138,139,140,141,142,126,125,124,143,144,24,120,145,119,118],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","orders",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":110,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":35},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[154,155,117,156,157,127,125,158,123,122,120,119],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":160,"name":161,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":35},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[166,167,168],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":173,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":35},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[177,178,179,180,181,182,183,26,184,185,186],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]