Security Assumptions Are Broken, Web Platform Gets Smarter, and the shadcn Ecosystem Grows Up
Published on 29.05.2026
Security by Obscurity Is Dead. Now What?
TLDR: AI has fundamentally lowered the cost of finding and exploiting software vulnerabilities, making the old "we're not a target" reasoning obsolete. The GitHub breach via a poisoned VS Code extension, the Trivy CI/CD supply chain attack, and research showing thousands of critical CVEs found by AI models in a single month are concrete evidence of a new threat landscape. The practical response is not panic but architectural discipline.
Summary: There's a thought experiment worth sitting with. Imagine your company's entire source code became public tomorrow. Not because of carelessness, exactly, but because one developer installed one VS Code extension that was malicious for eighteen minutes before anyone noticed. That's what happened to GitHub in May 2026. This is GitHub, owned by Microsoft, with mature MDM, endpoint detection, and more security engineering than almost any company in the world. Eighteen minutes was enough to exfiltrate around 3,800 internal repositories.
The author of this piece makes a point that stings a bit because it's true: most teams have been running security theater for years. Dependency scanners, a semi-annual penetration test because customers asked, a badge in the sales deck. That was enough when actually understanding an unfamiliar codebase took weeks of skilled human work. It's not enough now. A capable language model can read a codebase, model the system, identify authentication paths, find the tenant isolation gap nobody reviewed, and build a targeted exploit in hours. The economics of attack have flipped.
The Trivy incident drives this home from a different angle. Trivy is a security scanner, a tool teams use to feel safer, and version tags in its GitHub Action were force-pushed to credential-stealing malware. CI/CD pipelines, which tend to hold source code, deployment tokens, cloud access keys, and secrets for half the internal stack, became the attack surface. The CanisterWorm incident followed the same pattern: stolen npm tokens from compromised pipelines, backdoored packages published at install time. These aren't exotic nation-state attacks. They're supply-chain moves that anyone with patience and tooling can run.
The CVE feed as a primary security signal is also running out of steam. VulnCheck found that in the first half of 2025, over 32% of exploited vulnerabilities had exploitation evidence on or before the day the CVE was even issued. NIST enriched nearly 42,000 CVEs in 2025, more than any prior year, and still said it wasn't enough to keep pace. In April 2026, NIST moved to a risk-based enrichment model where some CVEs are listed but not immediately analyzed. "Patch faster" is not a coherent strategy when your own system's specific quirks, the forgotten GraphQL resolver, the retry path that isn't idempotent, the internal endpoint nobody documented, won't appear in any CVE feed at all.
The author's prescription lands somewhere practical rather than catastrophist: assume your source code has already leaked, treat CI/CD as a high-value attack surface, pin dependencies to commit SHAs rather than mutable tags, keep secrets short-lived, and design architecture that limits what one bug can expose. The checklist point deserves more credit than it usually gets. Not glamorous process for its own sake, but the kind that forces developers to actually ask what happens when the downstream service writes but the load balancer times out before a response comes back. Those are the bugs that don't come from clever attacks. They come from questions nobody thought to ask.
Key takeaways:
- Assume your source code has already been exfiltrated; build architecture that limits the blast radius rather than relying on obscurity
- CI/CD pipelines are high-value attack targets; pin actions to commit SHAs, treat anything executing code in your build environment as part of the product
- CVE feeds can no longer be the center of a security process; you need a model of your own system's specific risks, not just public vulnerability feeds
Why do I care: This one cuts close for frontend teams who often consider security someone else's problem. Supply chain attacks through VS Code extensions and poisoned GitHub Actions hit developers directly, and CI/CD pipelines are as much frontend infrastructure as backend. The architectural advice about limiting blast radius and making secrets short-lived applies to any team running deployments. The insight I'd push back on slightly is the tool pitch at the end: the checklist-driven approach is sound, but any given SaaS automating it is optional. The underlying discipline isn't.
Death of Security by Obscurity
April 2026 Baseline Digest: New CSS and JS Features You Can Actually Use
TLDR: The April 2026 Baseline digest documents two newly available features, the CSS contrast-color() function and Math.sumPrecise(), plus several features hitting "widely available" status including the HTML search element, WebAuthn key extraction, well-formed string methods, and ARIA attribute reflection.
Summary: Baseline's monthly digest is one of the more useful recurring publications for frontend developers, not because of hype, but because it signals when a platform feature is actually safe to ship without extensive polyfills or caveats. April 2026 has a few entries worth paying attention to.
The CSS contrast-color() function is probably the most immediately practical addition. It takes a background color as input and returns whichever of black or white produces the highest contrast against it. If you've ever maintained a theme system that lets users set custom colors, you know the alternative: maintain a parallel set of text colors, recalculate on every change, test every combination against WCAG contrast ratios. The contrast-color() function hands that calculation to the browser. It's newly available, meaning it's in all core browsers as of this month, though "newly available" in Baseline terminology still warrants checking MDN for the exact browser list before shipping to production.
Math.sumPrecise() is a smaller but genuinely useful addition for anyone doing financial calculations or aggregating telemetry. JavaScript's floating-point behavior has burned enough developers that there are entire libraries dedicated to working around it. Adding an iterable to get a precision-safe sum as a first-class language method removes one more category of subtle numeric bugs.
On the "widely available" side, the HTML search element reaching broad compatibility is worth noting. Wrapping a search form in a search element rather than a div with role="search" gives an implicit ARIA landmark for free, the kind of thing that makes screen reader navigation work without developers having to think carefully about it. ARIA attribute reflection is similarly good news: setting element.ariaExpanded in JavaScript rather than calling setAttribute each time is cleaner to write and easier for frameworks to work with. The isWellFormed() and toWellFormed() string methods close a real gap for anyone handling emoji or complex Unicode in URLs or API payloads.
The digest also makes a broader point about accessibility and web standards that resonates: custom JavaScript solutions recreating accessible patterns are fragile, hard to maintain, and often break under assistive technology in edge cases. As platform features reach interoperability, the argument for rolling your own diminishes. The browser has already done the work.
Key takeaways:
- CSS contrast-color() lets the browser handle accessible text color selection against dynamic backgrounds, removing a category of manual theme management work
- Math.sumPrecise() provides a native, precision-safe summation method, useful for financial or aggregated numeric calculations
- The HTML search element and ARIA attribute reflection are now widely available, reducing the need for custom role attributes and setAttribute calls in accessibility work
Why do I care: The contrast-color() function is something I'd start reaching for in any design system work involving user-customizable themes. The ARIA attribute reflection improvement is a quiet quality-of-life win for framework authors and anyone writing component libraries. None of these are revolutionary, but "now available without a polyfill" is exactly the kind of incremental progress that compounds over time into a significantly less painful development experience.
April 2026 Baseline monthly digest
Building Resizable Sidebars with shadcn/ui: A Practical Walkthrough
TLDR: A hands-on guide covers eleven-plus layout patterns for resizable sidebars using shadcn/ui, including persistent width storage, hover-only resize handles, IDE-style layouts, three-panel email client views, and mobile drawer fallbacks, alongside common failure modes and how to avoid them.
Summary: Sidebar behavior is one of those UI problems that looks simple until you're three hours in and the panel is collapsing to zero pixels on a user's laptop. The shadcn/ui resizable component gives you the primitives, but building something that actually works across screen sizes, survives page refreshes, and handles keyboard navigation requires more thought than the basic example suggests.
The guide from shadcndeck.com walks through over eleven variants with working demos. The most useful parts for real applications are the persistent width via localStorage pattern, where the sidebar remembers its position across sessions, and the snap-to-grid behavior that prevents users from accidentally dragging a panel to an unusable size. IDE-style layouts with multiple panels and the three-panel email client view are more complex setups, but they cover the cases where a simple two-column split isn't enough.
The troubleshooting section is probably the most practically valuable part. The "sidebar becomes too small" problem is a common failure mode when resize constraints aren't set properly. Handle discoverability, meaning users not realizing they can drag something to resize it, is a real UX issue that hover-only handles can make worse rather than better. Width resetting on refresh without localStorage persistence is the kind of bug that seems fine in development and annoying in production. Mobile behavior as a drawer fallback rather than a resizable panel is the right call for most applications, and it's good to see it treated as a first-class concern rather than an afterthought.
What the guide doesn't address much is accessibility for the resize interaction itself. Keyboard-driven collapse is listed as one of the variants, which is a good start, but resize handles need proper ARIA roles and keyboard support to work for users who don't use a mouse. If you're building this for a production application rather than an internal tool, that's worth verifying independently beyond what shadcn/ui provides out of the box.
Key takeaways:
- Persistent sidebar width via localStorage and snap-to-grid constraints are non-optional for good user experience in resizable layouts
- Mobile fallback to a drawer pattern should be planned from the start, not retrofitted
- Handle discoverability and minimum width constraints prevent the most common usability problems with resize interactions
Why do I care: shadcn/ui has become the practical starting point for a lot of React component work, and sidebar layout is one of the more complex UI patterns teams tend to underestimate. Having a reference set of working variants that covers the edge cases, especially the persistence and mobile behavior, is useful enough to bookmark even if you don't need it today.
Shadcn Resizable Sidebar Examples - 11+ Variants & Demos
Kibo UI: The shadcn/ui Extension You Didn't Know You Needed
TLDR: Kibo UI is an open-source component library built on top of shadcn/ui that adds more complex components like color pickers, QR code generators, Gantt charts, and AI chatbot interfaces, filling the gap between shadcn's primitive-focused approach and the richer component needs of real applications.
Summary: The shadcn/ui ecosystem has settled into a clear pattern: the core library wraps Radix UI primitives and handles the fundamentals well. What it doesn't include is a large category of more complex, application-specific components that teams end up building themselves or pulling in from disparate sources. Kibo UI positions itself as that next layer.
The library includes components for things like color pickers and Gantt charts, which are genuinely painful to build well and even more painful to make accessible. The AI chatbot interface component is a timely addition given how many applications are adding some form of conversational UI. Kibo UI provides these as ready-to-use blocks that follow the same installation and customization patterns as shadcn/ui, which means if you're already working in that ecosystem, the learning curve is minimal.
The "composable" framing in the docs matters here. A component library that gives you a Gantt chart as a black box is useful until you need it to behave slightly differently, then it becomes a liability. Kibo UI's emphasis on composability suggests the components are meant to be assembled and modified rather than dropped in as final solutions. That's the right philosophy for a library that sits this close to application logic.
The honest caveat is that this is a newer library and the breadth of components means some will be more production-ready than others. Color pickers and Gantt charts have a lot of edge cases, especially around accessibility, and it's worth checking any specific component carefully before relying on it in a user-facing product.
Key takeaways:
- Kibo UI fills a genuine gap in the shadcn/ui ecosystem by providing more complex application components that follow the same patterns
- The library includes color pickers, Gantt charts, QR code generators, and AI chat interfaces as composable building blocks
- Accessibility quality should be verified per component before production use, given the library's relative newness
Why do I care: If you're building anything beyond standard CRUD interfaces in React and already using shadcn/ui, Kibo UI is worth evaluating. The Gantt chart alone, if the implementation is solid, would save days of work. The AI chat component is well-timed. My main concern is that complex interactive components like these carry a high accessibility burden, and that's where newer libraries tend to have gaps. Test it before you ship it.