● Zion Boggan
repos/Cyclops V2/brain/semgrep-rules/deserialization.yaml
zionboggan.com ↗
138 lines · yaml
History for this file →
1
rules:
2
 
3
  - id: cyc-py-pickle-load
4
    languages: [python]
5
    severity: ERROR
6
    message: >
7
      pickle.load/loads on untrusted data is RCE-by-design (gadget via __reduce__).
8
      IMPACT GATE: Family 1 RCE if the bytes are attacker-controlled. Confirm source->sink in Joern,
9
      then prove with an executing gadget (callback / command output).
10
    metadata:
11
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
12
      confidence: HIGH
13
      archetype: [ml-model-loaders, ai-agent-mcp]
14
      impact: rce
15
    patterns:
16
      - pattern-either:
17
          - pattern: pickle.loads(...)
18
          - pattern: pickle.load(...)
19
          - pattern: cPickle.loads(...)
20
          - pattern: cPickle.load(...)
21
          - pattern: _pickle.loads(...)
22
          - pattern: dill.loads(...)
23
          - pattern: dill.load(...)
24
          - pattern: cloudpickle.loads(...)
25
          - pattern: cloudpickle.load(...)
26
 
27
  - id: cyc-py-yaml-unsafe-load
28
    languages: [python]
29
    severity: ERROR
30
    message: >
31
      yaml.load without SafeLoader (or yaml.unsafe_load/full_load) constructs arbitrary Python
32
      objects -> RCE. IMPACT GATE: Family 1. yaml.safe_load is the safe form and is intentionally
33
      NOT matched.
34
    metadata:
35
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
36
      confidence: HIGH
37
      archetype: [devops-infra, ai-agent-mcp]
38
      impact: rce
39
    patterns:
40
      - pattern-either:
41
          - pattern: yaml.load($X)
42
          - pattern: yaml.unsafe_load(...)
43
          - pattern: yaml.full_load(...)
44
      - pattern-not: yaml.load($X, Loader=yaml.SafeLoader)
45
      - pattern-not: yaml.load($X, Loader=SafeLoader)
46
 
47
  - id: cyc-py-ml-unsafe-load
48
    languages: [python]
49
    severity: ERROR
50
    message: >
51
      torch.load / joblib.load / numpy.load(allow_pickle=True) / pandas.read_pickle deserialize via
52
      pickle under the hood -> RCE from a malicious model/array file. IMPACT GATE: Family 1, the
53
      model-file RCE class (ml-model-loaders archetype).
54
    metadata:
55
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
56
      confidence: HIGH
57
      archetype: [ml-model-loaders]
58
      impact: rce
59
    patterns:
60
      - pattern-either:
61
          - pattern: torch.load(...)
62
          - pattern: joblib.load(...)
63
          - pattern: pandas.read_pickle(...)
64
          - pattern: pd.read_pickle(...)
65
          - pattern: numpy.load(..., allow_pickle=True, ...)
66
          - pattern: np.load(..., allow_pickle=True, ...)
67
 
68
  - id: cyc-py-marshal-shelve
69
    languages: [python]
70
    severity: ERROR
71
    message: >
72
      marshal.loads / shelve.open deserialize untrusted bytes into executable/code objects.
73
      IMPACT GATE: Family 1 if the source is attacker-controlled.
74
    metadata:
75
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
76
      confidence: MEDIUM
77
      archetype: [ml-model-loaders, devops-infra]
78
      impact: rce
79
    patterns:
80
      - pattern-either:
81
          - pattern: marshal.loads(...)
82
          - pattern: marshal.load(...)
83
          - pattern: shelve.open(...)
84
 
85
  - id: cyc-java-objectinputstream
86
    languages: [java]
87
    severity: ERROR
88
    message: >
89
      ObjectInputStream.readObject on untrusted bytes is the canonical Java deserialization RCE
90
      (ysoserial gadget chains). IMPACT GATE: Family 1.
91
    metadata:
92
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
93
      confidence: HIGH
94
      archetype: [devops-infra]
95
      impact: rce
96
    patterns:
97
      - pattern-either:
98
          - pattern: (ObjectInputStream $OIS).readObject()
99
          - pattern: $OIS.readObject()
100
          - pattern: $OIS.readUnshared()
101
          - pattern: new ObjectInputStream(...)
102
      - metavariable-regex:
103
          metavariable: $OIS
104
          regex: "(?i).*(ois|objectinput|in|stream).*"
105
 
106
  - id: cyc-java-other-deser
107
    languages: [java]
108
    severity: ERROR
109
    message: >
110
      XStream.fromXML / SnakeYAML new Yaml().load / Kryo.readObject deserialize untrusted input into
111
      arbitrary types -> RCE. IMPACT GATE: Family 1.
112
    metadata:
113
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
114
      confidence: MEDIUM
115
      archetype: [devops-infra]
116
      impact: rce
117
    patterns:
118
      - pattern-either:
119
          - pattern: $X.fromXML(...)
120
          - pattern: new Yaml().load(...)
121
          - pattern: $K.readClassAndObject(...)
122
 
123
  - id: cyc-js-node-serialize
124
    languages: [javascript, typescript]
125
    severity: ERROR
126
    message: >
127
      node-serialize unserialize() executes an IIFE embedded in the payload -> RCE. IMPACT GATE:
128
      Family 1.
129
    metadata:
130
      cwe: ["CWE-502: Deserialization of Untrusted Data"]
131
      confidence: HIGH
132
      archetype: [ai-agent-mcp, devops-infra]
133
      impact: rce
134
    patterns:
135
      - pattern-either:
136
          - pattern: $S.unserialize(...)
137
          - pattern: serialize.unserialize(...)
138
          - pattern: $F.deepDeserialize(...)