@@ -432,3 +432,79 @@ async def mock_cancel_flow_build_with_cancelled_error(*_args, **_kwargs):
432432 finally :
433433 # Restore the original function to avoid affecting other tests
434434 monkeypatch .setattr (langflow .api .v1 .chat , "cancel_flow_build" , original_cancel_flow_build )
435+
436+
437+ @pytest .mark .benchmark
438+ async def test_build_public_tmp_ignores_data_parameter (client , json_memory_chatbot_no_llm , logged_in_headers ):
439+ """Test that build_public_tmp endpoint silently ignores data parameter for security.
440+
441+ Security Test: Verifies that when a user attempts to provide custom flow data
442+ to the public flow endpoint, FastAPI silently ignores the extra parameter and
443+ the endpoint functions normally using the stored flow data from the database.
444+ """
445+ # Create a flow
446+ flow_id = await create_flow (client , json_memory_chatbot_no_llm , logged_in_headers )
447+
448+ # Make the flow public
449+ response = await client .patch (
450+ f"api/v1/flows/{ flow_id } " ,
451+ json = {"access_type" : "PUBLIC" },
452+ headers = logged_in_headers ,
453+ )
454+ assert response .status_code == codes .OK
455+
456+ # Create malicious flow data with different structure
457+ malicious_data = {"nodes" : [{"id" : "malicious" , "data" : {"type" : "CustomComponent" }}], "edges" : []}
458+
459+ # Set a client_id cookie
460+ client .cookies .set ("client_id" , "test-security-client-123" )
461+
462+ # Attempt to build with malicious data - FastAPI will silently ignore it
463+ response = await client .post (
464+ f"api/v1/build_public_tmp/{ flow_id } /flow" ,
465+ json = {
466+ "inputs" : {"session" : "test_session" },
467+ "data" : malicious_data , # This will be silently ignored by FastAPI
468+ },
469+ headers = {"Content-Type" : "application/json" },
470+ )
471+
472+ # Verify the request succeeded - the data parameter is simply ignored
473+ assert response .status_code == codes .OK
474+ response_data = response .json ()
475+ assert "job_id" in response_data
476+
477+
478+ @pytest .mark .benchmark
479+ async def test_build_public_tmp_without_data_parameter (client , json_memory_chatbot_no_llm , logged_in_headers ):
480+ """Test that build_public_tmp endpoint works without data parameter.
481+
482+ Security Test: Verifies that when no data parameter is provided, the endpoint
483+ works normally and returns a job_id. This proves the data parameter is optional
484+ and the stored flow definition is always used.
485+ """
486+ # Create a flow
487+ flow_id = await create_flow (client , json_memory_chatbot_no_llm , logged_in_headers )
488+
489+ # Make the flow public
490+ response = await client .patch (
491+ f"api/v1/flows/{ flow_id } " ,
492+ json = {"access_type" : "PUBLIC" },
493+ headers = logged_in_headers ,
494+ )
495+ assert response .status_code == codes .OK
496+
497+ # Set a client_id cookie
498+ client .cookies .set ("client_id" , "test-no-data-client" )
499+
500+ # Build without providing data parameter
501+ response = await client .post (
502+ f"api/v1/build_public_tmp/{ flow_id } /flow" ,
503+ json = {"inputs" : {"session" : "test_session" }},
504+ headers = {"Content-Type" : "application/json" },
505+ )
506+
507+ # Verify the request succeeded
508+ assert response .status_code == codes .OK
509+ response_data = response .json ()
510+ assert "job_id" in response_data
0 commit comments