merge: hardening seguridad osint_web (TrustedHost + escape iCal + tests del flag)
This commit is contained in:
@@ -7,4 +7,4 @@
|
||||
"enabled_at": "2026-06-13"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-2
@@ -2199,7 +2199,9 @@ def _build_vcalendar(data: "EventIn", uid: str) -> str:
|
||||
body.append(vtz)
|
||||
vevent = [
|
||||
"BEGIN:VEVENT",
|
||||
"UID:%s" % uid,
|
||||
# Sanitizamos el UID (quitamos saltos de línea) para que no pueda inyectar
|
||||
# propiedades/componentes iCal nuevos en el VEVENT.
|
||||
"UID:%s" % str(uid).replace("\r", "").replace("\n", ""),
|
||||
"DTSTAMP:%s" % dtstamp,
|
||||
_ical_dt_property("DTSTART", data.dtstart, tz, data.all_day),
|
||||
]
|
||||
@@ -2219,7 +2221,10 @@ def _build_vcalendar(data: "EventIn", uid: str) -> str:
|
||||
# canónica "RRULE:<cuerpo>" que entienden Xandikos y los clientes (DAVx5).
|
||||
if rrule.upper().startswith("RRULE:"):
|
||||
rrule = rrule[len("RRULE:"):].strip()
|
||||
vevent.append("RRULE:%s" % rrule)
|
||||
# Sanitizar: quitar saltos de línea para que el valor de la RRULE no
|
||||
# inyecte propiedades/componentes nuevos (los `;`/`,` son separadores
|
||||
# legítimos de la regla, así que no se escapan).
|
||||
vevent.append("RRULE:%s" % rrule.replace("\r", "").replace("\n", ""))
|
||||
vevent.append("END:VEVENT")
|
||||
body.append("\r\n".join(vevent))
|
||||
body.append("END:VCALENDAR")
|
||||
@@ -2240,6 +2245,15 @@ def create_app(vault_dir: str) -> FastAPI:
|
||||
"""
|
||||
state = VaultState(vault_dir)
|
||||
app = FastAPI(title="osint_web", version="0.1.0")
|
||||
# Anti DNS-rebinding: solo acepta requests cuyo Host sea localhost. Cierra el
|
||||
# vector por el que una web maliciosa rebindea su dominio a 127.0.0.1 y, desde
|
||||
# el navegador del usuario, alcanza este service local (sin auth) o el de DuckDB.
|
||||
from starlette.middleware.trustedhost import TrustedHostMiddleware
|
||||
|
||||
app.add_middleware(
|
||||
TrustedHostMiddleware,
|
||||
allowed_hosts=["127.0.0.1", "localhost", "testserver"],
|
||||
)
|
||||
app.state.vault = state
|
||||
|
||||
# -- Vault --
|
||||
|
||||
@@ -25,6 +25,17 @@ sys.path.insert(0, os.path.join(_HERE, "..", "server"))
|
||||
import main as srv # noqa: E402
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _flag_off_por_defecto(monkeypatch, tmp_path):
|
||||
"""Por defecto los tests corren con OSINT_DB_BACKEND OFF (camino histórico
|
||||
vault + Xandikos), independientemente del estado real de
|
||||
``dev/feature_flags.json`` en disco. Apunta ``_FLAGS_FILE`` a un archivo
|
||||
inexistente (→ False). Los tests que prueban el camino ON sobrescriben
|
||||
``srv._FLAGS_FILE`` dentro del propio test, ganando sobre este default.
|
||||
"""
|
||||
monkeypatch.setattr(srv, "_FLAGS_FILE", str(tmp_path / "_no_flags.json"))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fixtures: vault sintético mínimo
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user