mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 07:11:28 +02:00
export_yaml masks global_headers and tool_options, and import_yaml feeds that document straight into create(), which had nothing to unmask it against. Exporting an engine that carried auth and importing it back produced an engine that sent `Authorization: ••••••••` to every target and handed nuclei `-api-key ••••••••`. Both validators now refuse a value carrying the mask, naming the header or the tool. update() keeps working: it restores the stored value first and validates what it is about to store, rather than what was submitted, so the editor can keep sending masked values back. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X5roHYDYzSPRNaTkn8hSkJ
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
|
|
from app.services.scan_engine.validation import (
|
|
_mask_global_headers,
|
|
_mask_tool_options,
|
|
_unmask_global_headers,
|
|
_unmask_tool_options,
|
|
_validate_global_headers,
|
|
_validate_tool_options,
|
|
)
|
|
|
|
pytestmark = pytest.mark.api
|
|
|
|
_HEADERS = ["Authorization: Bearer real-token", "X-Env: staging"]
|
|
_TOOLS = {"nuclei": "-header Authorization: Bearer real-token -etags intrusive"}
|
|
|
|
|
|
def test_an_export_masks_the_credential_it_carries():
|
|
assert _mask_global_headers(_HEADERS)[0] == "Authorization: ••••••••"
|
|
assert "real-token" not in _mask_tool_options(_TOOLS)["nuclei"]
|
|
|
|
|
|
def test_importing_an_export_is_refused_rather_than_stored():
|
|
with pytest.raises(HTTPException, match="Authorization"):
|
|
_validate_global_headers(_mask_global_headers(_HEADERS))
|
|
|
|
|
|
def test_importing_masked_tool_options_is_refused():
|
|
with pytest.raises(HTTPException, match="masked"):
|
|
_validate_tool_options(_mask_tool_options(_TOOLS))
|
|
|
|
|
|
def test_a_header_left_masked_by_the_editor_is_restored_not_refused():
|
|
restored = _unmask_global_headers(_mask_global_headers(_HEADERS), _HEADERS)
|
|
_validate_global_headers(restored)
|
|
assert restored == _HEADERS
|
|
|
|
|
|
def test_tool_options_left_masked_by_the_editor_are_restored_not_refused():
|
|
restored = _validate_tool_options(
|
|
_unmask_tool_options(_mask_tool_options(_TOOLS), _TOOLS)
|
|
)
|
|
assert restored == _TOOLS
|
|
|
|
|
|
def test_an_engine_with_no_credential_is_untouched():
|
|
_validate_global_headers(["X-Env: staging"])
|
|
assert _validate_tool_options({"ffuf": "-mc 200,301"}) == {"ffuf": "-mc 200,301"}
|