Skip to content

Pickachu19/USBGuard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

USBGuard

A lightweight Flask dashboard for discovering connected USB devices, flagging vendor IDs on a local watchlist, recording device activity, and controlling USB storage access on Windows and Linux.

Warning

This project can disable USB devices or unload the Linux usb_storage kernel module when it starts. Review the security and safety notes before running it on a primary machine.

Python Flask License

Overview

USBGuard provides a browser-based view of USB devices connected to the host computer. The application:

  • Discovers USB devices with PowerShell on Windows and lsusb on Linux.
  • Extracts vendor IDs from the operating-system output.
  • Compares those IDs with a configurable watchlist.
  • Records device scans and watchlist matches in usb.log.
  • Encrypts the activity log with AES-256 through GnuPG after every ten logged events.
  • Provides an administrator unlock page that attempts to re-enable USB access.

This repository is a learning and prototype project. It is not related to, or a replacement for, the upstream Linux USBGuard daemon.

Application preview

Screenshot coming soon. Recommended path: docs/images/usbguard-dashboard.png.

Features

Cross-platform device discovery

Platform Discovery method Control method
Windows Get-WmiObject and Get-PnpDevice Enable-PnpDevice / Disable-PnpDevice
Linux lsusb Load or unload the usb_storage kernel module with modprobe

The Windows scanner filters common internal components such as root hubs, host controllers, composite devices, and USB input devices. The Linux scanner reads the standard lsusb output.

Vendor watchlist

The app extracts the four-character USB vendor ID and compares it with MALICIOUS_VENDORS in app.py. Matching devices appear in the dashboard response and activity log.

Important

A vendor ID identifies a manufacturer, not whether an individual device is malicious. A match is a signal for manual review, not proof of compromise.

Activity logging and encryption

Opening the dashboard records:

  • The scan timestamp.
  • The raw operating-system device output.
  • Any matching vendor IDs and device descriptions.

After ten events, encrypt.py uses python-gnupg to create usb.log.gpg with AES-256 symmetric encryption. The plaintext log is removed only when encryption succeeds.

Administrator unlock

The /unlock page checks the submitted password and attempts to enable USB access:

  • Windows enables the selected PnP devices.
  • Linux loads the usb_storage module.

How it works

Browser request
      |
      v
Flask route in app.py
      |
      +--> Query connected devices
      |      |
      |      +--> Windows PowerShell
      |      `--> Linux lsusb
      |
      +--> Extract and compare vendor IDs
      |
      +--> Append the scan to usb.log
      |      |
      |      `--> Encrypt every 10 events
      |
      `--> Render the dashboard

Project structure

USBGuard/
├── app.py            # Flask app, USB discovery, controls, routes, and logging
├── encrypt.py        # GnuPG setup and symmetric log encryption
├── requirements.txt  # Pinned Python dependencies
├── LICENSE           # MIT license
├── usb.log           # Plaintext runtime activity log
└── usb.log.gpg       # Encrypted log output

Flask also expects the following templates at runtime:

templates/
├── index.html        # Main device dashboard
└── unlock.html       # Administrator password form

If these template files are not present in your checkout, Flask will raise TemplateNotFound when you open the corresponding page.

Prerequisites

All platforms

  • Python 3.9 or newer.
  • GnuPG available as gpg.
  • Permission to inspect and manage USB devices.

Windows

  • Windows PowerShell.
  • The Get-PnpDevice, Enable-PnpDevice, and Disable-PnpDevice commands.
  • An elevated terminal for device state changes.

Linux

  • usbutils for lsusb.
  • kmod for modprobe.
  • sudo access for loading and unloading usb_storage.

On Ubuntu or Debian:

sudo apt update
sudo apt install python3 python3-venv gnupg usbutils kmod

Installation

  1. Clone the repository:

    git clone https://github.com/Pickachu19/USBGuard.git
    cd USBGuard
  2. Create and activate a virtual environment:

    Linux or macOS

    python3 -m venv .venv
    source .venv/bin/activate

    Windows PowerShell

    py -m venv .venv
    .\.venv\Scripts\Activate.ps1
  3. Install the dependencies:

    python -m pip install --upgrade pip
    python -m pip install -r requirements.txt

Configuration

The current prototype keeps its settings near the top of app.py.

Change the administrator password

Replace the default before running the app:

ADMIN_PASSWORD = "use-a-long-unique-password"

The repository default is usbdetector. Do not expose the server to another machine while using that password.

Edit the vendor watchlist

Add or remove lowercase, four-character USB vendor IDs:

MALICIOUS_VENDORS = {
    "0c45",
    "1d34",
    # Add reviewed vendor IDs here.
}

Change the encryption passphrase

encrypt.py currently uses a hardcoded passphrase. Replace it with a strong, unique value before storing real device data. For a production-quality design, load it from a protected environment variable or secret store instead of committing it to source control.

Running the application

Caution

Starting app.py immediately calls disable_usb_ports(). On Linux, that runs sudo modprobe -r usb_storage. On Windows, it attempts to disable filtered USB PnP devices. Disconnect unneeded storage, save open work, and use a test machine.

Start the Flask development server:

python app.py

Then open:

http://127.0.0.1:5000

The development server binds to 0.0.0.0:5000 and runs with debug mode enabled in the current source. Use host firewall rules and a trusted network.

Main workflow

  1. Open the dashboard to scan connected USB devices.
  2. Review any entries listed as malicious or suspicious.
  3. Check usb.log for timestamped scan details.
  4. Visit /unlock and enter the administrator password when USB access should be restored.
  5. Refresh device data through /update_devices.

HTTP routes

Route Methods Purpose
/ GET Scan devices, log the event, and render the dashboard
/unlock GET, POST Display the password form and attempt to enable USB access
/update_devices GET Return the latest scan as JSON

Example response from /update_devices:

{
  "devices": "raw operating-system output",
  "malicious": [],
  "timestamp": "2026-07-24 12:00:00",
  "device_count": 0,
  "malicious_count": 0
}

Security and safety notes

Before using USBGuard outside a lab, account for these limitations:

  • The Flask development server and debug mode are not suitable for production.
  • The app binds to every network interface by default.
  • The administrator password and encryption passphrase are hardcoded.
  • Password verification has no rate limiting, session management, or CSRF protection.
  • Vendor-ID matching can produce both false positives and false negatives.
  • USB device control requires elevated operating-system privileges.
  • Disabling a driver can interrupt mounted storage and cause data loss.
  • Runtime logs may contain device names and hardware identifiers.
  • The repository currently contains generated log files; review their contents before sharing a fork.

For real deployment, move secrets to environment variables, disable Flask debug mode, bind to localhost, add authentication protections, avoid running the web process as an administrator, and delegate privileged operations to a narrowly scoped system service.

Troubleshooting

TemplateNotFound: index.html

The Flask templates are missing. Add templates/index.html and templates/unlock.html using the structure shown above.

lsusb: not found

Install usbutils:

sudo apt install usbutils

PowerShell returns no devices

Open an elevated PowerShell window and verify:

Get-PnpDevice | Where-Object { $_.Class -eq 'USB' }

The application intentionally filters several internal and input-device categories.

modprobe reports permission errors

Run from an account with the required sudo permission. Avoid granting unrestricted passwordless administrator access to the Flask process.

GnuPG encryption does not create usb.log.gpg

Confirm that GnuPG is installed and visible:

gpg --version

Also verify that the process can read usb.log and write to the project directory.

The dashboard reports an incorrect device count

The current endpoint estimates the count from newline formatting in the raw command output. Windows PowerShell versions and device types may format results differently.

Development

There is no automated test suite in the current repository. Before submitting changes:

  1. Run the app on the platform you changed.
  2. Verify /, /unlock, and /update_devices.
  3. Test with no external devices and with multiple devices.
  4. Confirm that log encryption succeeds without deleting plaintext on failure.
  5. Check that internal USB controllers and input devices are not disabled.

Contributing

Issues and pull requests are welcome. Keep changes focused, explain platform-specific behavior, and include manual verification steps for Windows and Linux when applicable.

License

USBGuard is available under the MIT License.

About

A lightweight Flask-based security dashboard for monitoring USB devices, detecting watchlisted vendors, logging device activity, and controlling USB storage access across Windows and Linux.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages