Recent Posts
Archives

PostHeaderIcon [DevoxxUK2025] Cracking the Code Review

Paco van Beckhoven, a senior software engineer at Hexagon’s HXDR division, delivered a comprehensive session at DevoxxUK2025 on improving code reviews to enhance code quality and team collaboration. Drawing from his experience with a cloud-based platform for 3D scans, Paco outlined strategies to streamline pull requests, provide constructive feedback, and leverage automated tools. Highlighting the staggering $316 billion cost of fixing bugs in 2013, he emphasized code reviews as a critical defense against defects. His practical tactics, from crafting concise pull requests to automating style checks, aim to reduce friction, foster learning, and elevate software quality, making code reviews a collaborative and productive process.

Streamlining Pull Requests

Paco stressed the importance of concise, well-documented pull requests to facilitate reviews. He advocated for descriptive titles, inspired by conventional commits, that include ticket numbers and context, such as “Fix null pointer in payment service.” Descriptions should outline the change, link related tickets or PRs, and explain design decisions to preempt reviewer questions. Templates with checklists ensure consistency, reminding developers to update documentation or verify tests. Paco also recommended self-reviewing PRs after a break to catch errors like unused code or typos, adding comments to clarify intent and reduce reviewer effort, ultimately speeding up the process.

Effective Feedback and Collaboration

Delivering constructive feedback is key to effective code reviews, Paco noted. He advised reviewers to start with the PR’s description and existing comments to understand context before diving into code. Reviews should prioritize design and functionality over minor style issues, ensuring tests are thoroughly checked for completeness. To foster collaboration, Paco suggested using “we” instead of “you” in comments to emphasize teamwork, posing questions rather than statements, and providing specific, actionable suggestions. Highlighting positive aspects, especially for junior developers, boosts confidence and encourages participation, creating a supportive review culture.

Leveraging Automated Tools

To reduce noise from trivial issues like code style, Paco showcased tools like Error Prone, OpenRewrite, Spotless, Checkstyle, and ArchUnit. Error Prone catches common mistakes and suggests fixes, while OpenRewrite automates migrations, such as JUnit 4 to 5. Spotless enforces consistent formatting across languages like Java and SQL, and Checkstyle ensures adherence to coding standards. ArchUnit enforces architectural rules, like preventing direct controller-to-persistence calls. Paco advised introducing these tools incrementally, involving the team in rule selection, and centralizing configurations in a parent POM to maintain consistency and minimize manual review efforts.

Links:

PostHeaderIcon [OxidizeConf2024] The Basics of Profile-Guided Optimization (PGO) in Rust

Understanding PGO and Its Relevance

In the realm of high-performance software, optimizing applications for speed and efficiency is paramount. At OxidizeConf2024, Alexander Zaitsev, a seasoned developer with a background in C++ and extensive experience in compiler optimizations, delivered a comprehensive exploration of Profile-Guided Optimization (PGO) in Rust. PGO leverages runtime statistics to enhance software performance, a technique long supported by the Rustc compiler but fraught with practical challenges. Alexander shared his insights from applying PGO across diverse domains—compilers, databases, game engines, and CLI tools—offering a roadmap for developers seeking to harness its potential.

PGO operates by collecting runtime data to inform compiler optimizations, enabling tailored code generation that aligns with actual workloads. Alexander emphasized its applicability to CPU-intensive applications with complex branching, such as parsers, databases, and operating systems like OxideOS. By analyzing real-world benchmarks, he demonstrated significant performance gains, with speedups observed in open-source projects. These results, derived from practical workloads rather than synthetic tests, underscore PGO’s value in enhancing Rust applications, making it a vital tool for developers prioritizing performance.

Practical Applications and Performance Gains

Alexander’s presentation highlighted concrete examples of PGO’s impact. For instance, applying PGO to libraries like Serde resulted in notable performance improvements, with benchmarks showing reduced execution times for JSON parsing and other tasks. He showcased results from various applications, including databases and game engines, where PGO optimized critical paths, reducing latency and improving throughput. These gains were achieved by enabling PGO’s instrumentation-based approach, which collects detailed runtime profiles to guide optimizations like inlining and branch prediction.

However, Alexander cautioned that PGO’s effectiveness depends on workload representativeness. For databases, he used analytical workloads to generate profiles, ensuring optimizations aligned with typical usage patterns. This approach contrasts with manual optimization techniques, such as annotating hot paths, which Alexander argued are less adaptable to changing workloads. By automating optimization through PGO, developers can achieve consistent performance improvements without the maintenance burden of manual tweaks, a significant advantage in dynamic environments.

Navigating PGO’s Challenges and Ecosystem

While PGO offers substantial benefits, Alexander detailed several pitfalls. Common traps include profile mismatches, where training data does not reflect production workloads, leading to suboptimal optimizations. He also highlighted issues with link-time optimization (LTO), which, while complementary to PGO, is not universally adopted. To mitigate these, Alexander recommended starting with release mode optimizations (level three) and enabling LTO before applying PGO. For advanced users, sampling-based PGO or continuous profiling, as practiced by Google, can further enhance results.

The Rust ecosystem’s PGO support is evolving, with tools like cargo-pgo and community contributions improving accessibility. Alexander pointed to his “Awesome PGO” repository as a comprehensive resource, offering benchmarks and guidance across ecosystems, including C++. He also noted ongoing efforts to integrate machine learning into PGO workflows, citing tools like LLVM’s BOLT and Intel’s Thin Layout Optimizer. These advancements signal a bright future for PGO in Rust, though challenges like build system integration and community tooling maturity remain.

Links:

PostHeaderIcon Guarding the Web: Understanding and Mitigating Modern Application Security Risks: XSS • CSRF • Clickjacking • CORS • SSRF

Modern web applications operate in a hostile environment. Attackers exploit input handling, browser trust, and server connectivity to inject code (XSS), trigger unauthorized actions (CSRF), trick users into clicking hidden UI (clickjacking), abuse permissive cross-origin policy (CORS), or make the server itself fetch sensitive resources (SSRF). This article explains the mechanics of each threat and provides concrete, production-grade mitigation patterns you can adopt today.


Cross-Site Scripting (XSS): When Untrusted Input Becomes Code

Threat model: User-provided data is rendered into a page without correct encoding or policy restrictions, allowing script execution in the victim’s browser.

Typical Exploits

Stored XSS (comments, profiles):

<script>fetch('/api/session/steal', {credentials:'include'})</script>

Reflected XSS (search query):

GET /search?q=<script>alert(1)</script>

DOM-based XSS (dangerous sinks):

// Anti-pattern: innerHTML with untrusted input
const result = new URLSearchParams(location.search).get('msg');
document.getElementById('banner').innerHTML = result; // XSS sink

High-Confidence Mitigations

  • Contextual Output Encoding: Encode before insertion, based on context (HTML, attribute, URL, JS, CSS).
  • Prefer Safe APIs: Use textContent / setAttribute over innerHTML; avoid eval/Function constructors.
  • Framework Defaults: Modern templating (e.g., React, Angular) auto-escapes. Avoid escape bypasses (e.g., dangerouslySetInnerHTML) unless you sanitize with robust libraries.
  • Content Security Policy (CSP): Block inline scripts and restrict sources; use nonces.

CSP Example (Nonce-Based)

Content-Security-Policy: default-src 'none';
  script-src 'self' 'nonce-r4nd0mNonce';
  style-src 'self';
  img-src 'self' data:;
  connect-src 'self';
  base-uri 'self';
  frame-ancestors 'self';
  form-action 'self';

Server/Framework Snippets

Express.js: encode + CSP headers

app.use((req, res, next) => {
  res.set('Content-Security-Policy',
    "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; frame-ancestors 'self'");
  res.set('X-Content-Type-Options', 'nosniff');
  next();
});

Do sanitize if you must render HTML: Use a vetted sanitizer (e.g., DOMPurify on the client, OWASP Java HTML Sanitizer on the server) with an allowlist.


Cross-Site Request Forgery (CSRF): Abusing Session Trust

Threat model: A logged-in user’s browser sends a forged state-changing request (e.g., money transfer) to a trusted site because cookies are automatically included.

Exploit Example

<form action="https://bank.example/transfer" method="POST">
  <input type="hidden" name="to" value="attacker">
  <input type="hidden" name="amount" value="1000">
</form>
<script>document.forms[0].submit();</script>

Mitigations That Work Together

  • Synchronizer (Anti-CSRF) Tokens: Embed a per-session/per-request token in each state-changing form or AJAX request; verify server-side.
  • SameSite Cookies: Set session cookies to SameSite=Lax or Strict and Secure to block cross-site inclusion.
  • Method & Content Checks: Require POST/PUT/DELETE with Content-Type: application/json; reject unexpected content types.
  • Origin/Referer Validation: For sensitive endpoints, verify Origin (preferred) or Referer.
  • Re-authentication / Step-Up: For high-value actions, require a second factor or password confirmation.

Example (Express + CSRF Token)

// Pseudocode with csurf-like middleware
app.post('/transfer', requireAuth, verifyCsrfToken, (req, res) => {
  // process transfer
});

SPA + API note: Prefer token-based auth (Authorization header) to avoid ambient cookies. If you must use cookies, combine SameSite with CSRF tokens.


Clickjacking: UI Redress and Hidden Frames

Threat model: An attacker overlays your site in an invisible <iframe> and tricks users into clicking sensitive controls.

Exploit Sketch

<iframe src="https://target.example/approve" style="opacity:0;position:absolute;top:0;left:0;width:100%;height:100%"></iframe>

Mitigations

  • X-Frame-Options (XFO): DENY or SAMEORIGIN. (Legacy but still widely respected.)
  • CSP frame-ancestors: Modern, fine-grained embedding control.
  • UI Hardening: Re-prompt for confirmation on dangerous actions; disable one-click irreversible changes.

Header Examples

X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'self'

Server Config

Nginx:

add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;

Apache:

Header always set X-Frame-Options "DENY"
Header always set Content-Security-Policy "frame-ancestors 'self'"

CORS: Safe Cross-Origin Requests Without Overexposure

Threat model: Overly permissive CORS allows arbitrary origins to read sensitive API responses or send authenticated requests.

Dangerous Patterns

  • Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true (browsers will ignore, but this signals confusion and often pairs with other mistakes).
  • Reflecting the request Origin wholesale without an allowlist.
  • Forgetting Vary: Origin, causing caches/CDNs to serve one origin’s CORS response to all.

Safe Configuration

Access-Control-Allow-Origin: https://app.example
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: ETag, X-Request-Id
Vary: Origin

Implementation Tip

// Pseudocode: strict allowlist
const allowed = new Set(['https://app.example', 'https://admin.example']);
const origin = req.headers.origin;
if (allowed.has(origin)) {
  res.setHeader('Access-Control-Allow-Origin', origin);
  res.setHeader('Vary', 'Origin');
}

Principle: CORS is not an auth mechanism—treat it as a read-permission gate. Apply per-endpoint scoping; don’t turn it on globally.


Server-Side Request Forgery (SSRF): Turning Your Server Into a Proxy

Threat model: The application fetches remote resources based on user input (URLs), allowing attackers to reach internal networks or cloud metadata endpoints.

Exploit Examples

  • Cloud metadata theft: http://169.254.169.254/latest/meta-data/ (AWS) / http://metadata.google.internal/ / http://169.254.169.254/metadata/instance (Azure; IMDSv2/headers required).
  • Reaching services on localhost or RFC1918 IPs (e.g., Redis, internal dashboards).
  • Schema abuse: file://, gopher://, or ftp:// if unsupported schemas aren’t blocked.
  • Open redirect chains or DNS rebinding that convert a safe-looking hostname into an internal IP at resolution time.

Defense-in-Depth

  • Strict Allowlists: Only permit fetching from specific hosts/paths; reject everything else.
  • URL & IP Validation: Parse the URL; resolve DNS; block private and link-local ranges; re-validate after redirects.
  • Egress Proxy with ACL: Force all outbound HTTP(S) through a proxy that enforces destination policies and logs requests.
  • Cloud Hardening: Require IMDSv2 (AWS); block server access to metadata endpoints unless strictly needed.
  • Timeouts & Size Limits: Short connect/read timeouts and response byte caps to prevent internal scanning and DoS.

Hardening Snippet (Pseudocode)

function safeFetch(userUrl) {
  const url = new URL(userUrl);
  // allowlist scheme
  if (!['https:'].includes(url.protocol)) throw new Error('Blocked scheme');
  // DNS resolve and block private IPs
  const ip = resolveToIP(url.hostname);
  if (isPrivate(ip) || isLinkLocal(ip) || isLoopback(ip)) throw new Error('Blocked destination');
  // enforce egress proxy
  return proxyHttpGet(url, { timeoutMs: 2000, maxBytes: 1_000_000, followRedirects: 3, revalidateIPOnRedirect: true });
}

Header note: SSRF is best mitigated by network policy and URL validation; “headers” alone can’t prevent SSRF, but you may set request policies (e.g., disallow redirects, strip sensitive headers) and enforce gateway rules.


Complementary Security Headers

  • Strict-Transport-Security: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • X-Content-Type-Options: nosniff to block MIME type sniffing.
  • Referrer-Policy: e.g., strict-origin-when-cross-origin.
  • Permissions-Policy: Restrict powerful APIs (camera, geolocation, etc.).
  • Cross-Origin-Opener-Policy / Resource-Policy / Embedder-Policy: Strengthen isolation where feasible.

Operational Controls & SDLC Integration

  • Threat Modeling: Map trust boundaries (browser ⇄ app ⇄ services ⇄ internet) and identify high-risk data flows.
  • Static/Dynamic Testing: SAST, DAST, and dependency scanning in CI; add security unit tests for templating and request flows.
  • Observability: Log security-relevant events (CSP violations via report-to, WAF blocks, CSRF failures, SSRF proxy denies) and alert.
  • WAF/Gateway Policies: Enforce header baselines, block known bad payloads, and constrain egress with explicit ACLs.
  • Secrets Hygiene: Short-lived tokens, mTLS for service-to-service, and key rotation.
  • Least Privilege by Default: Scope CORS per endpoint, narrow IAM roles, network segmentation.

Deployment Checklist

  • XSS: Contextual encoding, CSP with nonces, sanitizer for any HTML rendering.
  • CSRF: Anti-CSRF tokens, SameSite + Secure cookies, Origin checks, step-up auth on critical actions.
  • Clickjacking: X-Frame-Options: DENY and CSP frame-ancestors 'self'.
  • CORS: Explicit allowlist, credentials only when necessary, Vary: Origin, scoped to sensitive endpoints.
  • SSRF: Allowlist destinations, block internal ranges, egress proxy with ACL, timeouts/size caps, re-validate after redirects.
  • Headers: HSTS, XCTO, Referrer-Policy, Permissions-Policy in place.
  • Ops: Logging/alerting on policy violations; SAST/DAST integrated; WAF rules tuned to app.
Security is not a single feature; it is a posture expressed through code, configuration, and continuous verification.

PostHeaderIcon [KotlinConf2025] Dependencies and Kotlin Native

The world of dependency management is often taken for granted in the JVM ecosystem. However, when venturing into the realm of Kotlin Native, the familiar comforts of JAR files and class loaders fade, giving way to a more intricate and challenging landscape. In his insightful talk, Tadeas Kriz, a senior Kotlin developer at Touchlab, demystified this complex topic, offering a detailed comparison between JVM and native dependency handling and providing practical solutions for common issues.

Tadeas began by drawing a clear distinction between the two worlds. The JVM handles the heavy lifting of linking and loading dependencies at runtime, a process that is largely transparent to the developer. In contrast, Kotlin Native produces a standalone binary, which means the developer must contend with the nuances of native linking and compilation. This fundamental difference introduces a new set of challenges, particularly for those accustomed to the JVM’s seamless “it just works” experience.

He delved into the specifics of native platforms, examining dependency management tools like CocoaPods and Swift Package Manager used on Apple platforms. By comparing their strengths and weaknesses, Tadeas provided valuable context for how Kotlin Multiplatform fits into this ecosystem. He underscored the importance of understanding the native build process, a step that is often abstracted away but is crucial for troubleshooting the cryptic errors that can arise when integrating dependencies. He emphasized that static linking is often the most reliable approach in Kotlin Native, offering a more predictable and robust solution.

A significant portion of the talk was dedicated to practical workarounds and tools to overcome these challenges. Tadeas introduced a key concept: cinterop bindings, which are used to interact with C libraries from Kotlin Native code. He explained how to handle dynamic and static libraries and provided guidance on navigating the complexities of header file inclusion and symbol visibility. He also highlighted the utility of specific tools and practices, such as meticulously heeding build warnings, as they often contain clues to underlying issues.

Tadeas also brought attention to Skie, an open-source tool he co-authored, which addresses a key pain point for developers: the quality of the Kotlin Multiplatform API exposed to Swift. He explained that Skie enhances the generated Swift API, making it more idiomatic and easier for iOS developers to work with. He positioned it as a valuable solution for teams looking to improve their development workflow and collaboration while waiting for future features like Swift export. His talk provided a comprehensive guide, arming developers with the knowledge and tools needed to navigate the complexities of dependencies in the Kotlin Native world with greater confidence and efficiency.

Links:


PostHeaderIcon [DefCon32] DEF CON 32: Gotta Cache ‘em All – Bending the Rules of Web Cache Exploitation

Martin Doyhenard, a seasoned security researcher, captivated the DEF CON 32 audience with his exploration of innovative web cache exploitation techniques. Focusing on exploiting ambiguities in RFC standards, Martin unveiled two novel methods—Static Path Deception and Cache Key Confusion—that push the boundaries of web cache attacks. Through detailed case studies and a live demonstration, he showcased how these techniques can compromise application confidentiality, enable arbitrary cache poisoning, and even achieve full site takeovers, providing actionable insights for security practitioners to identify and mitigate such vulnerabilities.

Unveiling Web Cache Mechanics

Martin began by elucidating the inner workings of web caches, which store frequently accessed content to enhance website performance. He highlighted how caches rely on URL parsing to determine what to store and serve, yet inconsistencies in parsing across platforms create exploitable vulnerabilities. By leveraging ambiguities in RFC standards, attackers can manipulate cache behavior to serve malicious content or expose sensitive data. Martin’s clear explanation set the stage for understanding the sophisticated attacks that followed, emphasizing the critical role of URL parsers in web security.

Static Path Deception: Breaching Confidentiality

Delving into his first technique, Martin introduced Static Path Deception, a method that exploits cache handling of static file paths to compromise application confidentiality. Using a case study involving Nginx behind Cloudflare, he demonstrated how attackers can trick caches into serving sensitive content to unauthorized users. By crafting specific URL patterns, Martin showed how this technique bypasses traditional cache restrictions, exposing private data. His findings underscore the need for consistent cache configuration across content delivery networks and web servers to prevent such breaches.

Cache Key Confusion: Poisoning and Denial of Service

Martin then presented Cache Key Confusion, a technique exploiting discrepancies in how platforms like Microsoft Azure Cloud normalize cache keys. He illustrated how attackers can manipulate URL parsing to poison caches, serving malicious content to all users or triggering denial-of-service attacks. His live demo combined Cache Key Confusion with an open redirect vulnerability to execute arbitrary JavaScript, achieving a complete site takeover. This powerful demonstration highlighted the far-reaching impact of parser inconsistencies and the potential for significant disruption in cloud-based environments.

Mitigation and Community Engagement

Concluding, Martin shared practical strategies to counter these vulnerabilities, urging organizations to audit cache configurations and disable key normalization where possible. He introduced his open-source tool, Cache Killer, designed to detect parsing discrepancies, and encouraged the DEF CON community to contribute to its development. By sharing references to prior research and his own findings, Martin fostered a collaborative approach to improving web cache security, inspiring attendees to hunt for similar vulnerabilities in bug bounty programs and beyond.

Links:

  • None available

PostHeaderIcon [NDCOslo2024] No More SQLite: How to Write Tests With EF Core Using TestContainers – Daniel Ward

Amid the arduous arena of application assurance, where integration inspections intersect infrastructure intricacies, Daniel Ward, a .NET navigator and testing tactician, torpedoes the tired trope of SQLite as EF Core’s ersatz examiner. With a penchant for precision and a portfolio of pragmatic patterns, Daniel decries the discrepancies—dialect drifts, devious defaults—that delude developers into dubious dependability. His herald: TestContainers, a titan of transient testing, tethering true-to-type databases to dotnet diagnostics, ensuring examinations echo environments exactly.

Daniel dives direct: SQLite’s siren song—simplicity’s shadow—seduces with speed yet sabotages similitude, spawning spurious successes in schema shadows. Real realms revel in PostgreSQL or SQL Server; sans such sentinels, tests tantalize with triumphs that tumble in truth. His thesis: TestContainers triumphs, turbocharging temporaries—containers conjured cleanly, configured crisply—for credible, containerized corroboration.

Ditching the Decoy: Drawbacks of Database Doppelgangers

SQLite’s shortcomings spotlight starkly: syntax schisms—TOP versus LIMIT—thwart translations; transaction treatments transmute, transactions toggling differently. Daniel details dev database dilemmas: devious dependencies, drift-prone data, deployment drudgery. False flags flourish: tests triumph trivially, only to falter in flight, fostering fragile faith.

His horror stories: SQLite’s solitary schema swallows specifics, sans stored procedures or sequences; in-memory imposters ignore indexes, inflating illusions. Daniel’s decree: discard decoys for doppelgangers divine—TestContainers delivers, Docker-driven duplicates that duplicate dynamics deftly.

Containers as Champions: TestContainers’ Triumphs

TestContainers, Daniel declaims, democratizes diligence: NuGet-nimble, it nurtures nodes—Postgres pods, SQL Server ships—spinning sans setup strife. Benefits burgeon: bit-for-bit fidelity, flakeless flurries, fleet-footed forays. Reusability reigns: withReuse() recycles realms, reining runtime rigorously.

Daniel demos deftly: dotnet add package Testcontainers.PostgreSql; a builder begets a beast, beckoning a bespoke bastion. Connection strings cascade, EF contexts calibrate, tests transact transparently—Respawn resets, restoring rectitude routinely.

Precision in Practice: Pitfalls and Panaceas

Pitfalls persist: parallelism’s pandemonium, port pandemonium—Daniel dispels with Docker Desktop’s discipline, orchestration’s oversight. His heuristic: harness health checks, heed horizons—hundreds hum harmoniously, hovering at half-minutes for hordes.

Respawn’s renaissance: rollback routines, resetting relations rigorously, rectifying residue. Daniel’s distillation: TestContainers transmutes testing from torment to triumph, true tests tempering temper tantrums.

Links:

PostHeaderIcon [KotlinConf2024] The Best Programmer I Know: Insights from KotlinConf2024

At KotlinConf2024, Daniel Terhorst-North shared a heartfelt reflection on the traits of exceptional programmers, drawing from his 30-year career and a colleague who embodies these qualities. Without a formal degree, this programmer excels by starting tasks, prioritizing outcomes, simplifying solutions, choosing tools wisely, and fostering team growth. Daniel’s narrative, blending personal anecdotes and practical advice, inspires developers to cultivate curiosity, resilience, and empathy while building impactful software.

Starting with Action

Great programmers dive into tasks without hesitation. Daniel recounted how his colleague tackles projects by starting anywhere, embracing the unknown. This “just start” mindset counters procrastination, which Daniel admits to masking as research. By iterating rapidly—trying, failing, and learning—programmers overcome perfectionism and ego. Daniel likened progress to navigating a grid city, moving stoplight to stoplight, accepting delays as part of the journey, ensuring steady advancement toward solutions.

Prioritizing Outcomes Over Code

Building products, not just code, defines effective programming. Daniel emphasized that emotional investment should focus on outcomes, not code, which is merely a means. The best programmers write minimal, high-quality code, holding no attachment to it. Studying the domain reveals user needs, as Daniel learned during a financial project where ignorance of CDOs led to unintended consequences. Observing users’ frustrations, like manual data entry, uncovers opportunities to eliminate friction, enhancing product value.

Simplifying the Complex

Exceptional programmers see through complexity to find simple solutions. Daniel shared a story of his colleague bypassing bloated Java web servers by writing a lean one from the HTTP spec. In another case, a team debating JSON libraries was guided to implement a simple interface for nine serialized objects, avoiding heavy dependencies. Writing clear documentation, like a streamlined README, drives “embarrassment-driven refactoring,” ensuring solutions remain concise and maintainable, solving only what’s necessary.

Choosing Tools for the Problem

Tool selection should prioritize the product, not team familiarity. Daniel recounted a team learning Scala to sketch code quickly, despite no prior experience, proving adaptability trumps comfort. He advocated for polyglot programming, using Advent of Code to learn Rust and Go, which broadened his problem-solving perspective. By minimizing cognitive distance between problem and solution, as Rich Hickey’s “Simple Made Easy” suggests, programmers select tools that evolve with project needs, ensuring flexibility.

Fostering Team Care

Great programmers uplift their teams. Daniel finds joy in pairing and teaching, inspired by an XKCD comic about the “lucky 10,000” who learn something new daily. He creates environments for learning, drawing from jiu-jitsu’s teaching-first philosophy. Sending teams home to rest, as Daniel advocates, boosts effectiveness, while assuming positive intent—per Virginia Satir’s family therapy principle—builds empathy, transforming conflicts into opportunities for collaboration and growth.

Building Psychological Safety

Psychological safety, per Amy Edmondson’s research, is vital for high-performing teams. Daniel explained that safe teams encourage saying “I don’t know,” seeking help, and disagreeing without fear. A study of surgical teams showed high performers report more errors, reflecting trust, not incompetence. In software, this translates to teams where questions spark learning, help fosters collaboration, and dissent drives improvement, creating dynamic, challenging environments that fuel innovation.

Growing as a Programmer

Personal growth sustains programming excellence. Daniel urged developers to stay current through communities, contribute actively, and remain skeptical of trends like AI hype. Practicing via challenges like Advent of Code sharpens skills, as Daniel found when switching languages mid-puzzle. Balancing work with physical activities, like running, and prioritizing rest prevents burnout. By embracing continual learning and kindness, programmers evolve, as Daniel’s colleague demonstrates, into impactful, resilient professionals.

Links:

PostHeaderIcon [DefCon32] DEF CON 32: Feet Feud

Tiberius, presenting as “Toes” with the OnlyFeet CTF team, hosted the lively “Feet Feud” game show at DEF CON 32, bringing together cybersecurity enthusiasts for a fun, interactive competition. Team captains Ali Diamond, known for her Hack 5 ThreatWire hosting, and John Hammond, a prominent cybersecurity educator, led their teams in a spirited battle of wits. The event, a fan favorite after unofficial runs in previous years, engaged the audience with hacker-themed challenges and quirky prizes, fostering community spirit and camaraderie.

The Game Show Experience

Tiberius kicked off the event with infectious enthusiasm, introducing Ali and John as team captains. Audience members, selected based on vibrant attire like orange bow ties, joined the teams, creating an electric atmosphere. The game, inspired by classic game shows, featured cybersecurity-themed questions and challenges, blending humor with technical knowledge. Tiberius’s dynamic hosting, supported by assistants Helen and Wolfie, ensured a fast-paced, engaging experience that kept the crowd entertained.

Celebrating the Hacker Community

The event celebrated the DEF CON community’s creativity and collaboration, with Ali and John leading their teams through rounds that tested hacking trivia and problem-solving skills. Prizes, including Hack The Box VIP vouchers, coding socks, and whimsical baby foot candles, added a playful touch. Tiberius emphasized the importance of community-driven events like Feet Feud, which provide a lighthearted counterbalance to the conference’s technical intensity, strengthening bonds among attendees.

Building on Tradition

Reflecting on Feet Feud’s evolution from a small gathering to a main-stage event, Tiberius highlighted its growing popularity, with this year’s crowd far exceeding the previous high of 40 attendees. The game’s success, supported by sponsors like Hack The Box, underscores its role in fostering a sense of belonging within the cybersecurity community. By encouraging audience participation and celebrating victories with quirky rewards, Feet Feud reinforces DEF CON’s unique blend of learning and fun.

Looking Ahead

Concluding, Tiberius expressed hope for Feet Feud’s return with even grander prizes, thanking Helen and Wolfie for their invaluable support. The event’s success lies in its ability to unite hackers in a shared celebration of their craft, inspiring future iterations that continue to blend competition with camaraderie. Ali and John’s leadership, combined with the audience’s enthusiasm, ensures Feet Feud remains a cherished DEF CON tradition.

Links:

PostHeaderIcon [KotlinConf2025] Building a macOS Screen Saver with Kotlin

A captivating tale of a developer’s obsession and a journey into the less-trodden paths of Kotlin development was shared by Márton Braun, a Developer Advocate at JetBrains. It all began with a simple, yet compelling, observation at a previous KotlinConf: a screen saver featuring the bouncing Kotlin logos, reminiscent of old DVD players. Upon discovering it was merely a pre-rendered video and not a true screen saver, a challenge was born. Márton set out to build his own, a native macOS application powered by Kotlin/Native.

The project became a masterclass in interoperability and a candid exploration of the quirks of native application development. Márton detailed how Kotlin/Native’s powerful interop capabilities made it surprisingly easy to call native macOS APIs. However, this ease was often contrasted with the complexities and frustrations of working with the macOS platform itself. The development process was a constant battle, with macOS often proving to be an uncooperative partner in this creative endeavor.

Márton’s perseverance paid off, resulting in a fully functional screen saver. He even managed to create two distinct implementations: one using the traditional AppKit framework and another built with Compose Multiplatform. This dual approach not only demonstrated the capabilities of both technologies but also provided a unique learning experience. He highlighted how the Compose version allowed him to focus on the core UI logic, abstracting away the intricacies of packaging the screen saver. This is a powerful testament to Compose Multiplatform’s potential for simplifying development and improving productivity.

The screen saver project serves as an excellent case study, showcasing Kotlin’s ability to venture into unconventional domains beyond mobile and backend development. Márton successfully demonstrated that with Kotlin and the right tools, developers can create truly native applications for platforms like macOS, leveraging their existing skills and knowledge. The flexibility of Kotlin Multiplatform allows developers to share code across platforms while still delivering a native user experience.

Ultimately, this project is a celebration of the unique possibilities that Kotlin offers. It encourages developers to think creatively about how they can apply the language to solve a wide range of problems and build applications for a diverse set of platforms. Márton’s story is an inspiring reminder that sometimes the most interesting and valuable projects are born from a simple desire to see something that doesn’t exist yet come to life.

Links:


PostHeaderIcon [DevoxxFR2025] Building an Agentic AI with Structured Outputs, Function Calling, and MCP

The rapid advancements in Artificial Intelligence, particularly in large language models (LLMs), are enabling the creation of more sophisticated and autonomous AI agents – programs capable of understanding instructions, reasoning, and interacting with their environment to achieve goals. Building such agents requires effective ways for the AI model to communicate programmatically and to trigger external actions. Julien Dubois, in his deep-dive session, explored key techniques and a new protocol essential for constructing these agentic AI systems: Structured Outputs, Function Calling, and the Model-Controller Protocol (MCP). Using practical examples and the latest Java SDK developed by OpenAI, he demonstrated how to implement these features within LangChain4j, showcasing how developers can build AI agents that go beyond simple text generation.

Structured Outputs: Enabling Programmatic Communication

One of the challenges in building AI agents is getting LLMs to produce responses in a structured format that can be easily parsed and used by other parts of the application. Julien explained how Structured Outputs address this by allowing developers to define a specific JSON schema that the AI model must adhere to when generating its response. This ensures that the output is not just free-form text but follows a predictable structure, making it straightforward to map the AI’s response to data objects in programming languages like Java. He demonstrated how to provide the LLM with a JSON schema definition and constrain its output to match that schema, enabling reliable programmatic communication between the AI model and the application logic. This is crucial for scenarios where the AI needs to provide data in a specific format for further processing or action.

Function Calling: Giving AI the Ability to Act

To be truly agentic, an AI needs the ability to perform actions in the real world or interact with external tools and services. Julien introduced Function Calling as a powerful mechanism that allows developers to define functions in their code (e.g., Java methods) and expose them to the AI model. The LLM can then understand when a user’s request requires calling one of these functions and generate a structured output indicating which function to call and with what arguments. The application then intercepts this output, executes the corresponding function, and can provide the function’s result back to the AI, allowing for a multi-turn interaction where the AI reasons, acts, and incorporates the results into its subsequent responses. Julien demonstrated how to define function “signatures” that the AI can understand and how to handle the function calls triggered by the AI, showcasing scenarios like retrieving information from a database or interacting with an external API based on the user’s natural language request.

MCP: Standardizing LLM Interaction

While Structured Outputs and Function Calling provide the capabilities for AI communication and action, the Model-Controller Protocol (MCP) emerges as a new standard to streamline how LLMs interact with various data sources and tools. Julien discussed MCP as a protocol that aims to standardize the communication layer between AI models (the “Model”) and the application logic that orchestrates them and provides access to external resources (the “Controller”). This standardization can facilitate building more portable and interoperable AI agentic systems, allowing developers to switch between different LLMs or integrate new tools and data sources more easily. While details of MCP might still be evolving, its goal is to provide a common interface for tasks like function calling, accessing external knowledge, and managing conversational state. Julien illustrated how libraries like LangChain4j are adopting these concepts and integrating with protocols like MCP to simplify the development of sophisticated AI agents. The presentation, rich in code examples using the OpenAI Java SDK, provided developers with the practical knowledge and tools to start building the next generation of agentic AI applications.

Links: