Skip to content

Security: Unsafe pickle deserialization in Redis/MongoDB queue backends (CWE-502) #408

@hypery11

Description

@hypery11

Summary

The Redis and MongoDB queue backends use pickle.loads() to deserialize task objects without any validation. Python's pickle module can execute arbitrary code during deserialization, enabling Remote Code Execution (RCE) when an attacker has network access to the backing database.

Affected Files

  • grab/spider/queue_backend/redis_queue.py, line 63
  • grab/spider/queue_backend/mongodb_queue.py, line 68

Details

Both queue backends serialize tasks with pickle.dumps() and deserialize with pickle.loads(). Python's official documentation explicitly warns that pickle is unsafe for untrusted data:

Warning: The pickle module is not secure. Only unpickle data you trust. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling.

Since the default Redis/MongoDB configurations do not require authentication, any process with network access to the database can inject malicious pickled data into the task queue.

Impact

  • Remote Code Execution as the user running the Grab spider
  • CVSS 3.1: 8.1 (High) — CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Suggested Fix

Replace pickle with safe serialization (e.g., JSON with a Task.to_dict()/Task.from_dict() pattern), or use a restricted unpickler that only allows the Task class:

import io
import pickle

class RestrictedUnpickler(pickle.Unpickler):
    ALLOWED_CLASSES = {("grab.spider.task", "Task")}
    def find_class(self, module, name):
        if (module, name) not in self.ALLOWED_CLASSES:
            raise pickle.UnpicklingError(f"Forbidden: {module}.{name}")
        return super().find_class(module, name)

def safe_loads(data):
    return RestrictedUnpickler(io.BytesIO(data)).load()

References


Reported by: Tom Chen (hypery11@gmail.com)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions