Skip to content
IoT Security — Device Authentication, Secure Boot, TLS, and OWASP IoT Top 10 Explained

IoT Security — Device Authentication, Secure Boot, TLS, and OWASP IoT Top 10 Explained

DodaTech Updated Jun 15, 2026 6 min read

IoT security is the practice of protecting internet-connected devices and the networks they connect to from unauthorized access, data breaches, and malicious exploitation, addressing unique challenges posed by resource-constrained hardware.

Why IoT Security Matters

In 2016, the Mirai botnet infected 600,000 IoT devices using default passwords and launched the largest DDoS attack in history (1.2 Tbps). In 2020, a casino’s smart fish tank thermometer was hacked to exfiltrate data to Finland. By 2026, there are 30+ billion IoT devices, and many lack basic security. A compromised IoT device isn’t just a privacy risk — it’s a physical safety risk when the device controls a pacemaker, a car’s brakes, or a factory’s safety systems. Industrial IoT environments face especially severe consequences from security failures.

Plain-Language Explanation

Imagine 30 billion houses where most owners never lock their doors, use “1234” as the alarm code, and leave the windows wide open. That’s the current state of IoT security. The doors are default passwords, the windows are unencrypted communication, and the unlocked back gate is missing firmware updates.

Securing an IoT device is harder than securing a smartphone because:

  • Limited resources: No room for antivirus, complex encryption, or frequent updates
  • Physical access: Devices sit in homes, factories, and streets — anyone can touch them
  • No human in the loop: Devices run unattended for years
  • Heterogeneity: Thousands of different chips, OSes, and protocols

graph TD
    subgraph "IoT Attack Surface"
        Device[Device Hardware
JTAG, UART, Flash] Network[Network
WiFi, BLE, Zigbee] Cloud[Cloud API
AWS, Azure] App[Mobile/Web App] end subgraph "Security Controls" SB[Secure Boot] EE[Encrypted Storage] TLS[TLS / DTLS] Auth[Device Auth
Certificates] FU[Firmware Updates
Signed + Encrypted] end Device --> SB Device --> EE Network --> TLS Cloud --> Auth Device --> FU style Device fill:#e74c3c,color:#fff style Network fill:#e67e22,color:#fff style Cloud fill:#3498db,color:#fff style App fill:#9b59b6,color:#fff

OWASP IoT Top 10 (2026)

  1. Weak, guessable, or hardcoded passwords: Default credentials like admin/admin or root/root. Fix: force password change on first use, enforce complexity.

  2. Insecure network services: Unnecessary open ports (Telnet, FTP). Fix: disable unused services, use firewall rules.

  3. Insecure ecosystem interfaces: Web and cloud APIs without authentication. Fix: require API keys, rate limit, validate input.

  4. Lack of secure update mechanism: Firmware updates delivered over HTTP without signatures. Fix: sign updates, deliver over HTTPS, verify before install.

  5. Use of insecure or outdated components: Old Linux kernels, patched libraries. Fix: BOM (bill of materials) tracking, automated vulnerability scanning.

  6. Insufficient privacy protection: Excessive data collection, no encryption at rest. Fix: collect minimum data, encrypt at rest.

  7. Insecure data transfer and storage: Data in plaintext over the network. Fix: TLS 1.3 for all communication, encrypt stored credentials.

  8. Lack of device management: No centralized monitoring or decommissioning. Fix: device registry, decommissioning process.

  9. Insecure default settings: Debug interfaces enabled in production. Fix: disable debug/UART/JTAG in production builds.

  10. Lack of physical hardening: Accessible debug ports, removable flash. Fix: epoxy potting, tamper sensors, secure element chips.

TLS in Constrained Devices

TLS 1.3 handshake requires significant resources. For ESP32-class devices:

// ESP32 secure MQTT with TLS
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient);

void setup() {
  // Load certificate from PROGMEM (flash memory)
  wifiClient.setCACert(ca_cert);       // CA certificate
  wifiClient.setCertificate(client_cert); // Device certificate
  wifiClient.setPrivateKey(client_key);   // Private key

  mqttClient.setServer("mqtts.example.com", 8883);
  mqttClient.connect("device-001");
}

For devices that can’t handle TLS, use DTLS for UDP-based protocols (CoAP + DTLS).

Device Authentication

Pre-shared keys (PSK): Simple but hard to rotate at scale. Each device gets a unique key.

X.509 certificates: Industry standard. Each device has a certificate signed by a trusted CA. Used by AWS IoT Core and Azure IoT Hub.

Hardware security module (HSM) / TPM: Dedicated chip stores private keys. Keys never leave the hardware, immune to software attacks.

Secure Boot and Signed Firmware

# Sign firmware binary with private key
openssl dgst -sha256 -sign private.pem -out firmware.bin.sig firmware.bin

# Device verifies signature against public key in boot ROM
# If verification fails, device refuses to boot

Secure Firmware Update Flow

# update_server.py
import hashlib, hmac

FIRMWARE_KEY = b"your-secret-key"

def generate_update(url: str, version: str) -> dict:
    manifest = {
        "version": version,
        "url": url,
        "hash_algorithm": "sha256",
    }
    # Create signature
    message = f"{version}:{url}".encode()
    manifest["signature"] = hmac.new(FIRMWARE_KEY, message, hashlib.sha256).hexdigest()
    return manifest

# Device side verification
def verify_update(manifest: dict):
    expected_sig = manifest["signature"]
    message = f"{manifest['version']}:{manifest['url']}".encode()
    computed = hmac.new(FIRMWARE_KEY, message, hashlib.sha256).hexdigest()
    if hmac.compare_digest(expected_sig, computed):
        print("Signature valid — applying update")
        # Download and flash firmware
    else:
        print("Signature INVALID — rejecting update")

Common Mistakes

  1. Default credentials: Most IoT hacks start with admin/admin. Require password change on first boot.

  2. No encryption: Sending sensor data in plaintext over WiFi. Anyone on the network can read it. Always use TLS/DTLS.

  3. No update mechanism: Devices shipped with known vulnerabilities and no way to patch. Plan OTA updates from day one.

  4. Overprivileged firmware: If a light bulb doesn’t need internet access, don’t give it internet access. Network segmentation limits blast radius.

  5. Physical debug ports left enabled: UART, JTAG, and SWD debug interfaces expose full device access. Disable or physically remove in production.

Practice Questions

  1. What is the OWASP IoT Top 10? A list of the 10 most critical security risks for IoT systems, including weak passwords, insecure network services, lack of secure updates, and privacy concerns.

  2. Why is TLS challenging on constrained devices? TLS handshake requires significant CPU and memory. ESP32-class devices can handle TLS 1.3 with optimized libraries, but 8-bit microcontrollers may need DTLS or hardware acceleration.

  3. How do X.509 certificates improve IoT security? Each device has a unique certificate signed by a trusted CA. The cloud verifies the certificate to authenticate the device. Compromising one device doesn’t compromise others.

  4. What is secure boot? The boot ROM verifies the firmware signature before executing it. If the firmware is tampered with, the device refuses to boot. Prevents persistent malware.

  5. How does network segmentation help IoT security? IoT devices are isolated on a separate VLAN from critical systems. If a smart light bulb is compromised, the attacker can’t reach the file server or database.

Mini Project

Build a Python tool to check for common IoT security issues:

import socket, ssl, hashlib

def check_device_security(host: str, port: int):
    issues = []

    # Check for default credentials
    try:
        test_credentials = [("admin", "admin"), ("root", "root"), ("admin", "1234")]
        for user, pwd in test_credentials:
            # Simulated check — in practice, try HTTP/SSH login
            print(f"  Testing {user}:{pwd}...")
    except:
        pass

    # Check if TLS is available
    try:
        context = ssl.create_default_context()
        with socket.create_connection((host, 8883), timeout=5) as sock:
            with context.wrap_socket(sock, server_hostname=host) as tls:
                cert = tls.getpeercert()
                print(f"  TLS enabled: {cert.get('subject', [])}")
    except:
        issues.append("No TLS on port 8883")

    # Check open ports (common insecure ports)
    insecure_ports = {23: "Telnet", 21: "FTP", 161: "SNMP"}
    for port_num, name in insecure_ports.items():
        try:
            with socket.create_connection((host, port_num), timeout=3):
                issues.append(f"{name} (port {port_num}) is open")
        except:
            pass

    if issues:
        print(f"\nSecurity issues found for {host}:{port}:")
        for issue in issues:
            print(f"  - {issue}")
    else:
        print(f"{host}:{port} passed basic checks")

check_device_security("192.168.1.100", 80)
check_device_security("192.168.1.101", 443)

Cross-References

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro