CR: netapi v0.4.0 Security Hardening

Change Summary

Change ID

CR-2026-03-25-netapi-security-hardening

Type

Security / Code Quality

Priority

P0 - Critical

Status

Completed

Requested

2026-03-25

Completed

2026-03-25

Owner

Evan Rosado

Background

After pushing netapi to GitHub, Dependabot identified 4 security vulnerabilities (2 HIGH, 1 MEDIUM, 1 LOW). As netapi is a "daily driver" P0 tool used for infrastructure automation, security vulnerabilities are unacceptable.

Additionally, the codebase lacked a unified exception hierarchy, making error handling inconsistent across 17+ vendor integrations.

Vulnerabilities Identified

Package Severity CVE Issue

cryptography ≤46.0.4

HIGH

GHSA-xxxx

SECT curve subgroup attack

pyasn1 ≤0.6.2

HIGH

GHSA-xxxx

DoS via unbounded recursion

requests <2.33.0

MEDIUM

GHSA-xxxx

Insecure temp file reuse

python-socketio <5.14.0

MEDIUM

GHSA-xxxx

RCE via pickle deserialization

Pygments ≤2.19.2

LOW

GHSA-xxxx

ReDoS (no patch available)

Implementation

Phase 1: Dependency Patching

Updated pyproject.toml with explicit version floors for vulnerable packages:

dependencies = [
    "requests>=2.33.0",           # CVE fix
    "cryptography>=46.0.5",       # CVE fix
    "pyasn1>=0.6.3",              # CVE fix
    "python-socketio>=5.14.0",    # CVE fix
    # ... other deps
]

Phase 2: genie/pyats Removal

Problem: Cisco genie/pyats pins pyasn1⇐0.6.2 which conflicts with the security fix.

Solution: Removed genie/pyats from the parsing extra entirely.

# CLI output parsing
parsing = [
    "textfsm>=1.1",
    "ntc-templates>=6.0",
    "ttp>=0.9",
]

# NOTE: Cisco pyATS/Genie removed due to unfixed CVEs (pyasn1, socketio)
# If needed, install separately: pip install genie pyats

Phase 3: Unified Exception Hierarchy

Created netapi.primitives.exceptions with vendor-aware base classes:

class NetapiError(Exception):
    """Base exception for all netapi errors."""
    vendor: str = "netapi"

class NetapiApiError(NetapiError):
    """HTTP API returned error (4xx, 5xx)."""
    status_code: int | None

class NetapiAuthError(NetapiError):
    """Authentication failed."""

class NetapiConnectionError(NetapiError):
    """Network unreachable."""

class NetapiNotFoundError(NetapiError):
    """Resource not found (404)."""

class NetapiRateLimitError(NetapiError):
    """Rate limit exceeded."""

class NetapiTimeoutError(NetapiError):
    """Request timeout."""

Phase 4: Vendor Exception Migration

Migrated vendor-specific exceptions to inherit from NetapiError:

Vendor Status Notes

pfSense

✅ Complete

PfSenseError(NetapiError)

WLC

✅ Complete

WlcError(NetapiError), WlcSshError(NetapiError)

GitHub

✅ Complete

GitHubError(NetapiError)

GitLab

✅ Complete

GitLabError(NetapiError)

Gitea

✅ Complete

GiteaError(NetapiError)

ISE

✅ Complete

8 clients: ERS, MnT, OpenAPI, pxGrid, SAML, Certs, Backup, DataConnect

Synology

✅ Complete

SynologyError(NetapiError)

Infoblox

✅ Complete

InfobloxError(NetapiError)

Keycloak

✅ Complete

KeycloakError(NetapiError)

KVM

✅ Complete

KvmError(NetapiError)

FMC

✅ Complete

FmcError(NetapiError)

ASA

✅ Complete

AsaError(NetapiError)

IOS-XE

✅ Complete

IosXeError(NetapiError), IosSshError(NetapiError)

Vault

N/A

No custom exceptions

Wazuh

N/A

No custom exceptions

Cloudflare

N/A

No custom exceptions

Phase 5: Bare Except Cleanup

Fixed bare except: clauses that swallow all exceptions:

File Fix

pfsense/client.py

except:except (ValueError, JSONDecodeError) with logging

mnt_client.py

except:except (ValueError, JSONDecodeError) with proper error propagation

Verification

# Regenerate lockfile
uv lock

# Verify patched versions installed
uv sync --extra all
uv pip list | grep -E "cryptography|pyasn1|requests|socketio"

# Verify exception hierarchy
python -c "from netapi.primitives.exceptions import NetapiError; print('OK')"

# Test vendor exceptions inherit correctly
python -c "
from netapi.vendors.github import GitHubError
from netapi.primitives.exceptions import NetapiError
assert issubclass(GitHubError, NetapiError)
print('OK')
"

Breaking Changes

Change Migration Path

genie/pyats removed from parsing extra

Install separately: pip install genie pyats (accepts security risk)

Files Modified

  • pyproject.toml - Dependency versions, removed genie/pyats

  • uv.lock - Regenerated with patched versions

  • netapi/primitives/exceptions.py - New unified hierarchy

  • netapi/vendors/pfsense/client.py - Bare except fix, inherit NetapiError

  • netapi/vendors/cisco/wlc/ssh_client.py - Inherit NetapiError

  • netapi/vendors/github/client.py - Inherit NetapiError

  • netapi/vendors/gitlab/client.py - Inherit NetapiError

  • netapi/vendors/gitea/client.py - Inherit NetapiError

  • netapi/vendors/cisco/ise/exceptions.py - NEW: Shared ISE exception hierarchy

  • netapi/vendors/cisco/ise/ers_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/mnt_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/openapi_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/pxgrid_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/saml_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/certs_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/backup_client.py - Import from shared exceptions

  • netapi/vendors/cisco/ise/dataconnect_client.py - Import from shared exceptions

  • netapi/vendors/cisco/firewall/asa_client.py - Inherit NetapiError

  • netapi/vendors/cisco/firewall/fmc_client.py - Inherit NetapiError

  • netapi/vendors/cisco/ios/client.py - Inherit NetapiError

  • netapi/vendors/cisco/ios/ssh_client.py - Inherit NetapiError

  • netapi/vendors/infoblox/client.py - Inherit NetapiError

  • netapi/vendors/keycloak/client.py - Inherit NetapiError

  • netapi/vendors/kvm/client.py - Inherit NetapiError

  • netapi/vendors/synology/client.py - Inherit NetapiError

Commits

Repository Commit

netapi

fix(security): Patch 4 Dependabot vulnerabilities

netapi

refactor: Migrate all vendor exceptions to unified NetapiError hierarchy

domus-captures

docs(netapi): v0.4.0 security fixes, 18 vendors, exception hierarchy

domus-netapi-docs

docs(changelog): Add v0.4.0 security fixes and exception hierarchy

Remaining Work

  1. ✅ Complete vendor exception migration (17/17 complete)

  2. Add unit tests for exception hierarchy

  3. Consider direnv for auto uv sync

Changelog

Date Author Change

2026-03-25

Evan Rosado

Initial CR created, security fixes completed

2026-03-25

Evan Rosado

All vendor exceptions migrated to NetapiError hierarchy (17/17)