_resolve_scoped_artifact_path validates the filename against traversal, but _base_root and _session_artifacts_dir use user_id and session_id directly in Path() construction without the same check.
A user_id or session_id containing ../ segments builds a scope root outside root_dir. The filename guard then validates against the already-escaped scope root, so it doesn't catch the escape.
GcsArtifactService and InMemoryArtifactService use string keys, not filesystem paths - only FileArtifactService is affected.
_resolve_scoped_artifact_pathvalidates the filename against traversal, but_base_rootand_session_artifacts_diruseuser_idandsession_iddirectly inPath()construction without the same check.A
user_idorsession_idcontaining../segments builds a scope root outsideroot_dir. The filename guard then validates against the already-escaped scope root, so it doesn't catch the escape.GcsArtifactServiceandInMemoryArtifactServiceuse string keys, not filesystem paths - onlyFileArtifactServiceis affected.