Skip to content

fix: sign and verify on-disk pickle/FAISS caches with HMAC (APPENG-5695, APPENG-5696) - #321

Open
gnetanel wants to merge 1 commit into
RHEcosystemAppEng:mainfrom
gnetanel:APPENG-5695_and_APPENG-5696
Open

fix: sign and verify on-disk pickle/FAISS caches with HMAC (APPENG-5695, APPENG-5696)#321
gnetanel wants to merge 1 commit into
RHEcosystemAppEng:mainfrom
gnetanel:APPENG-5695_and_APPENG-5696

Conversation

@gnetanel

Copy link
Copy Markdown
Collaborator
  • Mitigate CWE-502 by HMAC-signing on-disk cache artifacts before any pickle deserialization.
  • APPENG-5695: Sign/verify document pickle caches and the runtime stdlib pickle cache (dump_pickle_signed / load_pickle_verified).
  • APPENG-5696: Sign/verify FAISS index artifacts (including index.pkl) on VDB write/load.
  • On integrity failure:
    • Document pickles / FAISS → discard or rebuild rather than loading untrusted pickle.
  • HMAC key is resolved from env / credential encryption secret / local key file — not stored alongside cache artifacts on the PVC.

@gnetanel
gnetanel requested a review from zvigrinberg July 30, 2026 12:00
@vbelouso

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@zvigrinberg zvigrinberg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @gnetanel
Please see my comments.


def resolve_key_material() -> bytes:
"""Resolve HMAC key material from env, shared secret, or a local key file."""
for env_name in (CACHE_INTEGRITY_KEY_ENV, CREDENTIAL_ENCRYPTION_KEY_ENV):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnetanel If CACHE_INTEGRITY_KEY_ENV will be set in deployment and will used for the HMAC signing for creating pickle files , but in a restart it will be omitted, this will fall back to verify according to only CREDENTIAL_ENCRYPTION_KEY_ENV, which falsely will fail the verification before loading pickle files

Instead, go only for CREDENTIAL_ENCRYPTION_KEY_ENV, and omit the other one ( unless you want to add it to the deployment' secrets keys mounted into that env var)

Comment on lines +52 to +54
def _default_key_file() -> Path:
data_dir = os.environ.get("EXPLOIT_IQ_DATA_DIR", "./.cache/am_cache/")
return Path(data_dir) / ".secrets" / "cache_integrity_key"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnetanel This is quite dangerous, as the default_key_file ( when no env var available) , which is used to generate random key out of it, is persisted on the disk/pvc
So the attacker can gain access to it and using this key, can create any files he wants and sign them using the key so they will be considered legitimate.
But this is not the only problem...
What happens if it deleted ( by mistake or intentionally), next same request or request that uses the same pickle file, will use another random generated key in order to verify integrity and it will fail.

if value:
return value.encode("utf-8")

key_file = Path(os.environ.get(CACHE_INTEGRITY_KEY_FILE_ENV, str(_default_key_file())))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnetanel Don't fallback to default key file, it's security concern and error prone as well.
Instead, if env var is not populated ( you should decide if it's going to be CREDENTIAL_ENCRYPTION_KEY_ENV or CACHE_INTEGRITY_KEY_ENV) you should raise ValueError with an appropriate error message.

]


def integrity_manifest_path(folder_path: str | os.PathLike[str], index_name: str = "index") -> Path:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gnetanel minor - index_name is not being used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants