Skip to content

Archive

Security

23 articles
Software Engineering 19 Sep 2026 6 min read

seccomp User Notification Moves Selected Syscall Decisions to a Broker

A seccomp filter can do more than allow or reject a system call immediately. With user notification, a matching call can be suspended while another process receives a structured request on a listener file descriptor and decides what result the blocked thread receives. The mechanism turns selected syscall decisions into a brokered interface without moving the entire syscall implementation into user space. The boundary is precise but narrower than a general interposition layer. The kernel still owns syscall dispatch, task state, descriptor tables, and validation performed by kernel code. The broker receives metadata and can return a value, an error, or in supported cases request continued execution of the original syscall. Correct designs account for mutable target memory, notification lifetime, and the fact that a policy decision is not automatically a transaction over process state.

Linux 19 Sep 2026 6 min read

openat2 Constrains Path Resolution at the Kernel Boundary

A pathname that begins inside a trusted directory can resolve somewhere else before open() returns. Parent components, symbolic links, magic links, mount points, and concurrent namespace changes all participate in Linux pathname lookup. Checking a string before opening it therefore does not establish where the kernel will finish resolution. Linux openat2() places restrictions inside the lookup operation itself. A caller supplies a directory file descriptor, ordinary open flags, and a resolve policy in struct open_how. The kernel then applies those constraints while walking every relevant path component. This moves a security boundary from pre-validation of pathname text into the operation that actually resolves the pathname.

Linux 19 Sep 2026 5 min read

openat2 Constrains Linux Path Resolution at the Open Boundary

A pathname can change meaning while a process is resolving it. Directory renames, symbolic links, mount points, and .. components can redirect lookup away from the directory a program intended to treat as its boundary. Linux openat2() attaches resolution policy to the lookup itself. Its struct open_how contains a resolve bit mask, so the kernel can reject a path when resolution violates a caller-selected constraint instead of relying only on checks performed before open().

Linux 19 Sep 2026 4 min read

memfd Seals Constrain Shared-Memory Mutation After Handoff

A memfd_create() descriptor names an anonymous file whose storage lives in memory-backed filesystem infrastructure. By itself, descriptor handoff does not freeze that object: a process retaining suitable access can still write bytes, truncate the file, or extend it. Linux file seals add kernel-enforced restrictions that can make selected mutations fail after the producer declares the object complete. This changes shared-memory handoff from a convention into a state transition enforced at the file object.

Go 19 Sep 2026 7 min read

Email OTP in Go: Single-Use Codes, Expiration, and Replay Protection

Email OTP in Go: Single-Use Codes, Expiration, and Replay Protection An email OTP looks simple: generate six digits, send them, and compare what the user types. The security boundary is not the email API, though. It is the server-side challenge lifecycle. A correct implementation has to make the code unpredictable, expire it quickly, limit guesses, invalidate older challenges when appropriate, and guarantee that a successful code cannot be consumed twice. Those properties are different from TOTP, even though both mechanisms are commonly described as OTP.

Linux 18 Sep 2026 5 min read

openat2 Resolve Flags Constrain Path Traversal per Open

A pathname passed to openat2() can be rejected even when the same pathname would resolve successfully through openat(). The difference comes from open_how.resolve: Linux can apply traversal constraints while resolving every component of that single open operation. This changes the boundary around path handling. A directory file descriptor can act as more than a starting point; resolve flags can restrict escapes, symbolic-link traversal, mount crossings, and lookups that require work beyond cached state.

Linux 18 Sep 2026 6 min read

Landlock Rulesets Add Process-Local Access Control

A Linux process can voluntarily remove access that its UID, capabilities, mount namespace, and other security layers would otherwise permit. Landlock implements this as a stackable Linux Security Module: a process creates a ruleset, adds allowed objects, then places itself in a Landlock domain. The resulting policy is an additional restriction. It does not grant access denied by DAC, ACLs, SELinux, AppArmor, mount permissions, or another active control. Once enforced, the Landlock layer cannot be removed from that thread; later Landlock domains can only add restrictions.

Software Engineering 17 Sep 2026 5 min read

openat2 Constrains Path Resolution at the Lookup Boundary

A pathname can begin below a trusted directory and still escape that subtree during resolution. A .. component, symbolic link, magic link, or mount transition can change the object ultimately reached even when the initial directory file descriptor is trusted. Linux openat2() places constraints inside pathname resolution itself, so the kernel can reject a lookup that violates the selected boundary. This differs from checking a pathname string before calling open(). Path resolution operates on filesystem objects and namespace state, not only text. openat2() extends the openat() model with a struct open_how whose resolve field controls traversal of pathname components.

Software Engineering 17 Sep 2026 9 min read

Linux openat2 Makes Path Resolution Constraints Atomic

A pathname can name a different object by the time a second lookup checks it. On Linux, openat2() addresses that boundary by attaching resolution constraints to the same kernel operation that walks the pathname and opens the resulting object. The policy is evaluated during lookup rather than inferred from a pathname inspected before or after the open. This distinction matters whenever a process accepts path components from a less-trusted source while intending to keep resolution inside a directory, reject symbolic links, avoid mount crossings, or require a cache-only lookup. The relevant object is not the input string alone. It is the result of resolving that string against a live namespace whose directory entries, links, and mounts can change concurrently.

Tech 14 Sep 2026 6 min read

Passkeys Bind Sign-In Credentials to Site Domains

Passwords are portable by design. A person can type the same secret into a legitimate service, a lookalike page, or an unrelated application. That flexibility is convenient, but it also gives phishing pages a chance to collect credentials that can later be replayed against the real service. Passkeys change the shape of sign-in. Instead of sending a reusable secret to a server, a device proves possession of a private key. The matching public key is stored by the service, while the private key remains under control of the user’s authenticator or credential provider.

Go 13 Sep 2026 4 min read

Bound HTTP Request Bodies with http.MaxBytesReader in Go

An HTTP handler that decodes a request body without a byte limit can consume far more input than its application-level schema suggests. A JSON object with three fields may still arrive inside a multi-gigabyte body. Decoder validation controls structure; it does not establish a transport-sized boundary. Go’s http.MaxBytesReader places that boundary directly around the request body. It returns an io.ReadCloser that permits reads up to a configured limit and reports an error when code attempts to read beyond it.

Go 12 Sep 2026 5 min read

Reject Cross-Origin State Changes with http.CrossOriginProtection

A browser can send credentials with a request that was initiated from another site. For state-changing endpoints, accepting that request without checking its origin can expose an application to cross-site request forgery. Go’s net/http package includes CrossOriginProtection for placing that check at an HTTP handler boundary. The type does not attempt to identify every browser request. It applies a specific policy based on request method and cross-origin signals, while allowing requests that lack those browser-origin signals. Its behavior is narrow enough that endpoint semantics still matter.

Go 09 Sep 2026 8 min read

Control Structured Log Output in Go with slog.LogValuer

Passing a struct directly to slog is convenient until that struct grows a field that should never appear in logs. An access token, session secret, internal note, or large payload can turn an ordinary diagnostic line into a security problem or an expensive blob of noise. Go’s slog.LogValuer interface gives a type control over its own structured log representation. Instead of teaching every call site which fields are safe, you can define that representation next to the type and let slog use it wherever the value is logged.

Python 08 Sep 2026 12 min read

Process Template Strings Safely with Python T-Strings

Python’s f-strings are excellent when the desired result is immediately a string. That same immediacy becomes a limitation when an application needs to inspect interpolated values before deciding how they should be represented. Python 3.14 adds template string literals, usually called t-strings, for that boundary. A t-string looks much like an f-string, but it does not immediately collapse its literal text and interpolated values into one str. Instead, it produces a structured Template object from string.templatelib.

Python 08 Sep 2026 8 min read

Inspect ZIP Archives Before Extraction in Python

ZIP extraction looks like a single filesystem operation, but an archive is really a collection of filenames, metadata, and compressed byte streams supplied by whoever created the file. When the archive is untrusted, that metadata belongs at a trust boundary. Python’s zipfile module provides convenient extraction helpers, and those helpers include protections for suspicious path components. The documentation still warns against extracting untrusted archives without prior inspection. That distinction is useful: library normalization is not the same thing as an application-specific acceptance policy.

Go 08 Sep 2026 7 min read

Contain Untrusted File Access in Go with os.Root

Applications often combine a trusted directory with a file name that came from somewhere less trusted: an HTTP request, archive entry, manifest, job message, or database row. The obvious implementation is also a common security boundary mistake: path := filepath.Join("./uploads", userName) f, err := os.Open(path) If userName can select a path outside ./uploads, the application may expose files it never intended to touch. Even careful string validation becomes harder when symbolic links and concurrent filesystem changes enter the picture.

Python 03 Sep 2026 10 min read

Parse and Render Shell Arguments Safely with Python shlex

Command-line text looks deceptively simple. Splitting on spaces works until an argument contains whitespace. Concatenating strings works until a filename contains shell metacharacters. Logging a list of arguments works, but the result may be difficult for a human to copy and inspect. Python’s shlex module handles a useful middle ground: shell-like lexical analysis for Unix-style command text. Its split(), quote(), and join() helpers let programs move deliberately between a string representation and a sequence of argument tokens.

Software Engineering 02 Sep 2026 10 min read

Designing Structured Logs for Production Debugging

Production debugging often starts with a deceptively simple question: what happened to this request? Plain-text logs can answer that question in small systems, but they become difficult to search reliably when message wording changes, multiple services participate in one operation, or operators need to aggregate millions of records. Structured logging addresses that problem by representing important context as named fields instead of embedding everything in prose. The goal is not to turn every variable into a log field. A useful log schema captures stable facts about an event, preserves enough correlation context to connect related work, and avoids recording data that creates security or privacy risk.

Linux 01 Sep 2026 5 min read

Harden systemd Services with Security Directives

A systemd unit can do more than start and restart a process. It can also define a security boundary around the service by restricting filesystem access, Linux capabilities, namespaces, privilege changes, and resource consumption. These controls do not replace application security, but they can reduce the damage caused by a compromised or misbehaving process. Start from the service’s real requirements Hardening works best when it is based on what the process actually needs.

Cybersecurity Updated 10 Sep 2025 2 min read

How to Whitelist IP Address Ranges with .htaccess

.htaccess is useful for more than URL rewriting and caching. It can also provide an additional access-control layer, including restricting an application to specific IP addresses or IP ranges. This technique can be useful when: An application is still in development and should only be available to an internal team. You want to protect sensitive paths such as /admin or /api. A server should only be reachable from an office network or VPN. Whitelist One IP Address To allow only one IP address:

Cybersecurity Updated 10 Sep 2025 2 min read

How to Block IP Ranges with `.htaccess`

One useful feature of Apache is the flexibility of .htaccess. In addition to URL rewriting and caching rules, .htaccess can also restrict access based on IP addresses. If you are dealing with spam bots, brute-force attempts, or unwanted traffic from a particular network, one quick option is to block an individual IP address or an entire range. Block a Single IP Address To block one IP address, use: <RequireAll> Require all granted Require not ip 192.168.1.100 </RequireAll> This blocks 192.168.1.100 while allowing other clients to access the site.

Web Development 03 Sep 2025 3 min read

Automatically Encrypting Eloquent Model Attributes

Applications often store fields that deserve additional protection at rest. Laravel can encrypt selected Eloquent attributes before they are written to the database and decrypt them automatically when they are read. For modern Laravel applications, the built-in encrypted cast is preferable to overriding Eloquent’s magic __get() and __set() methods. It integrates with the model casting system and avoids interfering with Eloquent internals. Basic Implementation Define encrypted attributes in the model’s casts:

Cybersecurity 03 Sep 2025 3 min read

.htaccess Rules to Prevent PHP Execution

Public upload directories are a common security-sensitive part of web applications. If an attacker manages to upload a file such as shell.php and the web server executes it, the upload feature can become a route to remote code execution. On Apache, a directory-specific .htaccess configuration can help prevent script execution in locations that should contain only static files. Why .htaccess Can Help Apache supports .htaccess files for directory-level configuration when the server permits the relevant overrides. This makes it possible to apply security rules to a specific directory without changing every virtual-host setting.