VYPR
Medium severity5.5OSV Advisory· Published Sep 9, 2025· Updated Apr 15, 2026

CVE-2025-59036

CVE-2025-59036

Description

Infrahub offers a central hub to manage data, templates, and playbooks. Prior to versiond 1.3.9 and 1.4.5, a bug in the authentication logic will cause API tokens that were deleted and/or expired to be considered valid. This means that any API token that is associated with an active user account can authenticate successfully. This issue is fixed in versions 1.3.9 and 1.4.5. As a workaround, users can delete or deactivate the account associated with a deleted API token to prevent that token from authenticating.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
infrahub-serverPyPI
< 1.3.91.3.9
infrahub-serverPyPI
>= 1.4.0, < 1.4.51.4.5

Affected products

1

Patches

3
215185f217e2

prep release 1.3.9 (#7177)

https://github.com/opsmill/infrahubAaron McCartySep 8, 2025via ghsa
7 files changed · +151 37
  • backend/infrahub/core/account.py+60 34 modified
    @@ -5,9 +5,10 @@
     
     from typing_extensions import Self
     
    -from infrahub.core.constants import InfrahubKind, PermissionDecision
    +from infrahub.core.constants import NULL_VALUE, InfrahubKind, PermissionDecision
     from infrahub.core.query import Query, QueryType
     from infrahub.core.registry import registry
    +from infrahub.core.timestamp import Timestamp
     
     if TYPE_CHECKING:
         from infrahub.core.branch import Branch
    @@ -519,47 +520,72 @@ def __init__(self, token: str, **kwargs: Any):
             super().__init__(**kwargs)
     
         async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:  # noqa: ARG002
    -        token_filter_perms, token_params = self.branch.get_query_filter_relationships(
    -            rel_labels=["r1", "r2"], at=self.at, include_outside_parentheses=True
    +        branch_filter, branch_params = self.branch.get_query_filter_path(
    +            at=self.at.to_string(), branch_agnostic=self.branch_agnostic, is_isolated=False
             )
    -        self.params.update(token_params)
    -
    -        account_filter_perms, account_params = self.branch.get_query_filter_relationships(
    -            rel_labels=["r31", "r41", "r5", "r6"], at=self.at, include_outside_parentheses=True
    +        self.params.update(branch_params)
    +        self.params.update(
    +            {
    +                "token_attr_name": "token",
    +                "token_relationship_name": "account__token",
    +                "token_value": self.token,
    +                "null_value": NULL_VALUE,
    +            }
             )
    -        self.params.update(account_params)
     
    -        self.params["token_value"] = self.token
    -
    -        # ruff: noqa: E501
             query = """
    -        MATCH (at:InternalAccountToken)-[r1:HAS_ATTRIBUTE]-(a:Attribute {name: "token"})-[r2:HAS_VALUE]-(av:AttributeValue { value: $token_value })
    -        WHERE %s
    -        WITH at
    -        MATCH (at)-[r31]-(:Relationship)-[r41]-(acc:CoreGenericAccount)-[r5:HAS_ATTRIBUTE]-(an:Attribute {name: "name"})-[r6:HAS_VALUE]-(av:AttributeValue)
    -        WHERE %s
    -        """ % (
    -            "\n AND ".join(token_filter_perms),
    -            "\n AND ".join(account_filter_perms),
    -        )
    -
    +// --------------
    +// get the active token node for this token value, if it exists
    +// --------------
    +MATCH (token_node:%(token_node_kind)s)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: $token_attr_name})
    +    -[r2:HAS_VALUE]->(av:AttributeValue { value: $token_value })
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH token_node
    +WHERE r1.status = "active" AND r2.status = "active"
    +// --------------
    +// get the expiration time
    +// --------------
    +OPTIONAL MATCH (token_node)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: "expiration"})
    +    -[r2:HAS_VALUE]->(av)
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH token_node, CASE
    +    WHEN r1.status = "active" AND r2.status = "active" AND av.value <> $null_value THEN av.value
    +    ELSE NULL
    +END AS expiration
    +// --------------
    +// get the linked account node from the token node
    +// --------------
    +MATCH (token_node)-[r1:IS_RELATED]-(:Relationship {name: $token_relationship_name})-[r2:IS_RELATED]-(account_node:%(account_node_kind)s)
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH expiration, account_node
    +WHERE r1.status = "active" AND r2.status = "active"
    +        """ % {
    +            "branch_filter": branch_filter,
    +            "token_node_kind": InfrahubKind.ACCOUNTTOKEN,
    +            "account_node_kind": InfrahubKind.GENERICACCOUNT,
    +        }
             self.add_to_query(query)
    -
    -        self.return_labels = ["at", "av", "acc"]
    -
    -    def get_account_name(self) -> str | None:
    -        """Return the account name that matched the query or None."""
    -        if result := self.get_result():
    -            return result.get("av").get("value")
    -
    -        return None
    +        self.return_labels = ["account_node.uuid AS account_uuid", "expiration"]
     
         def get_account_id(self) -> str | None:
             """Return the account id that matched the query or a None."""
    -        if result := self.get_result():
    -            return result.get("acc").get("uuid")
    -
    -        return None
    +        result = self.get_result()
    +        if not result:
    +            return None
    +        account_uuid = result.get_as_str(label="account_uuid")
    +        expiration_with_tz = result.get_as_str(label="expiration")
    +        if expiration_with_tz is None:
    +            return account_uuid
    +        expiration = Timestamp(expiration_with_tz)
    +        if expiration < Timestamp():
    +            return None
    +        return account_uuid
     
     
     async def validate_token(token: str, db: InfrahubDatabase, branch: Branch | str | None = None) -> str | None:
    
  • backend/tests/unit/core/test_account.py+58 0 modified
    @@ -1,9 +1,13 @@
     import pytest
    +from infrahub_sdk.timestamp import Timestamp
    +from pytz import timezone
     
     from infrahub.auth import authenticate_with_password, authentication_token, validate_active_account
     from infrahub.core import registry
     from infrahub.core.account import validate_token
     from infrahub.core.constants import InfrahubKind
    +from infrahub.core.initialization import create_branch
    +from infrahub.core.manager import NodeManager
     from infrahub.core.node import Node
     from infrahub.database import InfrahubDatabase
     from infrahub.exceptions import AuthorizationError
    @@ -29,13 +33,67 @@ async def test_validate_token(db: InfrahubDatabase, default_branch, register_cor
         user1 = await Node.init(db=db, schema=account_schema)
         await user1.new(db=db, name="user1", password="User1Password123")
         await user1.save(db=db)
    +    user2 = await Node.init(db=db, schema=account_schema)
    +    await user2.new(db=db, name="user2", password="User2Password234")
    +    await user2.save(db=db)
         token1 = await Node.init(db=db, schema=account_token_schema)
         await token1.new(db=db, token="123456789", account=user1)
         await token1.save(db=db)
     
         assert await validate_token(token="123456789", db=db) == user1.id
         assert await validate_token(token="987654321", db=db) is None
     
    +    # with future expiration
    +    right_now = Timestamp()
    +    future = right_now.add(minutes=1)
    +    token1.expiration.value = future.to_string()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123456789", db=db) == user1.id
    +
    +    branch = await create_branch(db=db, branch_name="token_branch")
    +
    +    # test with updated account
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    await token1.account.update(db=db, data=user2)
    +    await token1.save(db=db)
    +    assert await validate_token(token="123456789", db=db, branch=branch) == user2.id
    +
    +    # test updated token value
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    token1.token.value = "123454321"
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) == user2.id
    +    assert await validate_token(token="123456789", db=db, branch=branch) is None
    +
    +    # test updated past expiration
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    past = right_now.add(minutes=-1)
    +    token1.expiration.value = past.to_string()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) is None
    +
    +    # test updated past expiration with tz
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    past = right_now.add(minutes=-1)
    +    # UTC-7
    +    past_with_tz = past.to_datetime().astimezone(timezone("US/Pacific"))
    +    token1.expiration.value = past_with_tz.isoformat()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) is None
    +
    +    # test updated future expiration with tz
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    future = right_now.add(minutes=1)
    +    # UTC+9
    +    future_with_tz = future.to_datetime().astimezone(timezone("Asia/Tokyo"))
    +    token1.expiration.value = future_with_tz.isoformat()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) == user2.id
    +
    +    # test delete works
    +    await token1.delete(db=db)
    +    assert await validate_token(token="123454321", db=db) is None
    +
     
     async def test_account_status(db: InfrahubDatabase, default_branch, register_core_models_schema):
         account_schema = registry.schema.get_node_schema(name=InfrahubKind.ACCOUNT, branch=default_branch)
    
  • CHANGELOG.md+6 0 modified
    @@ -11,6 +11,12 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang
     
     <!-- towncrier release notes start -->
     
    +## [Infrahub - v1.3.9](https://github.com/opsmill/infrahub/tree/infrahub-v1.3.9) - 2025-08-26
    +
    +### Security
    +
    +- Fixes bug in authentication logic that allowed expired and/or deleted API tokens to authenticate successfully.
    +
     ## [Infrahub - v1.3.8](https://github.com/opsmill/infrahub/tree/infrahub-v1.3.8) - 2025-08-26
     
     ### Fixed
    
  • docs/docs/release-notes/infrahub/release-1_3_9.mdx+23 0 added
    @@ -0,0 +1,23 @@
    +---
    +title: Release 1.3.9
    +---
    +<table>
    +  <tbody>
    +    <tr>
    +      <th>Release Number</th>
    +      <td>1.3.9</td>
    +    </tr>
    +    <tr>
    +      <th>Release Date</th>
    +      <td>September 8th, 2025</td>
    +    </tr>
    +    <tr>
    +      <th>Tag</th>
    +      <td>[infrahub-v1.3.9](https://github.com/opsmill/infrahub/releases/tag/infrahub-v1.3.9)</td>
    +    </tr>
    +  </tbody>
    +</table>
    +
    +### Security
    +
    +- Fixes bug in authentication logic that allowed expired and/or deleted API tokens to authenticate successfully.
    
  • docs/sidebars.ts+1 0 modified
    @@ -386,6 +386,7 @@ const sidebars: SidebarsConfig = {
                 slug: 'release-notes/infrahub',
               },
               items: [
    +            'release-notes/infrahub/release-1_3_9',
                 'release-notes/infrahub/release-1_3_7',
                 'release-notes/infrahub/release-1_3_6',
                 'release-notes/infrahub/release-1_3_5',
    
  • pyproject.toml+1 1 modified
    @@ -1,6 +1,6 @@
     [tool.poetry]
     name = "infrahub-server"
    -version = "1.3.8"
    +version = "1.3.9"
     description = "Infrahub is taking a new approach to Infrastructure Management by providing a new generation of datastore to organize and control all the data that defines how an infrastructure should run."
     authors = ["OpsMill <info@opsmill.com>"]
     readme = "README.md"
    
  • python_testcontainers/pyproject.toml+2 2 modified
    @@ -1,11 +1,11 @@
     [project]
     name = "infrahub-testcontainers"
    -version = "1.3.8"
    +version = "1.3.9"
     requires-python = ">=3.9"
     
     [tool.poetry]
     name = "infrahub-testcontainers"
    -version = "1.3.8"
    +version = "1.3.9"
     description = "Testcontainers instance for Infrahub to easily build integration tests"
     authors = ["OpsMill <info@opsmill.com>"]
     readme = "README.md"
    
50928dc3c15e

chore: update docker-compose

https://github.com/opsmill/infrahubopsmill-botSep 8, 2025via osv
1 file changed · +3 3
  • docker-compose.yml+3 3 modified
    @@ -199,7 +199,7 @@ services:
           - 6362:6362
     
       task-manager:
    -    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.4}"
    +    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.5}"
         command: uvicorn --host 0.0.0.0 --port 4200 --factory infrahub.prefect_server.app:create_infrahub_prefect
         restart: unless-stopped
         depends_on:
    @@ -232,7 +232,7 @@ services:
           retries: 5
     
       infrahub-server:
    -    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.4}"
    +    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.5}"
         restart: unless-stopped
         command: >
           gunicorn --config backend/infrahub/serve/gunicorn_config.py
    @@ -278,7 +278,7 @@ services:
         deploy:
           mode: replicated
           replicas: 2
    -    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.4}"
    +    image: "${INFRAHUB_DOCKER_IMAGE:-registry.opsmill.io/opsmill/infrahub}:${VERSION:-1.4.5}"
         command: prefect worker start --type infrahubasync --pool infrahub-worker --with-healthcheck
         restart: unless-stopped
         depends_on:
    
61b49a4a9e98

update AccountTokenValidatorQuery (#7160)

https://github.com/opsmill/infrahubAaron McCartySep 8, 2025via ghsa
2 files changed · +118 34
  • backend/infrahub/core/account.py+60 34 modified
    @@ -5,9 +5,10 @@
     
     from typing_extensions import Self
     
    -from infrahub.core.constants import InfrahubKind, PermissionDecision
    +from infrahub.core.constants import NULL_VALUE, InfrahubKind, PermissionDecision
     from infrahub.core.query import Query, QueryType
     from infrahub.core.registry import registry
    +from infrahub.core.timestamp import Timestamp
     
     if TYPE_CHECKING:
         from infrahub.core.branch import Branch
    @@ -519,47 +520,72 @@ def __init__(self, token: str, **kwargs: Any):
             super().__init__(**kwargs)
     
         async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:  # noqa: ARG002
    -        token_filter_perms, token_params = self.branch.get_query_filter_relationships(
    -            rel_labels=["r1", "r2"], at=self.at, include_outside_parentheses=True
    +        branch_filter, branch_params = self.branch.get_query_filter_path(
    +            at=self.at.to_string(), branch_agnostic=self.branch_agnostic, is_isolated=False
             )
    -        self.params.update(token_params)
    -
    -        account_filter_perms, account_params = self.branch.get_query_filter_relationships(
    -            rel_labels=["r31", "r41", "r5", "r6"], at=self.at, include_outside_parentheses=True
    +        self.params.update(branch_params)
    +        self.params.update(
    +            {
    +                "token_attr_name": "token",
    +                "token_relationship_name": "account__token",
    +                "token_value": self.token,
    +                "null_value": NULL_VALUE,
    +            }
             )
    -        self.params.update(account_params)
     
    -        self.params["token_value"] = self.token
    -
    -        # ruff: noqa: E501
             query = """
    -        MATCH (at:InternalAccountToken)-[r1:HAS_ATTRIBUTE]-(a:Attribute {name: "token"})-[r2:HAS_VALUE]-(av:AttributeValue { value: $token_value })
    -        WHERE %s
    -        WITH at
    -        MATCH (at)-[r31]-(:Relationship)-[r41]-(acc:CoreGenericAccount)-[r5:HAS_ATTRIBUTE]-(an:Attribute {name: "name"})-[r6:HAS_VALUE]-(av:AttributeValue)
    -        WHERE %s
    -        """ % (
    -            "\n AND ".join(token_filter_perms),
    -            "\n AND ".join(account_filter_perms),
    -        )
    -
    +// --------------
    +// get the active token node for this token value, if it exists
    +// --------------
    +MATCH (token_node:%(token_node_kind)s)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: $token_attr_name})
    +    -[r2:HAS_VALUE]->(av:AttributeValueIndexed { value: $token_value })
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH token_node
    +WHERE r1.status = "active" AND r2.status = "active"
    +// --------------
    +// get the expiration time
    +// --------------
    +OPTIONAL MATCH (token_node)-[r1:HAS_ATTRIBUTE]->(:Attribute {name: "expiration"})
    +    -[r2:HAS_VALUE]->(av)
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH token_node, CASE
    +    WHEN r1.status = "active" AND r2.status = "active" AND av.value <> $null_value THEN av.value
    +    ELSE NULL
    +END AS expiration
    +// --------------
    +// get the linked account node from the token node
    +// --------------
    +MATCH (token_node)-[r1:IS_RELATED]-(:Relationship {name: $token_relationship_name})-[r2:IS_RELATED]-(account_node:%(account_node_kind)s)
    +WHERE all(r in [r1, r2] WHERE (%(branch_filter)s))
    +ORDER BY r1.branch_level DESC, r1.from DESC, r1.status ASC, r2.branch_level DESC, r2.from DESC, r2.status ASC
    +LIMIT 1
    +WITH expiration, account_node
    +WHERE r1.status = "active" AND r2.status = "active"
    +        """ % {
    +            "branch_filter": branch_filter,
    +            "token_node_kind": InfrahubKind.ACCOUNTTOKEN,
    +            "account_node_kind": InfrahubKind.GENERICACCOUNT,
    +        }
             self.add_to_query(query)
    -
    -        self.return_labels = ["at", "av", "acc"]
    -
    -    def get_account_name(self) -> str | None:
    -        """Return the account name that matched the query or None."""
    -        if result := self.get_result():
    -            return result.get("av").get("value")
    -
    -        return None
    +        self.return_labels = ["account_node.uuid AS account_uuid", "expiration"]
     
         def get_account_id(self) -> str | None:
             """Return the account id that matched the query or a None."""
    -        if result := self.get_result():
    -            return result.get("acc").get("uuid")
    -
    -        return None
    +        result = self.get_result()
    +        if not result:
    +            return None
    +        account_uuid = result.get_as_str(label="account_uuid")
    +        expiration_with_tz = result.get_as_str(label="expiration")
    +        if expiration_with_tz is None:
    +            return account_uuid
    +        expiration = Timestamp(expiration_with_tz)
    +        if expiration < Timestamp():
    +            return None
    +        return account_uuid
     
     
     async def validate_token(token: str, db: InfrahubDatabase, branch: Branch | str | None = None) -> str | None:
    
  • backend/tests/unit/core/test_account.py+58 0 modified
    @@ -1,9 +1,13 @@
     import pytest
    +from infrahub_sdk.timestamp import Timestamp
    +from pytz import timezone
     
     from infrahub.auth import authenticate_with_password, authentication_token, validate_active_account
     from infrahub.core import registry
     from infrahub.core.account import validate_token
     from infrahub.core.constants import InfrahubKind
    +from infrahub.core.initialization import create_branch
    +from infrahub.core.manager import NodeManager
     from infrahub.core.node import Node
     from infrahub.database import InfrahubDatabase
     from infrahub.exceptions import AuthorizationError
    @@ -29,13 +33,67 @@ async def test_validate_token(db: InfrahubDatabase, default_branch, register_cor
         user1 = await Node.init(db=db, schema=account_schema)
         await user1.new(db=db, name="user1", password="User1Password123")
         await user1.save(db=db)
    +    user2 = await Node.init(db=db, schema=account_schema)
    +    await user2.new(db=db, name="user2", password="User2Password234")
    +    await user2.save(db=db)
         token1 = await Node.init(db=db, schema=account_token_schema)
         await token1.new(db=db, token="123456789", account=user1)
         await token1.save(db=db)
     
         assert await validate_token(token="123456789", db=db) == user1.id
         assert await validate_token(token="987654321", db=db) is None
     
    +    # with future expiration
    +    right_now = Timestamp()
    +    future = right_now.add(minutes=1)
    +    token1.expiration.value = future.to_string()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123456789", db=db) == user1.id
    +
    +    branch = await create_branch(db=db, branch_name="token_branch")
    +
    +    # test with updated account
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    await token1.account.update(db=db, data=user2)
    +    await token1.save(db=db)
    +    assert await validate_token(token="123456789", db=db, branch=branch) == user2.id
    +
    +    # test updated token value
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    token1.token.value = "123454321"
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) == user2.id
    +    assert await validate_token(token="123456789", db=db, branch=branch) is None
    +
    +    # test updated past expiration
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    past = right_now.add(minutes=-1)
    +    token1.expiration.value = past.to_string()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) is None
    +
    +    # test updated past expiration with tz
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    past = right_now.add(minutes=-1)
    +    # UTC-7
    +    past_with_tz = past.to_datetime().astimezone(timezone("US/Pacific"))
    +    token1.expiration.value = past_with_tz.isoformat()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) is None
    +
    +    # test updated future expiration with tz
    +    token1 = await NodeManager.get_one(db=db, branch=branch, id=token1.id)
    +    future = right_now.add(minutes=1)
    +    # UTC+9
    +    future_with_tz = future.to_datetime().astimezone(timezone("Asia/Tokyo"))
    +    token1.expiration.value = future_with_tz.isoformat()
    +    await token1.save(db=db)
    +    assert await validate_token(token="123454321", db=db, branch=branch) == user2.id
    +
    +    # test delete works
    +    await token1.delete(db=db)
    +    assert await validate_token(token="123454321", db=db) is None
    +
     
     async def test_account_status(db: InfrahubDatabase, default_branch, register_core_models_schema):
         account_schema = registry.schema.get_node_schema(name=InfrahubKind.ACCOUNT, branch=default_branch)
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.