#1227·paper-qa

Potential Deserialization Vulnerability in SearchIndex.index_files Using pickle.loads

Author: Doria77486Created Dec 8, 2025Updated Apr 29, 2026
Labelsbug

Description

The SearchIndex.index_files method in PaperQA internally uses pickle.loads to load serialized index files. This introduces a potential arbitrary code execution vulnerability if a malicious .pkl file is provided, as pickle is inherently unsafe when loading untrusted data.

python
    async def index_files(self) -> dict[str, str]:
        if not self._index_files:
            file_index_path = await self.file_index_filename
            if await file_index_path.exists():
                async with await anyio.open_file(file_index_path, "rb") as f:
                    content = await f.read()
                    try:
                        self._index_files = pickle.loads(  # noqa: S301
                            zlib.decompress(content)
                        )
                    except Exception:
                        logger.exception(
                            f"Failed to load index file {file_index_path}."
                        )
                        raise
        return self._index_files

Poc

step1

Create a malicious pickle file, then compress it using zlib, and save the compressed file as files.zip, then put it into "./paper_qa/pqa_index/files.zip"

step2 Run the following script:

python
import asyncio
from paperqa.agents.search import SearchIndex

async def main():
    si = SearchIndex(index_directory="./paper_qa")
    data = await si.index_files
    print("Loaded index_files:", data)

asyncio.run(main())