Canonical page: <https://www.guvenkaya.co/reports/virto>

[Work & reports](https://www.guvenkaya.co/work) Report

# Virto Network Pallet Pass Security Review

Guvenkaya reviewed the Virto Network Pass pallet and its passkey authenticators.

[View PDF on GitHub](https://github.com/Guvenkaya/public-reports/blob/master/Virto-Network-Pallet-Pass-Security-Review-Final-Report.pdf)

![Virto Network logo](https://www.guvenkaya.co/reports/assets/clients/virto.png)

Date of engagement: 9th July 2025 - 18th July 2025

- **Timur Güvenkaya** Principal advisor

## Engagement Dashboard

### Audit results

Guvenkaya conducted a security assessment of the Virto network Substrate Pallet Pass from 9th July 2025 to 18th July 2025. During this engagement, a total of 8 findings were reported. 1 of the findings was high, 4 medium and the remaining were low severity. Major issues are fixed by the Virto Network team.

### Engagement record

- Client

  Virto Network

- System

  Virto Network Pass pallet (Substrate)

- Review period

  9th July 2025 - 18th July 2025

- Paths in scope

  2

- Principal advisor

  Timur Güvenkaya

### Timeline

1. Review start 9th July 2025
2. Draft report 21st July 2025
3. Final report 19th August 2025

### Findings by severity

- Critical **0**
- High **1**
- Medium **4**
- Low **3**
- Informational **0**

### Finding status at final report

**8** Raised

**7** Fixed

**1** Scheduled

### Remediation complexity

**5** Simple

**3** Moderate

### Impact

**2** Severe

**3** Moderate

**3** Negligible

### Likelihood

**1** Likely

**5** Possible

**2** Rare

## Advisory and Client

The advisory

![Guvenkaya](https://www.guvenkaya.co/logo.svg)

Guvenkaya specializes in security for digital assets and financial infrastructure, from smart contracts and protocols to applications, infrastructure, custody and cryptography.

Our team, including the sitting Heads of Security at Gauntlet and Agora, brings experience from Kraken, OpenZeppelin, Binance, ZKsync, Nillion, Invicti and EY. Across the team: 200+ security reviews, $30B+ in volume secured, 13 published cryptography research papers, and credentials including OSCP, OSWE and CISM.

- Every reviewer has a public bio and is named before you sign. We match expertise to your system, with a principal leading scoping and checking findings.

The client

![Virto Network](https://www.guvenkaya.co/reports/assets/clients/virto.png)

Virto Network is next generation payment infrastructure for impactful communities.

## Scope and Review Boundaries

### Review depths

- Deep

  Line-by-line review with explicit attack hypotheses, adversarial reasoning about state transitions, and reproduction attempts for each hypothesis that survived reading.

- Supporting

  The code was read for its effect on a reviewed flow. Behaviour outside that effect was not assessed.

- Targeted

  Entry points were exercised or triaged against the flow's security properties rather than read in full.

This is the code we read, and how closely. 2 paths are in scope. Each path links to the file at the reviewed commit.

| Path                                                                                                                                                                                                       | Review depth | Scope note          |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------- |
| [`pallets/pass`](https://github.com/virto-network/frame-contrib/tree/d78e5e2236b8f8a8c5f07f7fef319729bf959249/pallets/pass)                                                                                | Deep         | Pallet Pass         |
| [`https://github.com/virto-network/pass-authenticators/tree/344a4363b0a887810932d625c63dff896c1f094a`](https://github.com/virto-network/pass-authenticators/tree/344a4363b0a887810932d625c63dff896c1f094a) | Deep         | Pass Authenticators |

### Out of scope

The audit will include reviewing the code for security vulnerabilities. The audit does not include a review of the tests and dependencies.

## Assessment Framework

Guvenkaya rates findings by likelihood and impact so remediation can be prioritized by technical risk, business context, and the decision the engagement is meant to support.

### Rating chain applied to every finding

1. 01 **Likelihood** Likely, possible or rare
2. 02 **Impact** Severe, moderate or negligible
3. 03 **Severity** Derived from the matrix below
4. 04 **Remediation complexity** Simple, moderate or difficult
5. 05 **Status** Not fixed, fixed, acknowledged or scheduled

### Impact

| Impact     | What it means here                                                                                                                                    |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Severe     | Exploitation could result in critical loss or compromise, such as full system control, substantial financial loss, or severe reputational damage.     |
| Moderate   | Exploitation may lead to limited data loss, partial compromise, moderate financial impact, or noticeable degradation of services.                     |
| Negligible | Exploitation has minimal impact, such as minor data exposure without significant consequences or slight inconvenience without substantial disruption. |

### Likelihood

| Likelihood | What it means here                                                                                 |
| ---------- | -------------------------------------------------------------------------------------------------- |
| Likely     | The vulnerability is easily discoverable and not overly complex to exploit.                        |
| Possible   | The vulnerability presents some challenges either in discovery or in the complexity of the attack. |
| Rare       | The vulnerability is either very difficult to discover or complex to exploit, or both.             |

This matrix provides a nuanced view, taking into account both the ease of discovering a vulnerability and the complexity involved in exploiting it.

| Attack Complexity \ Discovery Ease | Obvious  | Concealed | Hidden   |
| ---------------------------------- | -------- | --------- | -------- |
| Complex                            | Possible | Rare      | Rare     |
| Moderate                           | Likely   | Possible  | Rare     |
| Straightforward                    | Likely   | Possible  | Possible |

### Severity

| Severity      | What it means here                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Critical      | Assigned to vulnerabilities with severe impact and a likely likelihood of exploitation.                                                                       |
| High          | For vulnerabilities with either severe impact but only a possible likelihood, or moderate impact with a likely likelihood.                                    |
| Medium        | Used for vulnerabilities with severe impact but a rare likelihood, moderate impact with a possible likelihood, or negligible impact with a likely likelihood. |
| Low           | For vulnerabilities with moderate impact and rare likelihood, or negligible impact with a possible likelihood.                                                |
| Informational | The lowest severity rating, typically for vulnerabilities with negligible impact and a rare likelihood of exploitation.                                       |

| Likelihood \ Impact | Severe   | Moderate | Negligible    |
| ------------------- | -------- | -------- | ------------- |
| Likely              | Critical | High     | Medium        |
| Possible            | High     | Medium   | Low           |
| Rare                | Medium   | Low      | Informational |

### Remediation complexity

This measures how difficult it is to remediate a finding once it has been identified.

| Remediation complexity | What it means here                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Simple                 | Patches or fixes are readily available and easily implemented.                                                     |
| Moderate               | Requires some time and resources to remediate, but well within the capabilities of most organizations.             |
| Difficult              | Remediation requires significant resources, specialized skills, or substantial changes to systems or architecture. |

### Finding status

This tracks the client's response to each finding and whether remediation has been completed, accepted, or scheduled.

| Status       | What it means here                                                                                                                                                                                                                                                              |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Not Fixed    | Indicates that the vulnerability has been identified but no remedial action has been taken yet. This status is crucial for newly discovered vulnerabilities or those awaiting prioritization.                                                                                   |
| Fixed        | This status is applied when the vulnerability has been successfully remediated. It implies that appropriate measures, such as patching, configuration changes, or architectural modifications, have been implemented to resolve the issue.                                      |
| Acknowledged | This status is used for vulnerabilities that have been recognized, but for various reasons (such as risk acceptance, cost, or other business decisions), have not been fixed. It indicates that the risk posed by the vulnerability is known and has been consciously accepted. |
| Scheduled    | This status indicates that the vulnerability has been acknowledged and a plan is in place to fix it in the future. It signifies that while remediation hasn't yet occurred, the issue has been prioritized and is part of the planned development roadmap.                      |

## Findings Summary

**8** All findings

**0** Critical

**1** High

**4** Medium

**3** Low

**0** Informational

### Findings register

| Finding                                                                                                    | Impact     | Likelihood | Severity | Remediation complexity | Status    |
| ---------------------------------------------------------------------------------------------------------- | ---------- | ---------- | -------- | ---------------------- | --------- |
| [GUV-1: DoS of The Main Functionality Through Session Key Hijacking](#guv-1)                               | Moderate   | Likely     | High     | Simple                 | Fixed     |
| [GUV-2: Phishing and Cross-Site Credential Reuse Attacks Through Missing Origin & rpId Validation](#guv-2) | Severe     | Rare       | Medium   | Simple                 | Fixed     |
| [GUV-3: Arbitrary Device Registration Through Missing Validation in Device Attestation](#guv-3)            | Severe     | Rare       | Medium   | Moderate               | Fixed     |
| [GUV-4: Potential DoS and Resource Exhaustion Through Underestimated Benchmarks and Fixed Weights](#guv-4) | Moderate   | Possible   | Medium   | Moderate               | Scheduled |
| [GUV-5: Potential Out-of-Memory (OOM) and Degraded Performance Due to Inefficient Parsing](#guv-5)         | Moderate   | Possible   | Medium   | Moderate               | Fixed     |
| [GUV-6: Silent or Unauthorized Authentication Through Missing Authenticator Flags Validation](#guv-6)      | Negligible | Possible   | Low      | Simple                 | Fixed     |
| [GUV-7: Possible Storage Bloating Due To Unbounded Devices and Session Keys Per User](#guv-7)              | Negligible | Possible   | Low      | Simple                 | Fixed     |
| [GUV-8: Authentication Through Incorrect Credential Type](#guv-8)                                          | Negligible | Possible   | Low      | Simple                 | Fixed     |

## Detailed Findings

### GUV-1: DoS of The Main Functionality Through Session Key Hijacking

- Severity

  High

- Impact

  Moderate

- Likelihood

  Likely

- Remediation Complexity

  Simple

- Status

  Fixed

#### Description

In Pallet Pass, session keys are publicly exposed through the SessionCreated event (emitted in add\_session\_key with the raw session\_key value) and are queryable via the SessionKeys storage map. An attacker can monitor events or query storage to obtain existing session keys from other users. Due to insufficient checks in `add_session_key`, the attacker can then call this extrinsic with the stolen key for their own pass account. This triggers `try_remove_session_key`, which removes the key from the original owner's storage (decrementing their consideration count and emitting SessionRemoved), and re-assigns it to the attacker with a new expiration. The uniqueness check !frame\_system::Pallet::\<T>::account\_exists(session\_key) only prevents collisions with persistent system accounts, not with existing ephemeral session keys in the pallet's storage. As a result, attackers can hijack keys before their natural expiry, rendering the session key functionality unreliable.

add\_session\_key:pallet\_pass/​src/​lib.rs

```
ConsiderationHandler::<         T::AccountId,         SessionKeyConsiderations<T, I>,         T::SessionKeyConsideration,T::AccountId,>::increment(address)?;       Self::try_remove_session_key(session_key)?;       let until = duration         .unwrap_or(T::MaxSessionDuration::get())         .min(T::MaxSessionDuration::get());     SessionKeys::<T, I>::insert(session_key.clone(), (address.clone(), until));     Self::schedule_next_removal(session_key, duration)?;     ... }
```

try\_remove\_session\_key:pallet\_pass/​src/​lib.rs

```
if let Some(address) = &Self::pass_account_from_session_key(session_key) {         ConsiderationHandler::<             T::AccountId,             SessionKeyConsiderations<T, I>,             T::SessionKeyConsideration,             T::AccountId,         >::decrement(address)?;           SessionKeys::<T, I>::remove(session_key);           Self::deposit_event(Event::<T, I>::SessionRemoved {             session_key: session_key.clone(),         })     ... }
```

#### Impact

- **Denial-of-Service (DoS) of main functionality**: Attackers can continuously hijack all active session keys (e.g., by monitoring events and calling add\_session\_key with short durations like 1 block), making sessions unusable for legitimate users. Victims must re-authenticate via passkeys/devices, degrading UX and potentially overwhelming the system with re-auth requests.
- **Griefing Vector**: As outlined, attackers can target specific users (e.g., high-value accounts) or broadly disrupt the session feature, rendering it "useless" without constant re-creation. With short durations, attackers avoid risks to their own accounts while forcing expirations.
- **Economic Waste**: Victims lose active sessions prematurely, incurring re-auth costs (e.g., time/gas for new keys).
- **Reputation Damage**: Undermines trust in session keys as a reliable "short-lived" auth mechanism.

Proof of concept: [gist.github.com](https://gist.github.com/guvenkaya-security-team/c053cc113557493c40b2b7e0264acb45#file-guv_1-rs) [GUV-1](#guv-1) PoC

#### Recommendation

- **Prevent Key Reuse**: Add a check in add\_session\_key to ensure the key isn't already in SessionKeys: ensure!(!SessionKeys::\<T, I>::contains\_key(session\_key), Error::\<T, I>::SessionKeyInUse);.
- **Obscure Keys in Events**: Emit a hash instead of raw session\_key in SessionCreated (e.g., session\_key\_hash: T::Hashing::hash(\&session\_key.encode())).

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/frame-contrib/issues/55) [GUV-1](#guv-1)

### GUV-2: Phishing and Cross-Site Credential Reuse Attacks Through Missing Origin & rpId Validation

- Severity

  Medium

- Impact

  Severe

- Likelihood

  Rare

- Remediation Complexity

  Simple

- Status

  Fixed

#### Description

Pallet Pass's WebAuthn verification lacks checks for the origin (client domain) in client\_data JSON and rpIdHash in authenticator\_data, allowing credentials generated for one site to be reused on another. Per WebAuthn specs, these must match the expected Relying Party (RP) to prevent cross-origin misuse. The verifier only does signature checks, ignoring these fields.

#### Impact

- **Cross-Site Credential Reuse**: Allows auth from unintended domains, bypassing site isolation.
- **Compliance Failures**: Non-spec-compliant; may fail interop with standard WebAuthn clients, causing auth denials or bugs.

Proof of concept: [gist.github.com](https://gist.github.com/guvenkaya-security-team/c053cc113557493c40b2b7e0264acb45#file-guv_2-rs) [GUV-2](#guv-2) PoC

#### Recommendation

To ensure the passkey is genuine and from a verified source, you should:

- **Parse and Validate Client Data**: Ensure origin matches expected RP domain.
- **Validate rpIdHash**: Parse authenticator\_data; verify rpIdHash == SHA256(expected rpId).

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/pass-authenticators/issues/7) [GUV-2](#guv-2)

### GUV-3: Arbitrary Device Registration Through Missing Validation in Device Attestation

- Severity

  Medium

- Impact

  Severe

- Likelihood

  Rare

- Remediation Complexity

  Moderate

- Status

  Fixed

#### Description

The is\_valid method in the DeviceAttestation implementation always returns true, bypassing critical verification steps required for secure device registration in a WebAuthn-based system. This method is part of the DeviceChallengeResponse trait and is invoked during the Authenticator::verify\_device process, which handles new device attestations for user accounts. Normally, attestation verification should follow the WebAuthn Level 3 specification, including parsing the attestation object (CBOR-encoded with fields like fmt, attStmt, and authData), validating signatures against certificate chains, checking RP ID and origin bindings, and ensuring the authenticator's authenticity via AAGUID and FIDO Metadata. However, the current implementation skips all these checks.

is\_valid:authenticators/​webauthn/​src/​runtime/​attestation.rs

```
    impl<Cx> DeviceChallengeResponse<Cx> for Attestation<Cx> where     Cx: Parameter + Copy + 'static, {     // TODO: @pandres95, considering that DeviceChallengeResponse is used for creating a new     // authentication device, webauth_verify wouldn't work here. We need to implement a new     // verification method exclusively for credential creation.     fn is_valid(&self) -> bool {         true     }       fn used_challenge(&self) -> (Cx, Challenge) {         (self.meta.context, self.challenge())     }
```

#### Impact

- **Arbitrary Device Registration**: Attackers can register new accounts with malicious public keys, enabling front-running of legitimate users. For existing accounts, combined with phishing, it allows adding backdoor devices, leading to permanent unauthorized access and actions.
- **Phishing Amplification**: Weak attestation accepts cross-origin or fake attestations, making it easier to phish users into registering cloned/malicious devices.
- **Reputation and Compliance Risks**: Violates WebAuthn standards, exposing users to cloning/replay attacks.

#### Recommendation

- **Implement Full Attestation Verification**: Replace is\_valid = true with spec-compliant logic in DeviceChallengeResponse per this specification: https\://www\.w3.org/TR/webauthn-3/#sctn-registering-a-new-credential
- **Enhance Challenge Binding**: Use non-empty xtc in verify\_device to prevent precomputation.
- **Add Uniqueness and Limits**: Enforce unique devices per account; cap devices per account (e.g., via BoundedVec).

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/frame-contrib/issues/62) [GUV-3](#guv-3) Pallet Pass, [github.com](https://github.com/virto-network/pass-authenticators/issues/8) [GUV-3](#guv-3) Pass Authenticators

### GUV-4: Potential DoS and Resource Exhaustion Through Underestimated Benchmarks and Fixed Weights

- Severity

  Medium

- Impact

  Moderate

- Likelihood

  Possible

- Remediation Complexity

  Moderate

- Status

  Scheduled

#### Description

The benchmarks and weights in the pallet are not correctly configured to handle the variability introduced by WebAuthn-specific paths, particularly in functions like register and authenticate that involve parsing variable-sized fields such as client\_data (a Vec\<u8> containing JSON). The benchmarks rely on fixed-size, small inputs generated via BenchmarkHelper for SubstrateKey (sr25519-based) attestations, which are typically 100-200 bytes and do not exercise the WebAuthn variant. As a result, the weights are fixed and do not scale parametrically with input size.

#### Impact

- **Denial of Service (DoS) Vulnerability**: Attackers can submit extrinsics with large client\_data which are charged the same low fixed weight but incur high actual execution time and memory. This can exceed block production limits, cause node crashes, or fill blocks with resource-intensive transactions, disrupting network consensus.
- **Economic Exploitation**: Undercharged weights allow spamming without proportional gas fees, enabling cheap DoS attacks that waste validator resources (CPU, memory) while refunding minimal costs to the attacker.
- **Degraded Performance**: In production, unaccounted WebAuthn paths lead to slower block times or validation failures under load, especially if extensions inflate data sizes. This erodes pallet reliability for WebAuthn users.
- **Incomplete Security Model**: Fixed weights ignore adversarial inputs, potentially allowing griefing where large extrinsics pass validation but strain nodes, leading to operational costs and reduced scalability.

#### Recommendation

- **Update Benchmarks for Variability**: Revise benchmarks to include WebAuthn-specific paths with parametric inputs.
- **Implement Parametric Weights**: Calculate weights as base\_weight + per\_byte\_weight \* client\_data\_len, incorporating measured costs for decoding, parsing, and verification.
- **Add Input Bounds**: Enforce limits on Vec\<u8>fields (e.g., via BoundedVec\<u8, ConstU32<4096>>) to cap maximum sizes and prevent extreme cases.
- **Separate Paths in Benchmarks**: Benchmark SubstrateKey and WebAuthn variants independently to ensure accurate weights for each authenticator type.

#### Remediation

The Virto Network team has scheduled the fix of the issue: [github.com](https://github.com/virto-network/frame-contrib/issues/57) [GUV-4](#guv-4)

### GUV-5: Potential Out-of-Memory (OOM) and Degraded Performance Due to Inefficient Parsing

- Severity

  Medium

- Impact

  Moderate

- Likelihood

  Possible

- Remediation Complexity

  Moderate

- Status

  Fixed

#### Description

The find\_challenge\_from\_client\_data function (and related get\_from\_json\_then\_map) employs a simplistic, non-robust parsing approach for extracting keys like "challenge" from clientDataJSON (a Vec\<u8>). It converts the entire input to a string via String::from\_utf8 then performs O(n) operations like split and linear iteration with find\_map scanning substrings for matches. This allocates memory proportional to the input size (O(n)) and iterates in O(n) time worst-case, making it vulnerable to large or adversarial inputs.

find\_challenge\_from\_client\_data:src/​runtime/​helpers.rs

```
pub fn find_challenge_from_client_data(client_data: Vec<u8>) -> Option<Challenge> {     get_from_json_then_map(client_data, "challenge", |challenge| {         base64::decode_engine(challenge.as_bytes(), &BASE64_URL_SAFE_NO_PAD).ok()     }) } ... // get_from_json_then_map function declaration let json = String::from_utf8(json).ok()?;   let value = json     .split(",")     .find_map(|kv| kv.contains(key).then_some(kv.split_once(":")?.1))     .map(|v| v.trim_matches(|c: char| c.eq(&' ') || c.eq(&'"')))     .and_then(map)?;     ...
```

#### Impact

- **Out-of-Memory (OOM) Errors**: Large inputs during String::from\_utf8 or iteration can cause allocation failures, crashing the node or extrinsic execution, leading to failed transactions or consensus disruptions.
- **Degraded Performance and DoS**: O(n) time for huge JSON causes excessive CPU usage, slowing block validation/production and enabling cheap DoS by spamming large extrinsics that tie up resources without proportional weight charges.
- **Resource Exhaustion**: In validators, sustained large inputs consume memory/CPU, reducing throughput, increasing latency, or evicting other data, impacting overall network health and scalability.

#### Recommendation

- **Use Efficient Parsing**: Replace naive string operations with a proper JSON parser that validates structure, handles duplicates/escapes, and extracts keys without full buffering.
- **Implement Incremental Parsing**: Scan for keys without converting to a full string (e.g., byte-level searching), reducing memory to O(1) where possible.
- **Enforce Size Limits**: Bound client\_data (e.g., BoundedVec\<u8, ConstU32<8192>>) to a reasonable max based on WebAuthn specs, rejecting larger inputs early.
- **Add Early Validation**: Check UTF-8 validity and size before parsing; fail fast on anomalies to minimize resource use.

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/pass-authenticators/issues/9) [GUV-5](#guv-5)

### GUV-6: Silent or Unauthorized Authentication Through Missing Authenticator Flags Validation

- Severity

  Low

- Impact

  Negligible

- Likelihood

  Possible

- Remediation Complexity

  Simple

- Status

  Fixed

#### Description

No parsing/validation of authenticator\_data flags: UP (User Present), UV (User Verified), BE (Backup Eligible), BS (Backup State). Specs require UP (always), UV (if needed), and BE/BS consistency to ensure user interaction and detect backups/clones. Verifier ignores these, accepting silent auth.

#### Impact

- **Silent Auth Without Consent**: No UP/UV allows auth without touch/biometrics, enabling scripted attacks (e.g., malware on device).
- **Backup/Cloning Undetected**: No BE/BS checks fails to handle multi-device risks (e.g., insecure backups).
- **Security Downgrade**: Bypasses user verification, weakening passkey protection against physical access attacks.

Proof of concept: [gist.github.com](https://gist.github.com/guvenkaya-security-team/c053cc113557493c40b2b7e0264acb45#file-guv_6-rs) [GUV-6](#guv-6) PoC

#### Recommendation

- Follow flag verification per this specification: https\://www\.w3.org/TR/webauthn-3/#sctn-verifying-assertion

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/pass-authenticators/issues/10) [GUV-6](#guv-6)

### GUV-7: Possible Storage Bloating Due To Unbounded Devices and Session Keys Per User

- Severity

  Low

- Impact

  Negligible

- Likelihood

  Possible

- Remediation Complexity

  Simple

- Status

  Fixed

#### Description

No bounds on devices or session keys per user allow unlimited additions, leading to storage bloat. Costs exist (deposits via linear StoragePrice), but first device/session are free (FirstItemsFree), and privileged origins (Root/Communities) skip entirely (SkipConsideration). Attackers can loop registrations (pay per cycle) + free additions, orphaning data. Alternatively, a single account can add unlimited number of keys or devices.

#### Impact

- **Storage Bloat**: Unlimited devices and sessions per account can fill storage maps, increasing node costs and degrading performance.

#### Recommendation

- Introduce configurable limits, e.g., MaxDevicesPerAccount u32 = 5; MaxSessionsPerAccount u32 = 5. Check in extrinsics.

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/frame-contrib/issues/58) [GUV-7](#guv-7)

### GUV-8: Authentication Through Incorrect Credential Type

- Severity

  Low

- Impact

  Negligible

- Likelihood

  Possible

- Remediation Complexity

  Simple

- Status

  Fixed

#### Description

The verifier doesn't check the type field in client\_data JSON (must be "webauthn.get" for assertions per specs). It hashes client\_data without parsing, accepting any type (e.g., "webauthn.create" for registrations misused as assertions).

#### Impact

- **Type Confusion Attacks**: Allows "create" credentials (for registration) to auth as assertions, potentially creating invalid sessions or bypassing checks.
- **Compliance Issues**: Violates specs; may cause interop failures with clients enforcing types.

Proof of concept: [gist.github.com](https://gist.github.com/guvenkaya-security-team/c053cc113557493c40b2b7e0264acb45#file-guv_8-rs) [GUV-8](#guv-8) PoC

#### Recommendation

- **Parse Client Data Type**: Deserialize client\_data; ensure type == "webauthn.get".

#### Remediation

The Virto Network team has fixed the issue: [github.com](https://github.com/virto-network/pass-authenticators/issues/11) [GUV-8](#guv-8)

The web version and the [PDF](https://www.guvenkaya.co/reports/pdfs/virto.pdf) (18 pages) are generated from the same source. The [report as first delivered](https://github.com/Guvenkaya/public-reports/blob/master/legacy-design/Virto-Network-Pallet-Pass-Security-Review-Final-Report.pdf) is kept in the public reports archive.

## Table of Contents

- [Engagement Dashboard](#engagement-dashboard)
- [Advisory and Client](#advisory-and-client)
- [Scope and Review Boundaries](#scope-and-review-boundaries)
- [Assessment Framework](#assessment-framework)
- [Findings Summary](#findings-summary)
- [Detailed Findings](#detailed-findings)

## Share

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.guvenkaya.co%2Freports%2Fvirto\&text=Virto%20Network%3A%20Pallet%20Pass%20Security%20Review) [Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.guvenkaya.co%2Freports%2Fvirto) [Share on Threads](https://www.threads.net/intent/post?text=Virto%20Network%3A%20Pallet%20Pass%20Security%20Review%20https%3A%2F%2Fwww.guvenkaya.co%2Freports%2Fvirto)

[Discuss a security review](https://www.guvenkaya.co/contact?source=report) [View PDF on GitHub](https://github.com/Guvenkaya/public-reports/blob/master/Virto-Network-Pallet-Pass-Security-Review-Final-Report.pdf)

## Tell us what you need to secure.

Describe your system, main concern, and deadline. We’ll reply with scoping questions and a proposed next step.

[Discuss your scope](https://www.guvenkaya.co/contact?source=report)
