AI 资讯
Building a security posture scanner with Next.js and Python
I wanted to learn cloud security the way it actually sticks: by building something real. So I built PostureGuard, a web application that scans a domain and returns a security posture report covering TLS, HTTP security headers and open ports, with a 0-100 score and an A-F grade. This post walks through the architecture and the decisions I found most interesting. Update: Phase 1 is done. PostureGuard now runs on Azure Container Apps and is live at app.samdossou.com . The write-up is the next post in this series. The shape of the system PostureGuard has three moving parts: A Next.js web app (App Router, TypeScript) where users sign up, add a domain, and request scans. A PostgreSQL database that stores users, domains and scans. A Python worker that runs the actual scans in the background. The web app never runs a scan itself. When a user clicks "Scan", the app just inserts a row into a scans table with the status queued and returns immediately. The worker picks the job up a moment later. This keeps the request fast and the two halves of the system decoupled. Using PostgreSQL as a job queue The part I like most is that there is no separate message broker. The scans table doubles as the queue. The worker claims one job at a time with a single query: SELECT s . id , d . name FROM scans s JOIN domains d ON d . id = s . domain_id WHERE s . status = 'queued' ORDER BY s . requested_at FOR UPDATE OF s SKIP LOCKED LIMIT 1 FOR UPDATE locks the row so no one else can grab it, and SKIP LOCKED tells other workers to ignore locked rows and move on to the next job. That means I can run several workers in parallel and they will never process the same scan twice, without any extra infrastructure. For a project at this scale, a table plus SKIP LOCKED is simpler and more than enough. The scanners The worker runs three checks, all built on the Python standard library to keep dependencies light: TLS: it opens a TLS connection, reads the certificate expiry and the negotiated protocol version
AI 资讯
Who’s legally to blame for Anthropic and OpenAI’s autonomous AI hacks? It’s complicated
OpenAI and Anthropic admitted that their unreleased AI models escaped their sandboxes and hacked several companies in unprecedented cyberattacks. Who is legally to blame? Should prosecutors charge the two AI frontier labs? Can victims sue them? We spoke to lawyers who specialize in computer hacking laws to find out.
开发者
Apple challenges UK government’s latest demand for iCloud backdoor: report
Apple has appealed a new legal demand by the U.K. government, which critics say could threaten the privacy rights of users all over the world.
开发者
Sellar un archivo para que nadie pueda discutir que no lo tocaste
Una discusión sobre un archivo digital casi nunca se pierde por lo que el archivo dice. Se pierde una pregunta antes: ¿Cómo sabemos que ese es el archivo que usted recibió, y no el que editó anoche? Si la respuesta es "confíe en mí", ya perdiste. Y da igual cuánta razón tengas en el fondo. Este problema no es exclusivo de un juzgado. Lo tiene el auditor que recibe un volcado de logs, el equipo que documenta un incidente, quien conserva la copia de un contrato firmado por correo. En todos los casos hace falta lo mismo: poder demostrar que un conjunto de bytes no cambió desde un momento determinado, y que lo demuestre alguien que no seas tú . Para eso escribí Tunjo : una herramienta en Rust que recorre un material en solo lectura, calcula su huella y firma un acta verificable por cualquiera. Por qué un árbol y no un hash Lo obvio sería concatenar todo y sacar un SHA-256. Funciona, y es inútil en la práctica. Cuando alguien discute un archivo —un correo concreto entre cuatro mil— con un hash único solo puedes ofrecer dos cosas: o entregas el conjunto completo para que se recalcule, o pides que te crean. La primera opción expone material que no tiene por qué exponerse; la segunda no es una prueba. Un árbol de Merkle resuelve exactamente eso. Cada archivo es una hoja, cada par de nodos se combina hacia arriba y queda una raíz. Para demostrar que una hoja pertenece a esa raíz basta con exhibir esa hoja y el camino de hashes hasta arriba: unos pocos kilobytes. El resto del conjunto no se toca. Dos detalles del árbol que no son opcionales: // Separación de dominio: una hoja nunca puede hacerse pasar por nodo interno. h . update ([ 0x00 ]); // hoja h . update ([ 0x01 ]); // nodo interno // Y la raíz ata el número de hojas. h . update ([ 0x02 ]); h . update ( n . to_be_bytes ()); Sin lo primero, un hash de hoja podría presentarse como si fuera un nodo del árbol. Sin lo segundo aparece la ambigüedad clásica de los árboles con número impar de hojas: dos conjuntos distintos pued
AI 资讯
It refused to run a dangerous option. I wrote it one character shorter, and it ran
GitPython ships a guard against dangerous git options. If your code builds a clone command out of anything that arrived from outside, the library will not let --upload-pack or --config through by default, because both of them execute an arbitrary command. The guard is on out of the box and turns off only with an explicit allow_unsafe_options=True . I handed it --upload-pack=/srv/lab/helper.sh . It refused. I handed it the same thing written differently, -u/srv/lab/helper.sh , and it let it through. The script ran. This is CVE-2026-67324, published on 1 August 2026, scored 9.8 on CVSS 3.1 and 9.3 on CVSS 4.0. Those numbers still come from the CNA that filed it: NVD has not run its own analysis yet, the record sits in status Received, so the score may move. Version 3.1.50 is vulnerable, 3.1.51 is fixed. Below, step by step: the lab, both attempts with real output, the code of the check and why it missed, and what the attack looks like from the outside. Plus the part I find more interesting than the hole itself. This is the third bypass of the same barrier within one year, and all three share a root cause. Why this deserves your attention Almost nobody installs GitPython on purpose. It gets 254 million downloads a month from PyPI against five thousand stars on GitHub, and a two-order gap like that means one thing: it arrives as a passenger. With MLflow, with DVC, with bandit, with semgrep, with half the homegrown scripts that touch repositories in CI. Let me draw the boundary right away, so nobody panics for nothing. Having it installed is harmless on its own. The hole fires only when two conditions hold at the same time: your code calls Repo.clone_from(..., multi_options=[...]) , something an outsider influences ends up inside multi_options . The second one happens more often than it sounds. A repository URL from a web form, build parameters from a config another team edits, a field in a CI job, arguments from a webhook. And if you are leaning on allow_unsafe_options=
AI 资讯
The black box in your PDF is a shape, not a delete key
There are two ways to black out a name in a PDF. The first deletes the text and then draws a black rectangle where it used to be. The second just draws the black rectangle. On screen they are indistinguishable. In the file they are entirely different documents, and in the second one every character of the name is still there — selectable, copyable, and extractable by any PDF library in about one line of code. This mistake keeps reaching production in court filings, FOIA releases and regulatory submissions, from organisations that employ lawyers and document teams. It survives not because people are careless but because there is no feedback : the person doing the redacting sees a black box either way, and nothing tells them which one they made until somebody else selects the text. A PDF page is a program The reason the two operations look the same is worth understanding, because it is also the reason you can tell them apart. A page's content stream is a sequence of operators executed in order onto a blank canvas. A very small one looks like this: BT /F1 12 Tf 76 660 Td (Dana Whitfield) Tj ET 0 0 0 rg 74 656 120 16 re f Reading it out: begin text, select font F1 at 12pt, move to (76, 660), show the string Dana Whitfield , end text. Then set the non-stroking colour to black ( rg ), build a rectangle at (74, 656) 120 wide and 16 high ( re ), and fill it ( f ). There is no z-index here, and no concept of one object being "above" another. There is only order. Later paints over earlier. The rectangle covers the name for the same reason a second coat of paint covers the first. Now swap the two halves: 0 0 0 rg 74 656 120 16 re f BT /F1 12 Tf 76 660 Td (Dana Whitfield) Tj ET Same objects, same coordinates, opposite order — and now the name is drawn on top of the black box and is perfectly legible. Which is exactly what a table's shaded header row is: a filled rectangle, painted first, with text on it. That single fact is the whole of what follows. Check it yourself in one li
AI 资讯
We’re Giving AI Agents More Tools. What Happens When the Boundaries Fail?
📌 TL;DR AI agents are becoming useful because we're giving them the ability to do more than just answer questions. They can run commands, browse the web, use APIs, read and modify files, install packages, and interact with other systems. But the more an agent can do, the more the boundaries around it matter. I started thinking about this after reading Anthropic's July 30 report about three incidents discovered during its cybersecurity evaluations. Claude models were supposed to be working inside simulated environments and were explicitly told they had no internet access. Except internet access was actually available because of a problem with how the evaluation environment was configured. While trying to complete their assigned cybersecurity exercises, the models reached real systems and initially treated them as part of the simulation. In one incident, a Claude model even published a malicious Python package to the real PyPI registry while believing it was still operating inside the exercise. This came shortly after a separate OpenAI incident involving Hugging Face. The two stories might sound similar at first, but the models reached the real internet in importantly different ways. And that brings this back to a pretty familiar software engineering idea: A prompt is not a security boundary. Telling an agent “you don't have internet access” isn't the same as actually removing internet access. Telling it “only use these files” isn't the same as restricting its permissions to those files. The model is also only one part of the system. The tools we connect, the permissions and credentials we give it, the environment it runs in, and the monitoring and safeguards around it can all affect what happens. So when something goes wrong, I don't think it's enough to stop at “the AI did it.” The model's behavior matters, but so do the systems and boundaries we build around it. As we give agents more ability to act, we also have to be thoughtful about what we're actually allowing
AI 资讯
JWT Authentication: A Backend Engineer's Mental Model
Introduction Imagine you arrive at a hotel. At the reception, you show your ID and prove who you are. The receptionist then gives you a room key card. You don't need to show your ID every time you enter your room. Instead, you simply present the key card. The hotel doesn't need to ask your name again because the card itself proves that you already authenticated. JWT (JSON Web Token) works exactly like that. Username and password = Your ID JWT = Hotel key card Server = Receptionist What is JWT? JWT stands for JSON Web Token . It is a compact string that proves a user has already logged in successfully. Instead of storing login sessions on the server, the server gives the client a signed token. The client sends this token with every request. Example: Authorization: Bearer eyJhbGciOiJIUzI1NiIs... The server verifies the token and allows access. Why Do We Need JWT? Without JWT, every request would require sending the username and password repeatedly. Browser | Username Password | Server That would be inefficient and insecure. Instead: Login once ↓ Receive JWT ↓ Reuse JWT for every request Stateless Authentication JWT enables stateless authentication . Stateful Authentication Server | |-- Session #12345 |-- Session #91821 |-- Session #44211 The server stores every user's session. Stateless Authentication (JWT) Server (No session storage) ↓ Only verifies token signature The server doesn't remember users. The token remembers. JWT Structure A JWT consists of three parts separated by periods. Header.Payload.Signature Example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxMjMiLCJuYW1lIjoiRXZhbnMiLCJyb2xlIjoiYWRtaW4ifQ . K6L6GQX.... Think of it like Envelope Letter Wax Seal Part 1 — Header Example { "alg" : "HS256" , "typ" : "JWT" } The header tells us: Which algorithm signed the token. What type of token it is. Fields: alg → Signing algorithm typ → JWT Common algorithms: HS256 RS256 ES256 Part 2 — Payload The payload contains claims . Example: { "user_id" : 42 , "name" :
AI 资讯
Horizon3 hits $2 billion valuation with $250M Series E as AI threats escalate
Cybersecurity startup Horizon3 raised $250 million at a $2 billion valuation as companies want continuous, AI-powered security validation instead of annual pentesting.
AI 资讯
Google’s Gemini AI fixes 1,072 Chrome bugs in 60 days – How it happened
TL;DR: Google’s Gemini AI agents identified and helped remediate 1,072 Chrome security flaws in 60 days, dramatically shrinking the window for attackers. The race to protect 3.5 billion Chrome users has taken a high‑tech shortcut. Instead of relying solely on human researchers, Google deployed its Gemini‑powered AI agents to hunt for bugs, triage findings, and even suggest patches. The result? Over a thousand vulnerabilities squashed in just two months—a pace that would have taken years using traditional methods. How Gemini’s AI Agents Accelerated Chrome’s Bug Hunt Google’s internal security team integrated Gemini, the company’s latest large‑language‑model platform, into its vulnerability‑scanning pipeline. The AI agents performed three core tasks: Automated code analysis – By ingesting Chrome’s massive codebase, the models flagged risky patterns, unsafe API calls, and legacy modules that often hide bugs. Prioritization and risk scoring – Gemini assigned a severity score to each finding, allowing engineers to focus on exploits with the highest potential impact. Patch drafting assistance – For many low‑complexity issues, the AI generated candidate code changes, which senior engineers then reviewed and merged. The system worked in a loop: the AI scanned, reported, received feedback, and refined its heuristics. This iterative approach cut the average time‑to‑detect from weeks to hours and reduced manual triage effort by an estimated 40 %. The Scale and Impact of Fixing 1,072 Vulnerabilities During the 60‑day sprint, the AI‑augmented process uncovered 1,072 distinct security bugs across Chrome’s rendering engine, JavaScript runtime, and networking stack. Roughly half were classified as “high‑severity,” meaning they could have enabled remote code execution or data exfiltration. Key outcomes include: Reduced exposure window – The median time between bug discovery and patch release dropped from 45 days (historical average) to under 7 days. Broad coverage – The AI identifie
开发者
Cómo solucionar el error “Enable JavaScript and cookies to continue”
Cómo solucionar el error “Enable JavaScript and cookies to continue” Este error aparece cuando Cloudflare (u otro proxy inverso de seguridad) detecta que el navegador del usuario no cumple con los requisitos mínimos para acceder al sitio: JavaScript está deshabilitado o las cookies no están permitidas . Pero en entornos reales, el problema suele ser más sutil: el navegador sí tiene JS y cookies habilitados, pero la configuración del entorno de ejecución (como un headless browser, test automation, o un scraper) no emula correctamente el comportamiento del cliente . 🔍 Causa raíz técnica Cloudflare emite un desafío (CAPTCHA o JS challenge) para verificar que el cliente es un navegador real. Si la respuesta no cumple con el desafío (por ejemplo, porque: El navegador no ejecuta el JS del desafío (headless sin soporte), Las cookies no se persisten entre solicitudes, El User-Agent o Accept-Language no coinciden con navegadores reales, Falta el Referer o Origin en headers, Se bloquean cookies de terceros (como las de Cloudflare), … entonces el servidor devuelve este mensaje estático en lugar de redirigir a la página solicitada. ⚠️ Nota crítica : Si estás usando herramientas como curl , requests de Python, o navegadores headless sin configuración especial, no pasarás el desafío de Cloudflare . Es intencional: Cloudflare bloquea tráfico no humano por diseño. ✅ Solución definitiva (por escenario) 🛠️ Caso 1: Navegador real (usuario final) Verifica que JavaScript esté habilitado : Chrome: Configuración → Privacidad y seguridad → Configuración de sitios → JavaScript → Permitido . Firefox: Preferencias → Privacidad y seguridad → Cookies y datos de sitios → Deshabilitar “Bloquear cookies y datos de sitios” . Limpia cookies y caché (especialmente para *.cloudflare.com ). Reinicia el navegador y vuelve a cargar la página. 🛠️ Caso 2: Automatización / Scraping (Python + Playwright/Selenium) No uses requests o urllib : no ejecutan JS. Usa un navegador real con soporte para Cloudflare. ✅
安全
Samsung bans smart TV apps that share users’ internet connections with strangers
New security research offers a rare view inside residential proxy networks, which rely on apps that share a person's internet connection with someone else.
AI 资讯
HashiCorp Ships Public Beta of Vault Kubernetes Key Management
HashiCorp has released a public beta of Vault Kubernetes key management, a KMS v2-compatible plugin that lets the Kubernetes API server delegate envelope encryption to Vault Enterprise, moving the key encryption keys that protect etcd data out of the cluster and into a separately governed trust domain. By Mark Silvester
AI 资讯
We crossed 6,000 downloads. Here's what we shipped to get there.
Tuesday morning. Your SOC 2 auditor emails you. "Can you provide evidence of human review for all AI-assisted code changes in the last 90 days — which files were modified, what prompts were used, and whether any credentials were visible in context?" You open your IDE. Git log? Commits are there. PR history? Reviews too. But the AI session itself — the conversation, the code it proposed, whether it saw your .env file, which compliance controls it touched — gone. That gap is why I built Chron. What Chron is Chron is an MCP server that runs alongside your AI coding tool. Every message, every code change, every detected secret — locally timestamped, hash-chained, and stored in a SQLite database you own. No cloud. No data sharing. Works offline. # Install once npm install -g chron-mcp # Check setup chron doctor Works with Claude Code, Cursor, Windsurf, Continue.dev — any MCP-compatible tool. The last four releases: answers to questions auditors actually ask v0.1.39 — "Which sessions are worth reviewing first?" $ chron risk --since = 30d SESSION SCORE BAND SIGNALS a1b2c3d4 87 critical secrets·auth·infra e5f6g7h8 52 high auth·findings ( 2 ) i9j0k1l2 28 review code_changes The attention score: deterministic 0–100 per session. No ML, no API calls. Pure signal from what actually happened: secrets detected (+25), auth code changed (+15), infra modified (+12), open compliance findings (+8 each). A security lead can triage 90 days of AI sessions in under a minute. v0.1.40 — "Can I get a one-pager for this audit?" $ chron dashboard --since = 30d --output = q3-audit.html ✓ Written: q3-audit.html 8 sessions · 4 open findings · 1 critical · 2 high Coverage: 6 controls covered · 3 needs evidence Five sections in a single static HTML file — no server, no login, no port: executive summary, sessions ranked by risk score, findings grouped by framework (SOC 2 / ISO 27001 / EU AI Act / NIST AI RMF), a control coverage map, and contextual next actions. Open in a browser. Print to PDF. Attac
AI 资讯
The ‘Guardrail Guy’ Went Viral for Posting About Flock Cameras. Then Someone Destroyed Them
Steve Elmers, also known as the “Guardrail Guy,” is done calling out license plate readers after two that appeared in his videos were vandalized.
AI 资讯
Cracking WMI-exec in Rust by turning impacket into a byte-level oracle
How I implemented wmiexec from scratch in Rust — DCOM activation, OXID resolution, and MS-WMIO object marshaling — by using impacket not as a library but as a debugging oracle, and diffing my wire bytes against it until a Windows DC accepted them byte-for-byte. This is a build log from ADhammer, an Active Directory audit + validation toolkit I'm writing in Rust on a from-scratch DCE/RPC · NTLM · SMB2 · Kerberos stack (think "impacket for Rust"). The whole project is built with Claude Code, and this post is the single best example of what that actually looks like — not autocomplete, but a tight loop of hypothesis → capture live traffic → diff → fix against a real domain controller. The goal: wmiexec, from scratch wmiexec is the classic "quiet" remote-code-execution technique: instead of creating a service (psexec/SVCCTL) or a scheduled task (atexec), you talk to WMI over DCOM and call Win32_Process.Create. No service-install event, different host telemetry. Under the hood it's three stages, each a different flavour of pain:
AI 资讯
Approval Is Not a Boolean: What Must Still Be True When an Agent Resumes?
Human approval is a decision about one action under a particular set of facts. It is not a permanent permission bit. Imagine an AI agent preparing a refund request: Order: SO-1001 Amount: CNY 199.00 Reason: Duplicate payment The runtime classifies the action as high risk, pauses the task, and asks a human to approve the exact request. At 10:00, the approver reviews the parameters and clicks Approve . The task does not execute immediately. It remains paused, waits in a queue, survives a coordinator restart, and finally reaches dispatch at 15:00. During those five hours, any of the following may have changed: the order may already have been refunded by another channel; the refund policy may now require an additional finance review; the approver may no longer hold the required role; the acting subject may have left the organization; the amount or currency may have drifted during task reconstruction; the tool implementation may have changed; the approval may have been valid for only 30 minutes. Should the system execute merely because a database row still says approved = true ? No. The approval was not a timeless grant. It was a decision about a specific action, represented by a specific subject, using a specific capability, with specific arguments, under a specific policy and set of business facts. This distinction becomes essential when agents move beyond answering questions and begin creating real business consequences. 1. The dangerous simplification: approval = true In conventional administrative software, approval and execution are often close together. A user submits a form, a manager approves it, and the system performs the action soon afterward. That interaction encourages a simplified mental model: approval = true Once that value is stored, downstream code treats the action as permanently authorized. Agent tasks are different. A single task may cross several asynchronous boundaries: understand intent -> select a capability -> construct arguments -> request app
AI 资讯
CORS Errors Explained: Every Fix, Every Framework (2026 Guide)
CORS Errors Explained: Every Fix, Every Framework (2026 Guide) TL;DR — A CORS error means the browser blocked a cross-origin request because the server did not explicitly allow it. The fix is always server-side : return the correct Access-Control-Allow-Origin header from your backend. This guide covers every CORS error type, a step-by-step diagnosis flow, and copy-paste fixes for Express, FastAPI, Next.js, nginx, Cloudflare Workers, and Vercel. You can inspect and validate your CORS headers live with the CORS Header Checker — no curl, no Postman, no install. What CORS Actually Is (and Why the Browser Enforces It) The Same-Origin Policy (SOP) is a browser security rule: JavaScript running on https://myapp.com can only read responses from requests made to the same origin — same scheme, same host, same port. Everything else is cross-origin. CORS — Cross-Origin Resource Sharing — is the mechanism that lets servers selectively relax the Same-Origin Policy. A server adds HTTP headers to its responses that tell the browser: "it is okay to share this response with code from origin X." Without those headers, the browser reads the response, then silently discards it and throws a CORS error into your console. Three things to burn into memory before you read further: CORS is enforced by the browser, not the server. curl and Postman do not check CORS — they always get the response. Only browsers do CORS. If your API works in Postman but fails in the browser, CORS is almost certainly why. The fix is server-side, always. Browser extensions that "disable CORS" are masking the problem in your local browser only. They break for every real user. Never ship code that depends on them. Preflight is a separate request. For non-simple requests (anything with a custom header, a JSON body, or methods other than GET/POST), the browser sends an OPTIONS request first to ask for permission. Your server must handle this correctly. The Four CORS Error Types — Diagnosed from the Console Message Err
AI 资讯
COLDCARD Predictable RNG: From Seed Recovery to About $8.86M Bitcoin Theft
COLDCARD Predictable RNG: From Seed Recovery to About $8.86M Bitcoin Theft 1. Basic Information Article Title : COLDCARD wallet RNG flaw likely linked to $88 million Bitcoin theft Source : BleepingComputer Publication Date : August 2, 2026 Severity : Urgent Original Link : https://www.bleepingcomputer.com/news/security/coldcard-wallet-rng-flaw-likely-linked-to-88-million-bitcoin-theft/ Related Sources : Block Engineering "Predictable RNG Fallback and 32-Bit Reseed in COLDCARD Firmware": https://engineering.block.xyz/blog/predictable-rng-fallback-and-32-bit-reseed-in-coldcard-firmware Coinkite "Coldcard Security Advisory": https://blog.coinkite.com/coldcard-mk3-seed-generation-warning/ Related Malware / Threat Actors : Unknown. The attack may not require malware or phishing. CVE : None assigned at the time of publication Related Products : COLDCARD Mk2/Mk3 4.0.0–4.1.9, Mk4/Mk5 below fixed versions, Q below fixed versions. TAPSIGNER, OPENDIME, and SATSCARD are considered unaffected. Relation to Real Exploitation : Strongly suspected to be linked to the theft of a total of 1,367 BTC (approx. $88.6 million at the time of reporting) observed between July 30 and August 1, 2026. However, cryptographic or investigative confirmation of the attacker exploiting the vulnerability has not been officially established. 2. Executive Summary Due to a conditional branching error in the COLDCARD firmware, wallet seed randomness became deterministic or fell into a narrow candidate space. This may have allowed attackers to use public Bitcoin addresses as a verification oracle to offline-reproduce seeds and private keys, moving funds without ever breaking into the physical devices. 3. Attack Flow Chain A: Fund Theft from Existing Wallets (Chain Suspected to be Linked to Real Damage) A user generates a new seed, paper wallet, or related key material on an affected firmware version. The firmware uses the MicroPython Yasmarang fallback instead of the hardware RNG where it should use it. On
AI 资讯
Crypto-Agility Without a Redesign: The "Soft-Fade-Out" Pattern for Legacy IoT Silicon
Most conversations about CRA, DORA, and NIS2 compliance for IoT hardware boil down to one uncomfortable binary: redesign the board around newer, security-capable silicon, or accept that your existing product line falls out of compliance on a fixed deadline. For a product with years left in its lifecycle and a BOM that took months to qualify, "just redesign it" is rarely a real answer. There's a third option that gets far less attention than it deserves: pair the legacy chip with a modern security co-chip that absorbs the cryptographic boundary, while the legacy part keeps doing exactly what it already does well - application logic, peripherals, display, sensor polling. Call it a soft fade-out. The old silicon stays in service until its natural end-of-life; the compliance gap gets closed by a second, much cheaper part sitting next to it, not by replacing it. The Three Gaps a Legacy Chip Has - and Why a Co-Chip Fixes Them The regulatory pressure driving all of this isn't abstract. NIST finalized its post-quantum cryptography standards in 2024, and IR 8547 sets real dates: ECDSA and RSA are deprecated after 2030, disallowed after 2035. Germany's BSI has gone further - TR-02102-1 (2026 edition) sets a stricter 2030 deadline for high-protection-need data, and treats the migration as "alternativlos" (without alternative) rather than a recommendation. Older embedded silicon typically lacks three things simultaneously: a hardware-isolated key store (TEE/APM), side-channel countermeasures (DPA protection) strong enough for physical-access threat models, and enough RAM/compute headroom to run lattice-based PQC algorithms in software without starving the rest of the firmware. Redesigning the whole board to fix all three at once is expensive and slow. But none of those three gaps require touching the part that's already doing its job - they're all boundary problems. A second, purpose-built chip can own the boundary. Three concrete pairings Using the ESP32 family as a worked exa