<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[AISec]]></title><description><![CDATA[AISec]]></description><link>https://jeffrey23.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 08 Nov 2026 08:53:44 GMT</lastBuildDate><atom:link href="https://jeffrey23.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Client-Certificate Revocation Needs a Failure Policy, Not a Checkbox]]></title><description><![CDATA[Mutual TLS gives a service a strong signal about the certificate presented by a client. It does not automatically tell the service whether that certificate…]]></description><link>https://jeffrey23.hashnode.dev/client-certificate-revocation-needs-a-failure-policy-not-a-checkbox</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/client-certificate-revocation-needs-a-failure-policy-not-a-checkbox</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sun, 08 Nov 2026 05:41:48 GMT</pubDate><content:encoded><![CDATA[<p>Mutual TLS gives a service a strong signal about the certificate presented by a client. It does not automatically tell the service whether that certificate is still acceptable today. Certificate revocation is a separate status question, answered through OCSP, CRLs, or a short-lived certificate design. The difficult part is not enabling a checker. The difficult part is deciding what the service does when the checker cannot produce a fresh answer.</p>
<p>RFC 9325 describes a familiar operational reality: many TLS clients soft-fail OCSP, meaning they continue a connection when the responder is unavailable. For public web certificates, soft fail has practical tradeoffs. For client certificates that authorize access to an administrative API or a data plane, the same behavior can preserve access after a credential has been reported compromised. The team may believe it has revocation because a status query is configured, while the connection path fails open during an outage.</p>
<p>A useful policy separates three cases. A known-good response permits the connection under the service's normal authorization rules. A revoked or otherwise invalid response rejects it. An unavailable, stale, or malformed response needs a documented decision. High-risk paths should fail closed unless the team has an alternative identity signal with equal strength. Lower-risk paths may allow a bounded grace period, but the exception should be explicit, monitored, and tied to a specific deployment rather than hidden in TLS library defaults.</p>
<p>RFC 6960 defines OCSP request and response semantics. RFC 5280 explains how CRLs and freshness participate in certificate path validation. These are building blocks, not a complete operational model. OCSP stapling can reduce privacy and availability problems because the server presents a signed status response. It still needs a maximum age and a rejection rule. A cached "good" response from before a revocation event is a statement about an earlier moment, not a permanent fact.</p>
<p>Inventory the actual termination point. A load balancer may terminate mTLS, validate the certificate, and forward an identity header to an application. The application might trust a different port, a second proxy, or a service mesh sidecar. Each hop can have a different revocation policy. If the edge fails open but the application assumes the edge enforces revocation, the access decision is weaker than the architecture diagram suggests.</p>
<p>Log the certificate serial number or a stable fingerprint prefix, issuer, validation result, response source, response age, and the policy decision. Do not log the full certificate chain unless needed for a case. Alert on responder errors and on a sudden shift from fresh responses to stale ones. Monitor the response outcome as well as process health. A responder that returns HTTP 200 with an expired response is not healthy from the relying party's perspective.</p>
<p>Short-lived client certificates can reduce the need for revocation, but they do not remove the policy question. A stolen certificate is still usable until expiration unless another control blocks it. Bind the certificate to a workload identity where possible, rotate it automatically, and keep a revocation or deny path for emergencies. If the certificate is used for human access, pair it with device state or an interactive factor for sensitive actions.</p>
<p>Test the failure modes before an incident. Stop the responder in a staging environment. Present a stale response. Present a response signed by the wrong responder. Present a valid certificate with a serial that is not in the local cache. Record whether the connection succeeds and which component made the decision. The expected result should be written in the service's authorization documentation.</p>
<p>mTLS is a strong transport identity primitive. Its value depends on a current and explicit trust decision. A revocation checkbox without a failure policy can create a false sense of control. Teams should prefer a small number of clearly enforced paths, a fresh status rule, and a fail-closed outcome for operations that can change data or configuration.</p>
<h2>References</h2>
<ul>
<li><a href="https://www.rfc-editor.org/rfc/rfc9325.html">RFC 9325: Recommendations for Secure Use of TLS and DTLS</a></li>
<li><a href="https://www.rfc-editor.org/rfc/rfc6960.html">RFC 6960: Online Certificate Status Protocol</a></li>
<li><a href="https://www.rfc-editor.org/rfc/rfc5280.html">RFC 5280: X.509 Certificate and CRL Profile</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Metabase Setup and API Surfaces Need More Than a Title Search]]></title><description><![CDATA[Metabase is often exposed as a reporting portal. The visible login page is only one part of the deployment. The setup flow creates the first administrator…]]></description><link>https://jeffrey23.hashnode.dev/metabase-setup-and-api-surfaces-need-more-than-a-title-search</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/metabase-setup-and-api-surfaces-need-more-than-a-title-search</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sun, 08 Nov 2026 02:24:07 GMT</pubDate><content:encoded><![CDATA[<p>Metabase is often exposed as a reporting portal. The visible login page is only one part of the deployment. The setup flow creates the first administrator, API keys can be created for automation, and SCIM provisioning can connect an identity provider to user and group management. A public Metabase host deserves an inventory that covers those surfaces beyond a title match. The existence of the product does not prove that setup, API, or provisioning endpoints are available without authorization.</p>
<p>For this assessment, ZoomEye count-only queries were collected on November 8, 2026 using <code>sub_type=all</code>, page 1, and page size 1. <code>app="Metabase"</code> returned 117,591. <code>title="Metabase"</code> returned 108,386. <code>http.body="Metabase"</code> returned 196,775. The application and title counts are relatively close, which makes both useful candidate signals. The body count is broader and may include documentation, dashboards, reports, and pages that mention Metabase without running it.</p>
<p>Metabase's API documentation describes a setup flow that reads a setup token from <code>GET /api/session/properties</code> and creates the first admin through <code>POST /api/setup</code>. That flow is expected during first installation. The security question is whether an instance remains in an unfinished state or exposes setup metadata after commissioning. A team should check the setup state through an authorized administrative path, record the result, and confirm that subsequent admin creation is disabled.</p>
<p>API keys need a separate inventory. Metabase documentation places API key creation under Admin settings and authentication. A key can support automation, but it should have an owner, a purpose, and a rotation date. Review whether keys are scoped to an account with more access than the integration needs. Remove unused keys, rotate after staff changes, and avoid placing them in dashboard queries or client-side code. Do not print the key fragment in an incident ticket.</p>
<p>SCIM is another management surface. The documentation describes a SCIM endpoint and a SCIM token that is shown once and can be regenerated. Group and user provisioning can change access at scale. Review which identity provider owns the token, whether deprovisioning events reach Metabase, and whether an emergency local admin remains available. A token that is valid but no longer tied to a supported integration is a cleanup finding, not a reason to disable provisioning without a replacement plan.</p>
<p>The external inventory should compare the Metabase candidate with DNS, certificate, cloud, and application ownership data. Verify whether the host is an internal reporting service, a customer portal, or a marketing site. Check TLS and response headers, then move to authorized configuration review. Do not attempt to create a setup user, call API endpoints with guessed credentials, or enumerate tenant data.</p>
<p>The count differences also help plan sampling. The app query gives a product-oriented population. The title query gives a page-title population that may include deployments missed by the app fingerprint. The body query is a broad net that should not be treated as a list of exposed Metabase instances. A team can sample each group, confirm ownership, and compare the observed host with the internal reporting catalog.</p>
<p>Metabase's value comes from making data accessible. Its setup, API, and provisioning surfaces are part of that value. The exposure review should verify that each surface has an owner, an authentication rule, and a lifecycle. A product count starts the inventory. It does not replace the setup state and token review.</p>
<h2>Query evidence</h2>
<ul>
<li>Collection: 2026-11-08 00:44 UTC, ZoomEye SDK, <code>sub_type=all</code>, page 1, page size 1.</li>
<li><code>app="Metabase"</code>: 117,591.</li>
<li><code>title="Metabase"</code>: 108,386.</li>
<li><code>http.body="Metabase"</code>: 196,775.</li>
</ul>
<h2>References</h2>
<ul>
<li><a href="https://www.metabase.com/articles/set-up-metabase-from-code-with-the-api">Metabase: Set up from code with the API</a></li>
<li><a href="https://www.metabase.com/docs/latest/people-and-groups/user-provisioning">Metabase: User provisioning with SCIM</a></li>
<li><a href="https://www.metabase.com/docs/latest/ai/agent-api">Metabase: Agent API and authentication</a></li>
<li><a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJNZXRhYmFzZSI%3D">ZoomEye app query</a></li>
<li><a href="https://www.zoomeye.ai/searchResult?q=dGl0bGU9Ik1ldGFiYXNlIg%3D%3D">ZoomEye title query</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Apache James WebAdmin: inventory the control plane before it is exposed]]></title><description><![CDATA[Apache James is a mail server, and its WebAdmin interface is a management API for mailboxes, domains, users, and server tasks. The control plane is not a…]]></description><link>https://jeffrey23.hashnode.dev/apache-james-webadmin-inventory-the-control-plane-before-it-is-exposed</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/apache-james-webadmin-inventory-the-control-plane-before-it-is-exposed</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 23:01:36 GMT</pubDate><content:encoded><![CDATA[<p>Apache James is a mail server, and its WebAdmin interface is a management API for mailboxes, domains, users, and server tasks. The control plane is not a secondary feature. Its routes can create users, change mailbox data, and trigger operations that affect the mail service.</p>
<p>On 2026-11-08, ZoomEye count-only probes returned 3,036 matches for <code>app="Apache James"</code>, 2 for <code>title="Apache James"</code>, and 75 for <code>http.body="Apache James"</code>. The scope was <code>sub_type=all</code>, page 1, and page size 1. The application signal is far stronger than the title and body signals, but it still identifies product presence rather than the exposed WebAdmin route.</p>
<h2>The documented default is the finding</h2>
<p>Apache James WebAdmin configuration documentation states that JWT authentication is disabled by default. In that state, anyone who can reach the WebAdmin API can access it without restrictions. The documentation explicitly advises administrators to enable JWT or disable the WebAdmin interface to prevent unrestricted access to user data and server operations.</p>
<p>This is a design-level exposure, not a claim that every observed James host has an open WebAdmin endpoint. The endpoint may be bound to localhost, blocked by a firewall, or disabled. The count tells an operator where to look. The configuration and reachability test determine whether the control plane is actually exposed.</p>
<p>The WebAdmin documentation also notes that it has no notion of administrator identity and models several destructive operations as task actions. Route-level authorization in a reverse proxy can help, but only if the proxy knows which method, path, and parameters belong to a permitted operation. A broad <code>admin</code> role at the proxy is not equivalent to least privilege inside James.</p>
<h2>A review sequence that starts at the network edge</h2>
<p>Map the public mail ports and the WebAdmin port separately. Confirm the listener address, proxy route, TLS termination, and authentication method. From an external test location, try to reach the WebAdmin base path and record the response. Do not invoke a mailbox, domain, or task-changing endpoint during discovery.</p>
<p>If WebAdmin is required, enable JWT authentication and distribute the private key with restrictive permissions. Disable the interface when it is not needed. Place it behind a management network or a reverse proxy that strips client-supplied authentication headers and enforces an explicit route policy.</p>
<p>List the integrations that call WebAdmin. Each integration should have its own credential and a documented set of allowed operations. Rotate keys after exposure and verify that old tokens fail. Review logs for mailbox creation, user changes, domain changes, and task execution.</p>
<h2>Why title and body counts are low</h2>
<p>The James mail service may not display a recognizable title, and much of its traffic is not an HTTP page. The app fingerprint is therefore more useful for product inventory than title or body text. However, an app match can include a mail listener that has no WebAdmin route at all. The operator must distinguish service presence from management-plane exposure.</p>
<p>Search: <a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJBcGFjaGUgSmFtZXMi">ZoomEye application fingerprint for Apache James</a></p>
<p>WebAdmin is a strong example of an exposure where a single configuration default matters more than a long vulnerability list. Find the route, determine whether authentication is enabled, and remove the management path from the public network if it is not deliberately published.</p>
<h2>References</h2>
<ul>
<li>Apache James, <a href="https://james.apache.org/server/config-webadmin.html">WebAdmin Configuration</a></li>
<li>Apache James, <a href="https://james.apache.org/server/manage-webadmin.html">Web administration</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Prioritizing Axios CVE-2026-42037 Across a Node.js Estate]]></title><description><![CDATA[Large Node.js estates often contain hundreds of services with different exposure, data paths, and owners. CVE-2026-42037 should be prioritized with more…]]></description><link>https://jeffrey23.hashnode.dev/prioritizing-axios-cve-2026-42037-across-a-node-js-estate</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/prioritizing-axios-cve-2026-42037-across-a-node-js-estate</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 19:42:01 GMT</pubDate><content:encoded><![CDATA[<p>Large Node.js estates often contain hundreds of services with different exposure, data paths, and owners. CVE-2026-42037 should be prioritized with more than CVSS alone. The score is 5.3, but the practical decision depends on whether an application forwards attacker-controlled Blob metadata through affected Axios and whether a downstream parser trusts the resulting multipart headers.</p>
<p>The issue affects Axios 1.0.0 through releases before 1.15.1. The vulnerable code inserts <code>Blob.type</code> into a multipart part header without removing CR or LF. The official fix is in the 1.15.1 release, with pull request #10758 documenting CR/LF stripping, defaults for missing types, and filename encoding.</p>
<h2>Separate inventory from reachability</h2>
<p>Build an inventory of deployed Axios versions from package locks, images, serverless bundles, and runtime package listings. Mark every copy below 1.15.1. Then classify each owner by reachability.</p>
<p>A high-reachability service accepts uploads from untrusted users and forwards file objects through Axios. Medium reachability covers internal upload relays that receive input from another untrusted path. Low reachability covers services with fixed application-created Blob types or no multipart forwarding. A browser-only bundle has a different runtime context and should be documented rather than mixed with server-side findings.</p>
<p>Make the deployment artifact the source of truth. A repository update that has not been built, deployed, and observed in production does not reduce current exposure.</p>
<h2>Add consequence to the score</h2>
<p>The advisory lists possible Content-Type filter bypass, parser confusion, and phantom form fields. Add a downstream-consequence field to the risk record. Does the receiver use part metadata for routing, access, file classification, or storage? Does a parser error stop the request, or does the service continue with the injected value?</p>
<p>A service that forwards to a strict content-inspecting receiver may have a lower consequence than a gateway that routes files by client-declared type. The CVSS metrics describe low integrity impact and no confidentiality or availability impact for the library issue, but a downstream parser can change the application outcome. State both facts and avoid quoting the library score as the business risk.</p>
<h2>Use short remediation waves</h2>
<p>Wave one covers internet-facing upload proxies with attacker-controlled types and a downstream policy that trusts multipart metadata. Upgrade them to Axios 1.15.1 or later, rebuild, deploy, and run a negative CRLF test.</p>
<p>Wave two covers reachable services with constrained metadata or internal-only exposure. Apply the same dependency and validation controls on a planned schedule. Wave three covers package presence without a server-side reachable path; patch for hygiene and document the evidence for deferral.</p>
<p>Each wave should have an owner, service list, build digest, deployment date, and verification result. Avoid closing an entire package because one service uses a safe constant type. Avoid leaving a service open because its CVSS score looks moderate.</p>
<h2>Add durable controls</h2>
<p>At the upload boundary, validate the full MIME value and filename. Reject CR and LF, then apply an allowlist where the expected file formats are known. Replace client metadata with a canonical internal type when the service does not need the original value.</p>
<p>At the receiver, validate the part metadata and file content required for the local security policy. At the build layer, pin Axios to a fixed version and test lockfile resolution. Use dependency alerts for discovery and integration tests for reachability.</p>
<h2>Report exploitation accurately</h2>
<p>The advisory contains a public proof of concept. CISA enrichment marks exploitation as <code>poc</code> and automatable as <code>no</code>. No KEV listing or active exploitation was verified in this review. A vulnerable deployed package is a risk condition; an exploited service requires evidence that the unsafe path was used and produced a consequence.</p>
<h2>Exposure context</h2>
<p>ZoomEye Search <code>app="Node.js"</code> returned 5,548,145 fingerprint matches. The exact <code>vul.cve="CVE-2026-42037"</code> Filter returned 0. The broad Search count is not an estate inventory and does not prove that an Axios instance is present. Use internal SBOM and runtime data for remediation decisions.</p>
<h2>Portfolio completion check</h2>
<p>A credible completion report shows the fixed package version in each deployed artifact, the upload routes reviewed, the receiver policies checked, and a passing negative multipart test. It also records the services excluded and the code evidence behind each exclusion. That level of detail lets security and engineering teams defend the prioritization and verify that the fix reached production.</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/axios/axios/security/advisories/GHSA-445q-vr5w-6q77">GitHub advisory GHSA-445q-vr5w-6q77</a></li>
<li><a href="https://github.com/axios/axios/releases/tag/v1.15.1">Axios v1.15.1 release</a></li>
<li><a href="https://github.com/axios/axios/pull/10758">Axios pull request #10758</a></li>
<li><a href="https://www.cert.cyber.gouv.fr/avis/CERTFR-2026-AVI-1378/">CERT-FR advisory CERTFR-2026-AVI-1378</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[From ShinyHunters IOCs to Confirmed Compromise: Where External Search Stops]]></title><description><![CDATA[An IP address in a threat report is a lead. It is not a finding. Mandiant published network indicators associated with the PeopleSoft exploitation…]]></description><link>https://jeffrey23.hashnode.dev/from-shinyhunters-iocs-to-confirmed-compromise-where-external-search-stops</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/from-shinyhunters-iocs-to-confirmed-compromise-where-external-search-stops</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 16:21:26 GMT</pubDate><content:encoded><![CDATA[<p>An IP address in a threat report is a lead. It is not a finding. Mandiant published network indicators associated with the PeopleSoft exploitation campaign, including <code>5.199.162.157</code>, <code>104.219.234.138</code>, <code>162.219.30.165</code>, and <code>winmanage-me.network</code>. Those values help defenders search logs and endpoint telemetry. They do not prove that every system querying or appearing near that infrastructure is compromised.</p>
<p>ZoomEye returned zero all-asset records for <code>domain="winmanage-me.network"</code> on November 7, 2026. A zero in one collection window does not establish that the domain was inactive, harmless, or absent from private telemetry. Search indices change, and malicious infrastructure can be filtered, moved, or configured not to expose a scan-friendly service.</p>
<h2>Use IOCs for investigation, not decoration</h2>
<p>Begin with the internal evidence path. Review WebLogic access logs for encoded PSEMHUB requests. Look for unexpected JSP files in the PSEMHUB application directory, process creation under the WebLogic account, and outbound connections from the PeopleSoft tier. Compare DNS, proxy, firewall, and endpoint logs with the published indicators.</p>
<p>A match in a log is still not proof of full compromise. It tells the team where to look next. Preserve the host, user, process, command line, parent process, destination, and timestamp. Check whether the activity was approved maintenance or a security test. Escalate when the evidence aligns with the exploit path or post-exploitation behavior described by Mandiant.</p>
<h2>Avoid false certainty from external counts</h2>
<p>An external search can confirm that a domain or IP appears in indexed public data. It cannot see internal DNS resolution, proxy logs, or endpoint processes. It also cannot prove that a host was clean because no public record matched.</p>
<p>The reverse inference is equally risky. A public PeopleSoft title, a certificate containing the product name, or a WAF block count does not show that an attacker reached PSEMHUB. Oracle's patch status and the application owner's log review answer different questions.</p>
<p>The <a href="https://www.zoomeye.ai/searchResult?q=ZG9tYWluPSJ3aW5tYW5hZ2UtbWUubmV0d29yayI%3D">staging-domain search</a> can be recorded as a zero-result observation. The investigation should continue in the systems that hold the relevant telemetry.</p>
<h2>Build a defensible conclusion</h2>
<p>A strong incident note separates four states:</p>
<ol>
<li>The IOC is published by a reliable source.</li>
<li>The IOC appears in an external scan or public response.</li>
<li>The IOC appears in the organization's logs.</li>
<li>The host shows post-exploitation evidence and the incident owner confirms compromise.</li>
</ol>
<p>The ShinyHunters reporting supplies the first state. ZoomEye can sometimes supply the second. Only the organization's telemetry and forensic review can supply the last two.</p>
<p>This boundary protects both the investigation and the people affected by it. External visibility narrows the search. Confirmed compromise requires evidence from the environment that was attacked.</p>
<h2>References</h2>
<ul>
<li><a href="https://cloud.google.com/blog/topics/threat-intelligence/shinyhunters-renewed-mass-exploitation-campaign-targeting-oracle-peoplesoft">Mandiant and GTIG analysis with network indicators</a></li>
<li><a href="https://www.bleepingcomputer.com/news/security/shinyhunters-uses-waf-bypass-trick-in-oracle-peoplesoft-attacks/">BleepingComputer report on the WAF bypass and post-exploitation tooling</a></li>
<li><a href="https://www.oracle.com/security-alerts/alert-cve-2026-35273.html">Oracle Security Alert Advisory for CVE-2026-35273</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[SAML signature wrapping tests at the signed-reference boundary]]></title><description><![CDATA[A SAML response can contain a cryptographically valid XML Signature while the application consumes an assertion the signature never protected. This is the…]]></description><link>https://jeffrey23.hashnode.dev/saml-signature-wrapping-tests-at-the-signed-reference-boundary</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/saml-signature-wrapping-tests-at-the-signed-reference-boundary</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 13:02:19 GMT</pubDate><content:encoded><![CDATA[<p>A SAML response can contain a cryptographically valid XML Signature while the application consumes an assertion the signature never protected. This is the practical danger behind signature wrapping. The parser verifies one element, another element carries the attacker's identity, and both paths look reasonable to developers reading only the happy case.</p>
<h2>The failure pattern</h2>
<p>An XML Signature contains a <code>Reference</code> that identifies the data covered by the digest. Validation succeeds only when the referenced bytes, canonicalization and digest calculation all agree. Wrapping attacks exploit a mismatch between that verified reference and the element the application later trusts.</p>
<p>Duplicate assertions, copied identifiers or a signature placed beside rather than over the assertion can create the gap. A common mistake is to search the document for the first assertion and validate the first signature independently. The application then reads a second assertion whose identifier appears inside the signed material but whose content is not covered by the selected signature.</p>
<h2>Make the trust decision explicit</h2>
<p>Validate the signature, then return the exact signed assertion object to the authorization code. Do not re-query the XML tree for an assertion by identifier. Reject multiple top-level assertions unless the profile explicitly permits them, reject duplicate identifiers, and reject signatures that cover an object other than the assertion being consumed.</p>
<p>Check the signed subject, audience and recipient against the local service provider. Confirm that any <code>InResponseTo</code> value matches an outstanding authentication request when the profile uses one. Apply time conditions after signature verification and use parser settings that disable external entities and unrelated network resolution.</p>
<p>Canonicalization needs the same discipline. A verifier that normalizes one subtree while the application reads another can reintroduce the mismatch. Keep signature verification inside a reviewed library, pass the verified node forward, and avoid custom XML string manipulation around identifiers.</p>
<h2>Test the negative tree</h2>
<p>Build negative tests with two assertions sharing an identifier, a valid signature over a benign assertion followed by a privileged assertion, a modified <code>Audience</code> value and an assertion moved outside its signed response. Each test should fail before user lookup or session creation.</p>
<p>Log the reference URI, the identifier of the assertion selected for authorization and the signature result. Do not log complete assertions because they can contain personal data and bearer attributes.</p>
<p>The check is simple to state: the assertion that creates the session must be the assertion the signature proves. Any application path that loses that relationship should be treated as an authentication boundary failure.</p>
<h2>References</h2>
<ul>
<li><a href="https://docs.oasis-open.org/security/saml/v2.0/saml-sec-consider-2.0-os.pdf">SAML V2.0 Security and Privacy Considerations</a></li>
<li><a href="https://www.w3.org/TR/xmldsig-core1/">XML Signature Syntax and Processing Version 1.1</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Sidero Omni shows why zero-result scans need an evidence record]]></title><description><![CDATA[A zero result from an internet search engine is easy to misread. It can mean that no matching assets are exposed to the scanner, that the product does not…]]></description><link>https://jeffrey23.hashnode.dev/sidero-omni-shows-why-zero-result-scans-need-an-evidence-record</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/sidero-omni-shows-why-zero-result-scans-need-an-evidence-record</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 09:40:46 GMT</pubDate><content:encoded><![CDATA[<p>A zero result from an internet search engine is easy to misread. It can mean that no matching assets are exposed to the scanner, that the product does not publish a stable fingerprint, or that authentication redirects and network controls keep the management surface off the indexed internet. Sidero Omni provides a useful example because its control plane is designed around identity and service-provider flows rather than a public product landing page.</p>
<h2>What the measurement showed</h2>
<p>On 2026-11-07 UTC, page-one count-only ZoomEye probes with <code>sub_type=all</code> returned zero for <code>app="Sidero Omni"</code> and zero for <code>title="Sidero Omni"</code>. The queries were executed with page size 1, so the counts describe the engine's match total, not the number of records retrieved.</p>
<p>Those observations do not establish that no Omni deployments exist. They establish only that these two exact field queries produced no confirmed matches at that time. A production deployment can be behind SSO, a VPN, an IP allowlist or a reverse proxy that does not expose a distinctive title. The absence of an indexed page is not evidence of secure configuration.</p>
<h2>What the control plane exposes</h2>
<p>Omni supports SAML and OIDC identity flows and can issue temporary client certificates after authentication. Service accounts provide token-based access for automation. The default service-account lifetime is one year and the account uses the role of its creating user, so the creating identity and the intended workload should be explicit.</p>
<p>Inventory should track service accounts separately from human identities. Record the owner, purpose, role, creation time, expiry and last use. A long-lived automation credential created by an administrator can outlive the project that needed it. Prefer a dedicated creator and a review date when the deployment offers that choice.</p>
<h2>Use the zero result as a baseline</h2>
<p>Store the query, field, scope, time and result. Repeat the same query later and report changes rather than treating either zero or a new positive match as proof of compromise. Compare the public observation with the organization's own cloud inventory, identity-provider application list and DNS records.</p>
<p>For each owned Omni endpoint, verify that external access requires the intended identity flow, that service-account tokens have a bounded purpose and that stale accounts are disabled. Test a user without the required role and a token after its planned expiry.</p>
<p>The scan is useful because it creates a dated baseline. Its limitation must travel with the count.</p>
<h2>References</h2>
<ul>
<li><a href="https://omni.siderolabs.com/explanation/authentication-and-authorization">Omni: Authentication and Authorization</a></li>
<li><a href="https://omni.siderolabs.com/how-to-guides/create-an-omni-service-account">Omni: Create a Service Account</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Network Block Device exposure puts storage access before application login]]></title><description><![CDATA[Network Block Device (NBD) lets a Linux client use a remote server as a block device. The design is useful for migration, testing and storage provisioning…]]></description><link>https://jeffrey23.hashnode.dev/network-block-device-exposure-puts-storage-access-before-application-login</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/network-block-device-exposure-puts-storage-access-before-application-login</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 06:22:22 GMT</pubDate><content:encoded><![CDATA[<p>Network Block Device (NBD) lets a Linux client use a remote server as a block device. The design is useful for migration, testing and storage provisioning, but it changes the security question. A remote file share exposes files. An NBD connection exposes a block device that the client can read or write directly.</p>
<p>The kernel documentation describes the TCP version of NBD and points to separate user-space client and server tools. The basic protocol should not be treated as a private storage bus merely because the service uses a nonstandard port. Exposure depends on the server, the export and the transport controls around it.</p>
<h2>Authentication is not implied</h2>
<p>Transport security is a deployment choice. nbdkit documentation describes TLS support for authentication and encryption, and notes that client certificates are not checked unless peer verification is configured. A TLS listener without peer verification protects the channel less completely than an operator may assume.</p>
<p>Use TLS with a verified server certificate, and add a client certificate or a protected pre-shared key where the server supports it. Pin the expected server identity in the client configuration. Keep the server certificate private key off the storage host when the deployment can use a separate TLS terminator.</p>
<h2>Limit the export, not just the port</h2>
<p>Create one export per purpose and keep read-only snapshots separate from writable volumes. Restrict the server to storage clients by address and network policy. Do not expose NBD through a general reverse proxy or a public load balancer. Logging should record the client identity, export name, connection time and bytes transferred without recording encryption secrets.</p>
<p>On the client, inventory every configured NBD device, its server address, export name, mount policy and data owner. A stale device definition can reconnect after a reboot even if the original migration ended. Remove unused devices and ensure that the client refuses an unencrypted connection when the policy requires TLS.</p>
<h2>Respond as a storage incident</h2>
<p>If an NBD endpoint is exposed unexpectedly, first isolate the network path and prevent new sessions. Preserve server and proxy logs, identify the export and determine whether the protocol allowed writes. Take a snapshot through the storage provider before mounting or repairing the volume.</p>
<p>Rotate credentials and encryption keys, validate the client list and review the data for unauthorized changes. Restoring an older snapshot may also roll back legitimate writes, so coordinate recovery with the application owner. Rebuild the storage host if the management plane or TLS private key was accessible.</p>
<p>An NBD inventory should answer who can connect, which block range they receive and whether the channel is cryptographically authenticated. A port scan alone does not answer those questions.</p>
<h2>References</h2>
<ul>
<li><a href="https://docs.kernel.org/admin-guide/blockdev/nbd.html">Linux kernel: Network Block Device</a></li>
<li><a href="https://manpages.ubuntu.com/manpages/noble/man1/nbdkit-tls.1.html">nbdkit-tls: authentication and encryption for NBD</a></li>
<li><a href="https://manpages.ubuntu.com/manpages/noble/man3/nbd_set_tls.3.html">libnbd: TLS connection settings</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Teedy inventory should start with guest access and the first administrator account]]></title><description><![CDATA[Teedy is a document management system that combines document storage, search, user and group permissions, and a REST API. Its deployment defaults deserve…]]></description><link>https://jeffrey23.hashnode.dev/teedy-inventory-should-start-with-guest-access-and-the-first-administrator-account</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/teedy-inventory-should-start-with-guest-access-and-the-first-administrator-account</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Sat, 07 Nov 2026 03:02:05 GMT</pubDate><content:encoded><![CDATA[<p>Teedy is a document management system that combines document storage, search, user and group permissions, and a REST API. Its deployment defaults deserve attention because a document service can expose business records before an operator has finished configuring users.</p>
<p>The project documentation and README describe guest login and an initial administrator credential in self-hosted examples. Those are setup aids, not a production baseline. A release or container may change defaults, so the operator should confirm the deployed version and configuration rather than assuming one README applies to every build.</p>
<h2>Measurement evidence</h2>
<p>On 2026-11-07 UTC, page-one count-only ZoomEye probes with <code>sub_type=all</code> returned one match for <code>app="Teedy"</code>, 6,718 for <code>title="Teedy"</code> and 137,442 for <code>http.body="Teedy"</code>. The title and body counts are much broader than the application fingerprint. They should be treated as discovery leads, not as a population of unauthenticated document servers.</p>
<h2>Check guest and administrator paths</h2>
<p>Test anonymous access to the base page, search, document listing and document download. Guest read access may be intentional for a public archive, but it should not apply to every collection by accident. Verify the first administrator credential has been changed and that startup environment variables do not recreate a known password during deployment.</p>
<p>Map users, groups and document permissions. Test a user who belongs to one group but not another, then test the API with the same identity. A browser page that hides a button does not prove the API denies the operation. Record share links, document ownership and any external LDAP or OIDC provider.</p>
<h2>Treat the API as a separate surface</h2>
<p>Programmatic access needs its own token inventory, expiry and revocation path. The project documentation describes REST API access and recent self-hosting guidance describes API-key authentication. Confirm the exact behavior for the deployed version, then test that a revoked token fails and that a disabled user cannot continue through a cached session.</p>
<p>Monitor guest document access, administrator logins, permission changes, failed API calls and large downloads. After an exposure, disable guest access if it is not required, rotate administrator and API credentials, preserve audit logs and review which documents were readable. Changing the page template alone will not remove a direct API path.</p>
<p>The useful record is not just that Teedy is reachable. It is who can read which document and through which interface.</p>
<h2>References</h2>
<ul>
<li><a href="https://teedy.io/">Teedy: project overview</a></li>
<li><a href="https://github.com/sismics/docs/blob/master/README.md">Teedy: self-hosted project documentation</a></li>
<li><a href="https://github.com/fmaass/teedy-docs">Teedy documentation fork: authentication and API notes</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[SET SESSION AUTHORIZATION Changes More Than the Current Role]]></title><description><![CDATA[PostgreSQL exposes two identities in a session: the authenticated session user and the current user used for permission checks. SET SESSION AUTHORIZATION…]]></description><link>https://jeffrey23.hashnode.dev/set-session-authorization-changes-more-than-the-current-role</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/set-session-authorization-changes-more-than-the-current-role</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Fri, 06 Nov 2026 23:45:10 GMT</pubDate><content:encoded><![CDATA[<p>PostgreSQL exposes two identities in a session: the authenticated session user and the current user used for permission checks. <code>SET SESSION AUTHORIZATION</code> can change both. That makes it useful for controlled administrative work and dangerous when a connection pool or diagnostic query treats session state as immutable.</p>
<h2>Two names, different questions</h2>
<p>The session user identifier begins as the user name supplied by the client. The current user identifier normally starts equal to it, but can change in <code>SECURITY DEFINER</code> functions or through <code>SET ROLE</code>. PostgreSQL permission checks use the current user.</p>
<p>An audit query such as <code>SELECT current_user</code> answers which role is active. Add <code>session_user</code> to see the authenticated identity:</p>
<pre><code class="language-sql">SELECT session_user, current_user, current_setting('role');
</code></pre>
<p><code>session_user</code> is not a replacement for application-level attribution. It still describes the database connection identity, which may be a shared service account.</p>
<h2>The command has a privilege boundary</h2>
<p>The PostgreSQL manual states that only a session opened by a superuser can change the session user to an arbitrary name. A non-superuser session can set session authorization only to its own authenticated name. <code>DEFAULT</code> and <code>RESET</code> restore the originally authenticated name and can be run by any user.</p>
<p><code>SET SESSION AUTHORIZATION</code> cannot be used inside a <code>SECURITY DEFINER</code> function. The manual also explains that it changes the roles available to later <code>SET ROLE</code> commands. A review that checks only <code>current_user</code> after a function returns can miss the session-level change.</p>
<h2>Treat connection state as data</h2>
<p>Connection pools reuse sessions. Before a pooled connection returns to the application, reset transaction state and verify that role, search path, temporary objects, and other session-local settings match the pool policy. The exact reset method depends on the pool and application. Test it instead of assuming that a transaction rollback restores every setting.</p>
<p>Use separate database roles for separate responsibilities. Grant membership only where the application must switch roles. Avoid giving a shared login the right to assume broad administrative roles when a narrower owner role works.</p>
<h2>Evidence to collect</h2>
<p>For each application path that changes identity, record:</p>
<ol>
<li>The authenticated <code>session_user</code>.</li>
<li>The intended <code>current_user</code>.</li>
<li>The role membership that authorizes the change.</li>
<li>The queries or functions executed under each identity.</li>
<li>The reset step before connection reuse.</li>
</ol>
<p>Test direct connections, pooled connections, transaction retries, and error paths. Query <code>session_user</code>, <code>current_user</code>, and <code>current_setting('role')</code> at the start and end of each test.</p>
<p>The review is complete when the expected identity and privilege path are visible in evidence. A successful login alone does not prove that later statements ran with the intended authority.</p>
<h2>References</h2>
<ul>
<li><a href="https://www.postgresql.org/docs/current/sql-set-session-authorization.html">PostgreSQL: SET SESSION AUTHORIZATION</a></li>
<li><a href="https://www.postgresql.org/docs/current/sql-set-role.html">PostgreSQL: SET ROLE</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[CVE-2026-115560 Evidence Review: What Operators Can Confirm Today]]></title><description><![CDATA[An effective vulnerability response separates what the vendor published from what the internet can observe and what a local team can prove. CVE-2026-115560…]]></description><link>https://jeffrey23.hashnode.dev/cve-2026-115560-evidence-review-what-operators-can-confirm-today</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/cve-2026-115560-evidence-review-what-operators-can-confirm-today</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Fri, 06 Nov 2026 17:01:14 GMT</pubDate><content:encoded><![CDATA[<p>An effective vulnerability response separates what the vendor published from what the internet can observe and what a local team can prove. CVE-2026-115560 has a clear mitigation and a narrow set of conditions, but its full technical advisory is still pending. That makes evidence discipline more important than a dramatic risk label.</p>
<h2>Vendor evidence</h2>
<p>PHP published the informational notice on October 23, 2026. The exact condition involves configuration that sets <code>session.serialize_handler</code> to <code>php_binary</code> or <code>php_serialize</code>, followed by a runtime <code>ini_set()</code> change to <code>php</code> before <code>session_start()</code>. Session upload progress must be enabled. PHP calls the RCE vector unlikely and recommends disabling upload progress until the next regular bugfix release.</p>
<p>The notice says applications that never change the handler at runtime can keep the feature enabled. It also says a full advisory will follow. It does not publish a complete affected-version list, a CVSS score, or a detailed exploitation narrative. Those are absences in the record, not invitations to fill them with assumptions.</p>
<h2>Vendor corroboration</h2>
<p>Red Hat describes the mitigation as fully protective for this issue and explains how to enforce it for FPM and Apache. It recommends <code>php_admin_value</code>, auditing local overrides, checking the web configuration rather than the CLI, and restarting workers. cPanel notes that affected versions remain unknown because the full advisory has not been released.</p>
<p>The sources agree on the narrow condition and the temporary control. They do not turn the issue into a broad claim that every PHP installation is exploitable. cPanel's explicit version gap and PHP's promise of a later advisory should both be preserved.</p>
<h2>External measurement</h2>
<p>The selected ZoomEye Search was <code>app="PHP"</code>. It returned 111,111,696 product fingerprint matches on November 6, 2026. That is a broad PHP population count, not a count of installations that meet the configuration conditions for CVE-2026-115560. The separate Filter <code>vul.cve="CVE-2026-115560"</code> returned zero. The Search count is therefore the Exposure value, but it must not be read as confirmed vulnerable assets.</p>
<p>The Search link is <a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJQSFAi">ZoomEye</a>.</p>
<h2>Local evidence</h2>
<p>The only way to confirm a local match is to inspect the effective configuration and application path. Find the initial handler, the runtime change, the session start order, and the upload progress setting. Confirm the values in the production SAPI and record the deployment identity. If the code path is unreachable, record the network or application control that limits access.</p>
<p>This evidence should be timestamped. A later PHP release may change the version matrix, and a later deployment may change the handler behavior. A useful record includes the application owner, environment, evidence source, control status, and next review date.</p>
<h2>Action</h2>
<p>Disable session upload progress where the condition may exist, enforce the setting outside application control, restart workers, and test upload behavior. Continue to track the next regular PHP release for the complete fix and advisory. Avoid describing the external count as confirmed vulnerable systems, and avoid describing the absence of a CVE Filter result as proof that no local match exists.</p>
<h2>References</h2>
<ul>
<li><a href="https://www.php.net/archive/2026.php#2026-10-23-1">PHP informational advisory: Session upload progress</a></li>
<li><a href="https://www.openwall.com/lists/oss-security/2026/10/23/23">oss-security notice for CVE-2026-115560</a></li>
<li><a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-013">Red Hat request handling memory corruption bulletin</a></li>
<li><a href="https://support.cpanel.net/hc/en-us/articles/44488655369367-PHP-Security-Release-CVE-2026-115560">cPanel PHP security release note</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Penpot Team Webhooks Need the Same Review as Access Tokens]]></title><description><![CDATA[A Penpot team webhook can send design events to another service. An access token can read or modify the same team's data through the API. Both are…]]></description><link>https://jeffrey23.hashnode.dev/penpot-team-webhooks-need-the-same-review-as-access-tokens</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/penpot-team-webhooks-need-the-same-review-as-access-tokens</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Fri, 06 Nov 2026 13:41:43 GMT</pubDate><content:encoded><![CDATA[<p>A Penpot team webhook can send design events to another service. An access token can read or modify the same team's data through the API. Both are integration controls, but teams often review the token and forget the webhook. Depending on the team role and feature flags, an administrator may be able to configure an outbound destination that receives file, comment, or project events.</p>
<p>Penpot's team roles are Viewer, Editor, Admin, and Owner. Admins can manage membership and team settings. Owners can change any member's role, including transferring ownership, and can delete the team. The integration guide says webhooks are configured at team level and can post event data to a service the team controls. The configuration guide also makes clear that access tokens and webhooks depend on deployment feature flags.</p>
<h2>Model the integration boundary</h2>
<p>List every enabled webhook by team, destination, event set, secret handling, and owner. Verify that the destination belongs to an approved service and that its URL does not contain an unmanaged credential. If the payload includes file names, comments, or user identities, classify that data before enabling delivery.</p>
<p>A webhook endpoint should authenticate the sender, reject replayed requests, and validate the payload. Penpot payload format and signature support may vary by version, so test the exact deployment rather than assuming a generic signature header. Store the receiver's secret in a secret manager and rotate it with an overlap window.</p>
<h2>Access-token review</h2>
<p>Access tokens are an alternative to interactive login for internal API use. Tie each token to a named automation account or an owner with a review date. Check whether the token can be scoped and whether the deployment requires a feature flag that may be turned off after an upgrade. A token that works in staging but not production often indicates a configuration difference rather than a permission bug.</p>
<p>Use the team role model to limit who can create integrations. An Editor may need to edit files but should not automatically be able to change the team's outbound webhook. Review this in the application and at the reverse proxy or identity provider where the role is sourced.</p>
<h2>What the ZoomEye observation shows</h2>
<p>The search used <code>sub_type=all</code>, page 1, and page size 1. <code>app="Penpot"</code> returned no matches, <code>title="Penpot"</code> returned 3,774, and <code>http.body="Penpot"</code> returned 4,415. A public title match is a lead for an exposed design service, but it does not establish whether webhooks or access tokens are enabled. The body count is broad enough to include documentation and templates.</p>
<p>For owned deployments, correlate the public hostname with certificate inventory, asset tags, and DNS. If the service should be internal, verify that the reverse proxy blocks both the UI and the API, not just the dashboard path.</p>
<h2>Validate the failure modes</h2>
<p>Test a disabled webhook, a receiver timeout, a rejected payload, and a retry. Confirm that the failure does not leak the secret or send duplicate events in a way the receiver treats as a new action. Test token revocation and disabled feature flags. Review logs for outbound destination changes, team-role changes, and repeated delivery failures.</p>
<p>The design goal is simple: only the intended team can create an integration, only the intended receiver can consume it, and removing either side takes effect quickly.</p>
<h2>References</h2>
<ul>
<li><a href="https://help.penpot.app/user-guide/account-teams/teams/">Penpot teams and roles</a></li>
<li><a href="https://help.penpot.app/technical-guide/integration/">Penpot integration guide</a></li>
<li><a href="https://help.penpot.app/technical-guide/configuration/">Penpot configuration</a></li>
<li><a href="https://www.zoomeye.ai/">ZoomEye search</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[SimpleSAMLphp Metadata Signing Needs a Certificate Lifecycle]]></title><description><![CDATA[SimpleSAMLphp can sign the metadata it generates and can validate signed metadata from other entities. That makes certificates part of the federation trust…]]></description><link>https://jeffrey23.hashnode.dev/simplesamlphp-metadata-signing-needs-a-certificate-lifecycle</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/simplesamlphp-metadata-signing-needs-a-certificate-lifecycle</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Fri, 06 Nov 2026 00:02:28 GMT</pubDate><content:encoded><![CDATA[<p>SimpleSAMLphp can sign the metadata it generates and can validate signed metadata from other entities. That makes certificates part of the federation trust model. A valid signature only says that a known key signed the document. Operators still need to decide which keys are trusted, how metadata is refreshed, and what happens when a certificate expires or changes.</p>
<h2>Signing and verification are separate jobs</h2>
<p>SimpleSAMLphp's advanced feature documentation describes enabling metadata signing and configuring a private key and certificate. Remote metadata sources can specify the certificate files used to verify a signature. The signing key protects the metadata an identity provider or service provider publishes. The verification key protects what a consumer accepts.</p>
<p>Record both sides. A local configuration that signs outbound metadata does not automatically validate inbound metadata. A remote entity that validates the local metadata may require a specific algorithm or certificate set.</p>
<h2>Keep private keys out of shared metadata</h2>
<p>The certificate is public and belongs in metadata. The private key must remain restricted to the service that signs. File permissions, backups, and deployment artifacts should not expose it. Use a dedicated key for each entity and environment.</p>
<p>The SimpleSAMLphp maintenance documentation warns that the certificate included in the distribution is not suitable when it has been exposed. Replace sample credentials before production use. The same principle applies to copied federation keys and private keys included in container images.</p>
<h2>What the ZoomEye observation shows</h2>
<p>The count-only queries used <code>sub_type=all</code>, page 1, and page size 1. <code>app="SimpleSAMLphp"</code> returned 0, <code>title="SimpleSAMLphp"</code> returned 963, and <code>http.body="SimpleSAMLphp"</code> returned 4,323.</p>
<p>The zero application result is a successful measurement, not an error. The title and body counts show product references but do not prove that a federation endpoint, metadata publisher, or administrative interface is exposed.</p>
<p>Use the observations to reconcile public references with owned identity providers and certificate inventory. Do not fetch sensitive metadata or attempt authentication against unknown services.</p>
<h2>Plan certificate rollover</h2>
<p>Add the new verification certificate alongside the old one before switching the signing key. Publish metadata, wait for consumers to refresh, then remove the old certificate after the documented overlap. Test both old and new signatures during the transition.</p>
<p>Confirm how metadata is cached and whether a refresh failure leaves the last good copy in place. A stale cache can turn a planned rollover into an outage. It can also preserve trust in a revoked key for longer than intended.</p>
<h2>Validate the federation path</h2>
<p>Test a signed metadata document, a malformed signature, an expired certificate, and an unknown issuer. Confirm that the service rejects each case for the expected reason. Review the trust anchors for remote metadata and remove entities that no longer belong to the federation.</p>
<p>Monitor certificate expiry, metadata refresh failures, signature validation errors, and changes to the trusted certificate set. The security decision is not merely whether metadata is signed. It is which keys are accepted, how those keys rotate, and whether the service fails safely when the evidence is wrong.</p>
<h2>References</h2>
<ul>
<li><a href="https://simplesamlphp.org/docs/stable/simplesamlphp-advancedfeatures.html">SimpleSAMLphp advanced features</a></li>
<li><a href="https://simplesamlphp.org/docs/stable/simplesamlphp-reference-sp-remote.html">SimpleSAMLphp remote SP metadata</a></li>
<li><a href="https://simplesamlphp.org/docs/stable/simplesamlphp-maintenance.html">SimpleSAMLphp maintenance</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[After CVE-2026-113461: Root Cause, Residual Risk, and Closure Criteria]]></title><description><![CDATA[CVE-2026-113461 is a reminder that a monitoring plugin's local inputs are part of its security boundary. Checkmk 2.5.0p14 added loading of individual…]]></description><link>https://jeffrey23.hashnode.dev/after-cve-2026-113461-root-cause-residual-risk-and-closure-criteria</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/after-cve-2026-113461-root-cause-residual-risk-and-closure-criteria</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Thu, 05 Nov 2026 20:41:22 GMT</pubDate><content:encoded><![CDATA[<p>CVE-2026-113461 is a reminder that a monitoring plugin's local inputs are part of its security boundary. Checkmk 2.5.0p14 added loading of individual Oracle home libraries for instances listed in <code>oratab</code>. The implementation did not properly validate the permissions of those libraries, allowing a local user with write access to execute code as root when the <code>mk-oracle</code> plugin was enabled.</p>
<p>The vendor fixed the issue in Checkmk 2.5.0p15. The fixed release loads a library only as the user who owns the file or rejects it. The CVE is rated 5.2 Medium under CVSS 4.0 and is associated with CWE-426 and CWE-829. CISA ADP enrichment records exploitation as none and automatable as no.</p>
<h2>What the public evidence supports</h2>
<p>The official Checkmk Werk identifies exactly one affected release, 2.5.0p14, and the fixed release, 2.5.0p15. It names the relevant plugin and describes the write-access requirement for the library or <code>oratab</code>. It also says <code>permissions_check</code> must be set to <code>yes</code> for validation behavior to be enabled.</p>
<p>The public record does not describe an unauthenticated remote exploit, a public proof of concept or confirmed in-the-wild activity. Claims beyond local privilege escalation would need additional evidence. The narrow scope does not remove the risk, especially on multi-user Oracle hosts where a low-privileged account may have an unexpected write path.</p>
<h2>Why the bug occurred</h2>
<p><code>oratab</code> tells <code>mk-oracle</code> where Oracle instances and their home directories are located. The vulnerable implementation trusted the libraries found there without adequately checking whether another user could modify them. When the agent loaded those libraries, the code inherited the agent's privilege level.</p>
<p>The fix changes the trust decision at the point of loading. Ownership now matters, and a library that fails the rule is not used. This approach addresses the specific path by which a writable library could become privileged code.</p>
<h2>Residual risk after upgrading</h2>
<p>An upgrade removes the vulnerable loading behavior, but it does not automatically fix file permissions or configuration drift. Systems can still have an unsafe Oracle home layout, a disabled permission check or an unused plugin that expands the attack surface.</p>
<p>Check the effective <code>mk-oracle</code> configuration after the update. Confirm that <code>permissions_check</code> is enabled where Oracle monitoring is required. Review the owner and permissions of every library named by <code>oratab</code>, including parent directories that an ordinary user could rename or replace.</p>
<p>Investigate any library rejection in the agent output. A rejection may indicate a legitimate ownership problem that needs correction, or it may reveal an unauthorized file change. The security response should preserve evidence before the path is repaired.</p>
<h2>Closure criteria</h2>
<p>A host can be considered remediated when the agent runs 2.5.0p15 or later, the plugin configuration is understood and approved, only trusted administrators can modify the libraries and <code>oratab</code>, and a controlled test shows that an unsafe library is rejected. A version report alone is insufficient.</p>
<p>Fleet closure adds two checks. The inventory should include temporary, test and disaster-recovery agents, and the review should cover shared accounts and ACL inheritance. The monitoring team should retain the evidence long enough to compare later configuration changes against the post-patch baseline.</p>
<h2>External exposure</h2>
<p>ZoomEye's <code>title="Checkmk"</code> Search returned 2,429 matches, while <code>vul.cve="CVE-2026-113461"</code> returned 0. The first number identifies a Checkmk-related web fingerprint population. It does not confirm vulnerable agents or local write access. The second is a separate CVE-indexed observation and does not prove that no vulnerable endpoint exists.</p>
<p>External measurement is useful for finding assets and business units that may be missing from an inventory. Closure still depends on local release, plugin and permission evidence.</p>
<h2>Final assessment</h2>
<p>The issue is a constrained but meaningful local privilege escalation. Its severity is medium because the attacker needs local access and a specific writable path. Its consequence is significant because successful execution can reach root. The fixed release and a clean file-permission model address both the software defect and the condition that made it dangerous.</p>
<h2>References</h2>
<ul>
<li><a href="https://checkmk.com/werk/22621">Checkmk Werk #22621</a></li>
<li><a href="https://docs.checkmk.com/latest/en/monitoring_oracle.html">Checkmk Oracle monitoring documentation</a></li>
<li><a href="https://www.cve.org/CVERecord?id=CVE-2026-113461">CVE-2026-113461</a></li>
<li><a href="https://vulnerability.circl.lu/vuln/cve-2026-113461">CISA ADP enrichment</a></li>
<li><a href="https://wid.cert-bund.de/content/public/content/2f7611de-cbbf-46f7-8ef3-6044ea7b739b">CERT-BUND WID-SEC-2026-4072</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The Small Type Check Behind CVE-2026-114509: Secure Input Boundaries in PHP]]></title><description><![CDATA[CVE-2026-114509 is a useful case study in a recurring PHP design mistake: a value is checked for emptiness when the code actually needs to know its type…]]></description><link>https://jeffrey23.hashnode.dev/the-small-type-check-behind-cve-2026-114509-secure-input-boundaries-in-php</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/the-small-type-check-behind-cve-2026-114509-secure-input-boundaries-in-php</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Thu, 05 Nov 2026 17:21:09 GMT</pubDate><content:encoded><![CDATA[<p>CVE-2026-114509 is a useful case study in a recurring PHP design mistake: a value is checked for emptiness when the code actually needs to know its type. The vulnerable Laravel TokenGuard accepted a non-string API credential, passed it into a user-provider lookup and allowed MySQL or MariaDB comparison behavior to select an unintended user.</p>
<p>The fix is small. The lesson is larger. Authentication code should reject the wrong shape at the boundary before any business logic, query builder or database engine interprets it.</p>
<h2>Empty is not the same as valid</h2>
<p>PHP's <code>empty()</code> answers a broad question. It returns true for values such as <code>null</code>, <code>false</code>, zero, an empty string and an empty array. It returns false for a non-empty array, even though that array may be completely wrong for an API token field.</p>
<p>The pre-fix Laravel code used <code>empty()</code> as an admission check. That was enough to reject an obviously empty credential, but it did not enforce the expected type. A JSON request can create arrays, integers, booleans and nested structures. An authentication guard that expects a string must say so explicitly.</p>
<p>The patched code uses <code>is_string()</code> before the user lookup. That small condition removes the ambiguous values before the framework can turn them into a query. It is a clear boundary check rather than a patch to a downstream symptom.</p>
<h2>Type confusion can become a database decision</h2>
<p>A non-string credential is not automatically an authentication failure because Laravel's user provider accepts a credential map. When a value is an array, the provider can convert it into a <code>whereIn()</code> condition. The database then receives a value that the application did not intend to treat as a valid token.</p>
<p>MySQL and MariaDB compare a text token column with the supplied numeric-like value through conversion. A stored token that does not begin with a digit can evaluate as zero and match an unintended row. The database is acting according to its comparison rules. The application has lost control of the input before that point.</p>
<p>This chain shows why validation must happen at the trust boundary. Checking only the final HTTP response or adding a query filter does not repair the semantic mistake. The guard must reject an array, integer or other non-string value before it becomes part of a credential lookup.</p>
<h2>Apply the pattern to custom guards</h2>
<p>TokenGuard is the named component, but the same review question applies to custom authentication and authorization code. Does a function require a string, integer, UUID or list? If a value arrives from JSON, headers or a query parameter, validate that type and fail closed when it does not match.</p>
<p>Use an explicit parser or validator, not a chain of loose comparisons. Reject arrays where a scalar is expected. Reject numeric strings when the protocol requires a string identifier. Normalize only according to a documented rule, and make the invalid branch return a clear authentication failure without exposing internal details.</p>
<p>A type check should happen before a query, shell command, file path or template lookup. If the function signature accepts <code>string</code>, PHP's runtime declarations can help, but web input often arrives as a mixed value. The boundary that converts request data into application data must enforce the contract.</p>
<h2>Test the failure, not only the happy path</h2>
<p>A unit test for a token guard should cover a valid string, an empty value, a non-empty array, a numeric value, a boolean and an object-like structure. The expected behavior is rejection for every non-string value. The test should not depend on a database connection to prove the guard rejects the input before the query.</p>
<p>An integration test should then use MySQL or MariaDB with synthetic users and verify that the vulnerable fixture exhibits the issue while the patched fixture returns an authentication failure. The patched test should observe no user lookup for the malformed value if instrumentation can capture that decision.</p>
<p>This layered test is valuable because a unit test can miss a provider transformation and an integration test can miss a route-level validation bypass. Keep both. Record the exact framework package and database version when the tests are run.</p>
<h2>Write secure comparisons into the review checklist</h2>
<p>Reviewers should ask three questions when they see authentication input handling:</p>
<ul>
<li>What exact type does this function require?</li>
<li>Where is that type enforced before user input reaches a query or provider?</li>
<li>What happens when the value is an array, object, boolean or number?</li>
</ul>
<p>For credential code, fail closed. Do not turn a malformed input into an empty token, a default user or a wildcard lookup. Do not rely on <code>empty()</code>, truthiness or an unspecified cast to define the API contract.</p>
<p>A framework-level fix is the primary remediation for CVE-2026-114509. The code review pattern helps prevent the next variation in a custom guard, middleware or package. The source analysis provides a concrete example to discuss with application teams, not a reason to patch only one line and leave similar boundaries unexamined.</p>
<h2>Keep database behavior in the threat model</h2>
<p>Developers should know that MySQL and MariaDB can compare strings numerically in some contexts, but the fix belongs in the application. Database migration or server configuration is not a substitute for type validation. A different database engine can remove one path while leaving the authentication bug intact.</p>
<p>When a framework or ORM converts a credential map into a query, review the shape of the generated condition. A scalar token lookup should not silently become an <code>in</code> list. If the application permits a list, the code should validate the list and document the semantics. Authentication should not infer those semantics from whatever JSON the client sent.</p>
<h2>Use exposure carefully</h2>
<p>ZoomEye's <code>app="Laravel"</code> query returned 910,052 product-fingerprint matches during this review. The CVE filter returned zero. Those results can prompt a review of Laravel assets, but they do not tell a code owner which route uses TokenGuard or which database comparison path is active. The secure-design lesson still comes from the code and the test evidence.</p>
<p>CVE-2026-114509 is easy to describe as a Laravel bug. At the boundary, it is also a familiar validation problem: a function accepted a value outside its contract and a downstream component interpreted it. The durable response is to make the contract explicit and test the invalid shapes.</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/advisories/GHSA-f9x3-7vq9-cph6">GitHub Advisory GHSA-f9x3-7vq9-cph6</a></li>
<li><a href="https://yokai.hakaisecurity.io/en-ghsa-f9x3-7vq9-cph6-authentication-bypass-in-laravel-tokenguard/">Hakai technical analysis</a></li>
<li><a href="https://github.com/hakaioffsec/GHSA-f9x3-7vq9-cph6-PoC">Hakai proof-of-concept lab</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Matomo token_auth placement decides where secrets leak]]></title><description><![CDATA[Matomo uses token_auth for Reporting API calls, authenticated Tracking API requests and embedded widgets. The token is not just an analytics-read key…]]></description><link>https://jeffrey23.hashnode.dev/matomo-token-auth-placement-decides-where-secrets-leak</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/matomo-token-auth-placement-decides-where-secrets-leak</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Thu, 05 Nov 2026 14:01:46 GMT</pubDate><content:encoded><![CDATA[<p>Matomo uses <code>token_auth</code> for Reporting API calls, authenticated Tracking API requests and embedded widgets. The token is not just an analytics-read key. Matomo's documentation compares it to a user's password and explains that a token can be sent in a GET query string or a POST body. The HTTP method therefore changes where the secret can appear in logs, browser history, proxies and support bundles.</p>
<p>On 2026-11-05, a count-only ZoomEye query with <code>sub_type=all</code>, page 1 and page size 1 returned 30,589 matches for <code>app="Matomo"</code>. The title query returned 34,688. These counts locate application surfaces, not installations with weak tokens or exposed reports.</p>
<p>Matomo 6 documentation adds a token access level and an "Only allow secure requests" option. A secure token is accepted only in POST requests, not as a URL parameter. The option is useful only when the integration can actually use POST. A tracking proxy or third-party connector that hardcodes GET may fail after the restriction, so test the integration before enforcing it.</p>
<h2>Map token authority before rotation</h2>
<p>The Reporting API documentation advises creating a dedicated user for Tracking API work and granting only the required website permission. Do that for reporting jobs as well. A token used to read one site's reports should not inherit administration of every site. If Matomo's token model provides a narrower access level, test it against the exact API methods in use. Older documentation notes that some token versions share the user's permissions; the deployment version and plugin set matter.</p>
<p>Search application code and configuration for <code>token_auth</code> passed as a query parameter. Replace it with POST body or an approved OAuth flow where available. Never put a token in a public dashboard URL or share a copied report link without checking the query string. Treat logs, HAR files and browser history as secret-bearing evidence when a token was used in a URL.</p>
<p>Use HTTPS and a trusted reverse proxy. Redact query strings at the proxy where possible, but do not rely on redaction as the only control because access logs may be duplicated across systems. Restrict Matomo administration to an internal network or SSO-protected gateway. Keep the dashboard and the tracking endpoint on separate hostnames if that simplifies policy.</p>
<p>If a token is exposed, regenerate it first, then inspect reports and administration changes made during the window. Review plugin access and saved segments that could expose another site's data. Matomo recommends two-factor authentication in its security guidance, but MFA does not protect a bearer token that has already been copied.</p>
<p>The ZoomEye count is not evidence of compromise. It is a reason to verify the login page, API endpoints, token transport and public reporting configuration on owned instances. The useful defensive decision is to make the secret's transport and permission scope explicit for each integration.</p>
<h2>References</h2>
<ul>
<li><a href="https://matomo.org/faq/general/faq_114/">Matomo token_auth FAQ</a></li>
<li><a href="https://developer.matomo.org/guides/reporting-api">Matomo Reporting API authentication</a></li>
<li><a href="https://matomo.org/security/">Matomo security overview</a></li>
<li><a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJNYXRvbW8i">ZoomEye app="Matomo" observation</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Quest Foglight CVE-2026-92188 exposes an unauthenticated MBean execution path]]></title><description><![CDATA[Quest Foglight for Databases is used to monitor database estates, collect performance data, and run management workflows. ZDI published CVE-2026-92188 on…]]></description><link>https://jeffrey23.hashnode.dev/quest-foglight-cve-2026-92188-exposes-an-unauthenticated-mbean-execution-path</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/quest-foglight-cve-2026-92188-exposes-an-unauthenticated-mbean-execution-path</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Thu, 05 Nov 2026 10:41:15 GMT</pubDate><content:encoded><![CDATA[<p>Quest Foglight for Databases is used to monitor database estates, collect performance data, and run management workflows. ZDI published CVE-2026-92188 on November 4, 2026 and describes a missing-authentication flaw involving <code>ForgeMBeanServerSupport</code>. The vulnerability permits remote code execution on affected installations.</p>
<p>The public title is compact but the architecture is familiar. Monitoring platforms often expose a management protocol that can invoke methods on the server. That functionality exists to automate collection and remediation. If an unauthenticated request can reach the MBean execution path, the monitoring appliance becomes an execution service on the management network.</p>
<h2>Why an MBean endpoint matters</h2>
<p>Java Management Extensions expose attributes and operations through MBeans. Administrators use them for runtime inspection, configuration, and control. A monitoring integration may also use them to collect metrics or trigger a task.</p>
<p>An unauthenticated <code>MBeanServer</code> operation is not equivalent to a harmless status page. The operations available depend on the registered MBeans and their permissions. Some read data. Others invoke methods, change configuration, or load classes. The exact exploit chain and affected versions should come from Quest and ZDI; the public description does not justify inventing a specific object name.</p>
<p>The key defensive question is reachability. If the Foglight management interface or management protocol is exposed to a network where an unauthenticated client can send requests, the flaw has a direct path. A VPN-only management plane reduces exposure but does not eliminate the need to patch.</p>
<h2>Inventory the monitoring plane</h2>
<p>Build a list of Foglight servers, collectors, federation components, and database connections. Record the version, management port, authentication configuration, and network path. Include appliances managed by a database or observability team rather than assuming the server team owns them.</p>
<p>Map what the Foglight service account can reach. A monitoring account may have read access to many databases and operating-system metrics. A deeper compromise could use those credentials to query sensitive metadata or move toward database hosts.</p>
<p>Review JMX exposure at the network level. Management protocols should not be reachable from user workstations, guest networks, or general application segments. Restrict them to an administrative subnet and require authenticated access.</p>
<h2>Patch and test the boundary</h2>
<p>Apply the fixed Quest release identified in the ZDI advisory and Quest's support documentation. Verify the running build on every server and collector. If the organization cannot patch immediately, isolate the management endpoint and monitor for unexpected MBean invocations.</p>
<p>After patching, test unauthenticated access to the management interface from a network that should be denied. Confirm that it fails before reaching application logic. Then test a legitimate authenticated monitoring operation to ensure that the fix did not break collection.</p>
<p>Review logs for requests from unexpected sources, new MBean operations, class-loading events, and service restarts. A monitoring server often has a high-privilege service account; changes to database connection settings or collection jobs deserve investigation.</p>
<h2>Treat monitoring as a control plane</h2>
<p>Foglight holds an inventory of databases, connection endpoints, and operational history. It may also have credentials or integrations that can change monitoring behavior. If the product is compromised, the attacker can learn where the data lives and which systems are monitored.</p>
<p>Separate the monitoring network from the data network where possible. Use a dedicated service account with the minimum privileges needed for collection. Rotate credentials after a suspected compromise and review database audit logs for queries that came from the monitoring host.</p>
<p>The patch closes the missing-authentication path. Network restrictions and least-privilege accounts limit what an exploit can do if another path is found.</p>
<h2>References</h2>
<ul>
<li><a href="https://www.zerodayinitiative.com/advisories/ZDI-26-854/">ZDI-26-854 Quest Foglight advisory</a></li>
<li><a href="https://www.tenable.com/cve/CVE-2026-92188">CVE-2026-92188 public record</a></li>
<li><a href="https://www.rapid7.com/db/vulnerabilities/cve-2026-92188/">Rapid7 vulnerability record</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[ProtectClock closes more than the RTC device]]></title><description><![CDATA[A service that can change the host clock can change the order of events recorded around it. It can also shift timestamps used by applications that assume…]]></description><link>https://jeffrey23.hashnode.dev/protectclock-closes-more-than-the-rtc-device</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/protectclock-closes-more-than-the-rtc-device</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Thu, 05 Nov 2026 07:21:27 GMT</pubDate><content:encoded><![CDATA[<p>A service that can change the host clock can change the order of events recorded around it. It can also shift timestamps used by applications that assume the operating system clock is outside their control. The systemd <code>ProtectClock=</code> setting reduces that authority in several ways at once.</p>
<h2>What the setting changes</h2>
<p>When <code>ProtectClock=yes</code> is configured, systemd removes <code>CAP_SYS_TIME</code> and <code>CAP_WAKE_ALARM</code> from the unit's capability bounding set. It also installs a system call filter for operations that can set a clock and applies a read-only device rule to the real-time clock devices.</p>
<p>The effect therefore extends beyond making <code>/dev/rtc0</code> read-only. A service that previously called <code>clock_settime()</code>, <code>settimeofday()</code>, or an adjacent time-control interface meets both a capability restriction and a system call filter.</p>
<p>The filter is deliberately coarse. The systemd manual explains that the calls are blocked even when a particular argument combination would only read clock state. Applications that need those calls for a legitimate reason need a narrower policy than <code>ProtectClock=yes</code>, or they need to move the operation outside the sandbox.</p>
<h2>Where it fits in a service policy</h2>
<p><code>ProtectClock=</code> is most useful as part of an execution profile that already runs the service as an unprivileged user. A process running as root may retain other ways to reach kernel interfaces. Removing <code>CAP_SYS_TIME</code> blocks one path, but mount access, writable kernel settings, and device access still need review.</p>
<p>Keep the service's actual requirements visible. A time daemon needs to adjust the clock. A certificate validation service usually does not. A scheduler may need accurate time, while the database or job runner it supports only needs to consume the clock. Those roles should not share the same unit policy.</p>
<p>Review the related settings together:</p>
<pre><code class="language-ini">[Service]
User=app
ProtectClock=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallFilter=~@mount
</code></pre>
<p>The example is a review starting point. Some services need mount operations for their own temporary storage or runtime directories. A denied system call can fail a health check long after the unit starts, so test the full startup and shutdown path.</p>
<h2>The host still owns the clock</h2>
<p>The setting protects the service from writing the clock. It does not make the host clock trustworthy. A hypervisor, a privileged local process, or an administrator can still change it. Logs from different hosts can still disagree because of clock drift or a broken time source.</p>
<p>Defenders should combine host time synchronization, authenticated time where the environment supports it, and independent log evidence. Application logs should record monotonic durations for local timers when event ordering matters. Central log storage should preserve receipt time separately from the timestamp supplied by the host.</p>
<p><code>ProtectClock=</code> reduces a service's ability to create a misleading local timeline. It does not repair a timeline that was already altered before the logs left the host.</p>
<h2>Verify the effective unit</h2>
<p>Start with the expanded unit rather than the fragment in <code>/etc</code>:</p>
<pre><code class="language-bash">systemctl cat example.service
systemctl show example.service -p User -p ProtectClock -p CapabilityBoundingSet
systemd-analyze security example.service
</code></pre>
<p>Then exercise the paths that need time access. A harmless application startup is not enough if a maintenance command changes the clock or wakes an alarm through a separate process. Check those helper processes and any command started with a <code>+</code> prefix, because systemd does not apply every sandbox setting to those commands in the same way.</p>
<p>Record the intended result. The service should be able to read time, run its scheduled work, and pass its health checks. It should fail when asked to change host time. If it succeeds, the unit policy is incomplete or the test is running outside the sandbox.</p>
<h2>References</h2>
<ul>
<li><a href="https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html">systemd.exec execution environment settings</a></li>
<li><a href="https://www.freedesktop.org/software/systemd/man/latest/systemd-analyze.html">systemd-analyze security</a></li>
<li><a href="https://docs.kernel.org/admin-guide/time_namespaces.html">Linux time namespaces</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Crossplane Providers Expand the Control Plane's Credential Surface]]></title><description><![CDATA[Crossplane turns Kubernetes into a control plane for external infrastructure. Providers install APIs and controllers that manage outside resources. The…]]></description><link>https://jeffrey23.hashnode.dev/crossplane-providers-expand-the-control-plane-s-credential-surface</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/crossplane-providers-expand-the-control-plane-s-credential-surface</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Wed, 04 Nov 2026 21:21:12 GMT</pubDate><content:encoded><![CDATA[<p>Crossplane turns Kubernetes into a control plane for external infrastructure. Providers install APIs and controllers that manage outside resources. The convenience comes with a larger credential and authorization surface than a plain application deployment.</p>
<p>An internet search for the Crossplane name may identify candidate pages. It cannot show which provider packages are installed, which cloud identities they use, or which subjects can create managed resources.</p>
<h2>Providers run inside the cluster</h2>
<p>Crossplane's provider documentation says providers may create Deployments, Service Accounts, and RBAC configuration. A provider runtime can use a <code>ProviderConfig</code> that points to credentials stored in a Kubernetes Secret, the pod filesystem, or an environment variable.</p>
<p>Each choice changes the credential boundary. A Secret is still cluster data that must be protected. A mounted file must be controlled by the pod and image. An environment variable may leak through process inspection or diagnostics. The provider's external permissions determine what a compromised controller or managed resource definition can do.</p>
<p>Crossplane's multi-tenant guidance emphasizes composition and Kubernetes RBAC to define what self-service users can request. That policy is only effective if users cannot create or alter the provider configuration, composition functions, or RBAC that the infrastructure request ultimately uses.</p>
<h2>Two scoped title matches</h2>
<p>On 2026-11-04 at 20:49 UTC, a count-only ZoomEye SDK query returned 0 for <code>app="Crossplane"</code> and 6 for <code>title="Crossplane"</code>. The scoped query <code>title="Crossplane" &amp;&amp; http.body="crossplane.io"</code> returned 2 at 20:50 UTC.</p>
<p>The two scoped title matches are web candidates. They might be documentation, a dashboard, or a test deployment. The count is not the number of Crossplane control planes, and no asset records were retrieved. The zero application result should remain a zero for that specific fingerprint, not a conclusion about installed controllers.</p>
<p>For control-plane products, external fingerprint coverage is often thin. A web UI is optional, and management may happen entirely through the Kubernetes API. A serious inventory therefore starts inside the cluster.</p>
<h2>Inventory providers and identities</h2>
<p>List provider packages, versions, namespaces, service accounts, RBAC roles, and provider configurations. For each provider, record the external account, credential source, and permissions. Identify which Crossplane resources a tenant can create and which composition can reach those credentials.</p>
<p>Review the RBAC manager and any permission it binds automatically. Confirm that a provider's service account cannot read every Secret in the cluster. Compare the package version and source with an approved registry policy.</p>
<p>Test a user who can create a managed resource but cannot modify a provider configuration. Test a composition that references a credential outside its intended scope. Rotate a provider secret and verify that the controller uses the new value without exposing it in status or events.</p>
<p>Crossplane's value is that infrastructure becomes declarative. Its risk is that one Kubernetes identity can reach several external control planes. The provider configuration and the Kubernetes request path need to be inventoried together.</p>
<h2>References</h2>
<ul>
<li>[1] <a href="https://docs.crossplane.io/v2.4/packages/providers/">Crossplane providers</a></li>
<li>[2] <a href="https://docs.crossplane.io/v1.20/guides/multi-tenant/">Multi-tenant Crossplane</a></li>
<li>[3] <a href="https://docs.crossplane.io/latest/guides/pods/">Crossplane pods and RBAC manager</a></li>
<li>[4] <a href="https://www.zoomeye.ai/">ZoomEye</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Garage Inventory Has Two Different Credential Planes]]></title><description><![CDATA[Garage is an S3-compatible distributed object store with a separate administration API. That separation is the useful starting point for an exposure…]]></description><link>https://jeffrey23.hashnode.dev/garage-inventory-has-two-different-credential-planes</link><guid isPermaLink="true">https://jeffrey23.hashnode.dev/garage-inventory-has-two-different-credential-planes</guid><dc:creator><![CDATA[jeffreyreiciendisag]]></dc:creator><pubDate>Wed, 04 Nov 2026 18:02:18 GMT</pubDate><content:encoded><![CDATA[<p>Garage is an S3-compatible distributed object store with a separate administration API. That separation is the useful starting point for an exposure review. The S3 endpoint serves object operations to applications. The Admin API can inspect or change cluster and bucket configuration. Metrics may be another endpoint. A count of pages that mention Garage cannot tell which listener answered or which credential class is in use.</p>
<p>Garage's configuration documentation describes an admin token that has full administrative scope unless replaced by narrower v2 tokens. Dynamic admin tokens can have an expiration and a restricted set of admin API functions. If no static admin token is configured on current versions, only explicitly defined tokens may authorize the admin endpoint. The metrics endpoint may be unauthenticated unless <code>metrics_require_token</code> is set. The admin listener can bind to a Unix socket with restrictive permissions, which reduces network exposure but still requires host-level access control.</p>
<p>A ZoomEye count-only probe on 2026-11-04 returned 19 for <code>app="Garage"</code> and 52,468 for <code>title="Garage"</code>, with <code>sub_type=all</code>, page 1, and page size 1. The application count is a narrow lead. The title count is too broad to treat as a deployment census because the word can appear in many unrelated pages. Neither observation shows whether the admin token is configured, whether an S3 key is exposed, or whether a bucket allows public access.</p>
<h2>Map the listeners and grants</h2>
<p>Inventory the S3, Admin, metrics, and web endpoints by address and port. Bind the Admin API to a management interface or Unix socket and restrict access to the operator account or group. Do not expose it through the same public proxy as object traffic. If metrics are published, require a token or restrict the network path, and review which labels reveal bucket, node, or operation details.</p>
<p>Review admin token scope and lifetime. Replace a static full-scope token where the deployment supports scoped, expiring tokens. Store token files with restrictive permissions and keep them out of configuration backups that are broadly readable. Rotate the token after a host rebuild or administrator departure.</p>
<p>For S3 identities, enumerate access keys, bucket grants, and any public or anonymous bucket policy. Grant only the bucket and operation required by an application. The presence of an S3 key does not mean the key permits every bucket. Conversely, a read-only listing grant may still expose object names and metadata that the application does not need. Test policy changes with a separate key and an unauthorized bucket.</p>
<p>Record the query and its time beside any asset inventory. The <a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJHYXJhZ2Ui">application search</a> is the starting point. A <a href="https://www.zoomeye.ai/searchResult?q=dGl0bGU9IkdhcmFnZSI%3D">title query</a> may find additional leads but should not be used as a count of Garage clusters. Confirm the service type, then inspect only systems owned by the reviewing organization.</p>
<h2>References</h2>
<ul>
<li><a href="https://github.com/deuxfleurs-org/garage/blob/main-v2/doc/book/reference-manual/configuration.md">Garage configuration reference</a></li>
<li><a href="https://garagehq.deuxfleurs.fr/api/garage-admin-v2.html">Garage administration API v2</a></li>
<li><a href="https://garagehq.deuxfleurs.fr/">Garage project documentation</a></li>
</ul>
]]></content:encoded></item></channel></rss>