Skip to content

Security: Add Content-Security-Policy and validate update download URLs #201

@techmore

Description

@techmore

Type

security

Severity

medium

Area

nmapui/handlers/updates.py, templates/index.html

Description

Two related defense-in-depth issues:

1. No Content-Security-Policy header

The Flask app serves HTML without any CSP header. All JavaScript, including from CDN sources (lucide), executes without restriction. Combined with any innerHTML usage, this widens the XSS attack surface.

2. Update download URL not validated

perform_app_update opens download_url via subprocess.run(["open", str(download_url)]) where the URL comes from the GitHub releases API. If the update endpoint were compromised or DNS-hijacked, open could be used to launch arbitrary URL schemes (file://, ssh://, etc.).

Proposed Fix

CSP: Add a restrictive Content-Security-Policy header:

@app.after_request
def add_security_headers(response):
    response.headers["Content-Security-Policy"] = (
        "default-src 'self'; "
        "script-src 'self' https://unpkg.com; "
        "style-src 'self' 'unsafe-inline' https://unpkg.com https://fonts.googleapis.com; "
        "font-src https://fonts.gstatic.com; "
        "connect-src 'self' ws://127.0.0.1:* ws://localhost:*; "
        "img-src 'self' data:;"
    )
    return response

Update URL: Validate the URL origin before opening:

if not download_url.startswith("https://github.com/"):
    return {"success": False, "error": "Untrusted download URL"}

Related Issues

#164 (Security hardening initiative)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecuritySecurity vulnerability or concern

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions