TRANSPARENCY: This is an AI-assisted submission – Aikido
Summary
gtc.Payload.Offerable() always returns true, so the generic protocol-selection handler can select EAP-GTC in an unprotected root context or as a configured fallback. GTC then emits its challenge and accepts the peer response as ordinary EAP payload data, without a confidentiality-context or downgrade-policy check.
Description
EAP-GTC is a credential-bearing method whose response is only suitable for transmission when encapsulated by an authenticated, confidentiality-providing method such as PEAP, TTLS, or TLS. This implementation does not encode that requirement. Offerable() unconditionally authorizes GTC, and the generic handler uses that result for protocol selection without distinguishing root and protected inner contexts. Encode() returns the configured challenge directly and Decode() retains the peer response directly, so a root-level or fallback GTC exchange exposes the credential-bearing response on the EAP wire. The handler also advances through configured protocols after a NAK, allowing GTC to be selected as an insecure fallback when it appears in the configured list. The example uses GTC as an inner method, but the public protocol configuration can also make it available at the root level. This is a real security issue when the application configuration permits that composition: an observer of the client-facing EAP path can recover passwords, OTPs, or bearer tokens, and a downgrade path can defeat an administrator's stronger-method preference.
Risk
Medium: the attacker needs observation or interception access to the client-facing EAP path, and the deployment must configure GTC as a root method or permit it as a fallback. Once selected, this method applies no cryptographic protection to the credential-bearing EAP payload.
Evidence
1
GTC is unconditionally marked offerable, with no requirement that it run inside a protected tunnel.
func (p *Payload) Offerable() bool {
return true
}
2
The generic handler relies only on Offerable() before offering the configured protocol and does not apply a root-versus-inner confidentiality policy.
np, t, _ := eap.EmptyPayload(stm.GetEAPSettings(), nextChallengeToOffer)
...
if !np.Offerable() {
ctx.Log().Debug("Root-EAP: protocol not offerable, skipping")
return next()
}
3
The peer response is retained verbatim and the configured challenge is emitted verbatim, making both ordinary EAP payload bytes rather than data protected by GTC itself.
func (p *Payload) Decode(raw []byte) error {
p.raw = raw
return nil
}
func (p *Payload) Encode() ([]byte, error) {
return p.Challenge, nil
}
4
The unprotected raw response is passed directly to the application validator and can complete authentication.
st := settings.ValidateResponse(ctx, p.raw)
if st != protocol.StatusUnknown {
ctx.EndInnerProtocol(st)
return &Payload{}
}
5
After a non-initial NAK, the handler advances to the next configured method without checking whether that fallback is an unacceptable security downgrade.
l.Debug("Root-EAP: received NAK, trying next protocol", "desired", n.DesiredType)
pp.(*eap.Payload).Payload = nil
return next()
6
The example demonstrates inner use, while the same public settings structure can place GTC in a root protocol list without a library-level restriction.
InnerProtocols: protocol.Settings{
Protocols: []protocol.ProtocolConstructor{
identity.Protocol,
legacy_nak.Protocol,
gtc.Protocol,
mschapv2.Protocol,
},
ProtocolPriority: []protocol.Type{mschapv2.TypeMSCHAPv2, gtc.TypeGTC},
Root Cause Analysis
The handler calls np.Offerable() before offering a configured protocol and does not otherwise establish that the current context is a protected inner tunnel. Because GTC's implementation always returns true, a root-level configuration containing GTC reaches its normal handling path. Its challenge is returned as ordinary EAP application data, and the peer's raw response is passed to ValidateResponse without cryptographic protection supplied by this method. Separately, the NAK path advances to the next configured protocol without checking whether the next method is an unacceptable security downgrade. Thus the code exposes a credential-bearing cleartext method whenever application configuration permits GTC outside a confidentiality-providing context.
Remediation
Require an authenticated confidentiality-providing parent context before GTC is offerable, and enforce the requirement at the protocol-selection boundary rather than relying solely on caller configuration. Reject GTC in root-level protocol lists by default, or require an explicit insecure-use policy for that mode. Also prevent NAK-driven fallback from selecting GTC unless the protected-context or explicit-policy check succeeds. Preserve GTC for validated PEAP/TTLS/TLS inner contexts.
TRANSPARENCY: This is an AI-assisted submission – Aikido
Summary
gtc.Payload.Offerable() always returns true, so the generic protocol-selection handler can select EAP-GTC in an unprotected root context or as a configured fallback. GTC then emits its challenge and accepts the peer response as ordinary EAP payload data, without a confidentiality-context or downgrade-policy check.
Description
EAP-GTC is a credential-bearing method whose response is only suitable for transmission when encapsulated by an authenticated, confidentiality-providing method such as PEAP, TTLS, or TLS. This implementation does not encode that requirement. Offerable() unconditionally authorizes GTC, and the generic handler uses that result for protocol selection without distinguishing root and protected inner contexts. Encode() returns the configured challenge directly and Decode() retains the peer response directly, so a root-level or fallback GTC exchange exposes the credential-bearing response on the EAP wire. The handler also advances through configured protocols after a NAK, allowing GTC to be selected as an insecure fallback when it appears in the configured list. The example uses GTC as an inner method, but the public protocol configuration can also make it available at the root level. This is a real security issue when the application configuration permits that composition: an observer of the client-facing EAP path can recover passwords, OTPs, or bearer tokens, and a downgrade path can defeat an administrator's stronger-method preference.
Risk
Medium: the attacker needs observation or interception access to the client-facing EAP path, and the deployment must configure GTC as a root method or permit it as a fallback. Once selected, this method applies no cryptographic protection to the credential-bearing EAP payload.
Evidence
1
GTC is unconditionally marked offerable, with no requirement that it run inside a protected tunnel.
2
The generic handler relies only on Offerable() before offering the configured protocol and does not apply a root-versus-inner confidentiality policy.
3
The peer response is retained verbatim and the configured challenge is emitted verbatim, making both ordinary EAP payload bytes rather than data protected by GTC itself.
4
The unprotected raw response is passed directly to the application validator and can complete authentication.
5
After a non-initial NAK, the handler advances to the next configured method without checking whether that fallback is an unacceptable security downgrade.
6
The example demonstrates inner use, while the same public settings structure can place GTC in a root protocol list without a library-level restriction.
Root Cause Analysis
The handler calls np.Offerable() before offering a configured protocol and does not otherwise establish that the current context is a protected inner tunnel. Because GTC's implementation always returns true, a root-level configuration containing GTC reaches its normal handling path. Its challenge is returned as ordinary EAP application data, and the peer's raw response is passed to ValidateResponse without cryptographic protection supplied by this method. Separately, the NAK path advances to the next configured protocol without checking whether the next method is an unacceptable security downgrade. Thus the code exposes a credential-bearing cleartext method whenever application configuration permits GTC outside a confidentiality-providing context.
Remediation
Require an authenticated confidentiality-providing parent context before GTC is offerable, and enforce the requirement at the protocol-selection boundary rather than relying solely on caller configuration. Reject GTC in root-level protocol lists by default, or require an explicit insecure-use policy for that mode. Also prevent NAK-driven fallback from selecting GTC unless the protected-context or explicit-policy check succeeds. Preserve GTC for validated PEAP/TTLS/TLS inner contexts.