<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: StarkMan</title>
    <description>The latest articles on DEV Community by StarkMan (@stark_zhuang_df5076f35c68).</description>
    <link>https://dev.to/stark_zhuang_df5076f35c68</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3505647%2Fa170812c-4424-4701-a003-3135d19ab975.jpg</url>
      <title>DEV Community: StarkMan</title>
      <link>https://dev.to/stark_zhuang_df5076f35c68</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stark_zhuang_df5076f35c68"/>
    <language>en</language>
    <item>
      <title>Archivematica's 1,061 title matches make preservation control planes worth inventorying</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sun, 01 Nov 2026 00:00:38 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/archivematicas-1061-title-matches-make-preservation-control-planes-worth-inventorying-cf5</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/archivematicas-1061-title-matches-make-preservation-control-planes-worth-inventorying-cf5</guid>
      <description>&lt;h1&gt;
  
  
  Archivematica's 1,061 title matches make preservation control planes worth inventorying
&lt;/h1&gt;

&lt;p&gt;Archivematica manages digital preservation workflows: transfers, ingest, normalization, storage and archival packages. A dashboard that controls those workflows can approve transfers, expose metadata and connect to a separate Storage Service. The system is not a passive archive viewer. It is a control plane over the evidence and files an institution has promised to preserve.&lt;/p&gt;

&lt;p&gt;On 2026-10-31, a count-only ZoomEye query returned zero matches for &lt;code&gt;app="Archivematica"&lt;/code&gt; and 1,061 for &lt;code&gt;title="Archivematica"&lt;/code&gt;. The title query ran at 23:44:58 UTC and the application query at 23:44:57 UTC. Both used &lt;code&gt;sub_type=all&lt;/code&gt;, page 1 and page size 1. The zero application result is a fingerprint miss, not a claim that no dashboard exists. The 1,061 title matches can include project pages, training material and user portals.&lt;/p&gt;

&lt;p&gt;The documentation distinguishes the Dashboard from the Storage Service API. Both require authentication, and the Dashboard uses Django's cookie-based user authentication for its web session. API calls can use a username and API key, with an Authorization header carrying the key or, in the older documented pattern, query parameters. The query-parameter form creates a logging risk. Prefer the header form, enforce TLS, and make sure reverse-proxy logs do not retain credentials.&lt;/p&gt;

&lt;p&gt;Inventory both services. The Dashboard may be used by archivists and preservation staff. The Storage Service may have its own API and credentials and may connect to object storage, network filesystems or remote locations. A dashboard that is private does not automatically make a storage endpoint private. A storage service that is reachable from an application network should still authenticate callers and restrict administrative operations.&lt;/p&gt;

&lt;p&gt;Test roles with a low-privilege account. Confirm who can create a transfer, approve an ingest, change processing configuration, download a package or delete an object. The documented API is designed for automation, so a CI job or preservation integrator may hold a powerful key. Give that key a named owner, store it outside the repository, rotate it on staff or vendor changes, and review recent actions. Avoid sharing one key across scripts.&lt;/p&gt;

&lt;p&gt;Preservation systems often hold restricted material. Accession records, donor agreements, personal information and embargoed files may not belong in a public finding aid. Review the metadata export paths and the object download URLs, not only the Dashboard page. A public preservation index or thumbnail can disclose the existence of a collection even when the package itself is protected.&lt;/p&gt;

&lt;p&gt;Availability is a security property for preservation. A dashboard exposed to the internet increases the chance of credential attacks, automated scanning and accidental configuration changes. Restrict administrative access to a trusted network or identity-aware proxy, monitor failed logins, and test restoration of the configuration as well as the content. An outage in the control plane may stop preservation processing even when the stored packages remain intact.&lt;/p&gt;

&lt;p&gt;The 1,061 title matches are a candidate set, not a list of exposed archives. An owning organization should confirm the service, map Dashboard and Storage Service endpoints, and compare anonymous, staff and administrator behavior. Archivematica protects digital material over long periods. Its own administrative path needs the same care as the collections it preserves.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.archivematica.org/en/docs/archivematica-1.14/dev-manual/api/api-overview/" rel="noopener noreferrer"&gt;Archivematica API overview&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.archivematica.org/en/docs/archivematica-1.16/admin-manual/security/security/" rel="noopener noreferrer"&gt;Archivematica security guidance&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJBcmNoaXZlbWF0aWNhIg%3D%3D" rel="noopener noreferrer"&gt;ZoomEye application query for Archivematica&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=dGl0bGU9IkFyY2hpdmVtYXRpY2Ei" rel="noopener noreferrer"&gt;ZoomEye title query for Archivematica&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>zoomeye</category>
      <category>archivematica</category>
      <category>preservation</category>
    </item>
    <item>
      <title>Triage playbook for suspected CVE-2026-105482 exploitation</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 20:40:37 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/triage-playbook-for-suspected-cve-2026-105482-exploitation-3j6a</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/triage-playbook-for-suspected-cve-2026-105482-exploitation-3j6a</guid>
      <description>&lt;h1&gt;
  
  
  Triage playbook for suspected CVE-2026-105482 exploitation
&lt;/h1&gt;

&lt;p&gt;An alert about CVE-2026-105482 may arrive as a scanner finding, a runtime-version report, or a suspicious DNS request. The first task is not to label every Node.js system compromised. The team needs to establish whether an affected runtime received an attacker-controlled hostname and acted on a truncated resolution result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Establish the technical facts
&lt;/h2&gt;

&lt;p&gt;The flaw affects Node.js &lt;code&gt;dns.resolve*()&lt;/code&gt; and &lt;code&gt;dns.reverse()&lt;/code&gt;. A hostname containing a NUL byte can be silently shortened at the c-ares boundary. The resolver then returns records for the shorter name without an error. The Node.js advisory calls the issue an incomplete fix of CVE-2026-48930, which covered &lt;code&gt;dns.lookup()&lt;/code&gt; and host options in &lt;code&gt;net&lt;/code&gt; and &lt;code&gt;tls&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The issue is rated high severity. The GitHub Advisory Database lists CVSS 3.0 score 7.4 with vector &lt;code&gt;AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N&lt;/code&gt;. That describes a network-accessible condition with high attack complexity and potential confidentiality and integrity impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Confirm the runtime
&lt;/h2&gt;

&lt;p&gt;Node.js 22.x, 24.x, and 26.x are affected before the fixed releases. The patched versions are Node.js 22.23.4, 24.22.1, and 26.12.1. Check the actual process and package version from the deployed host, container, or serverless environment. A dependency scanner that reports an application library is not evidence that the runtime is patched.&lt;/p&gt;

&lt;p&gt;Record where the process runs, who owns it, what it exposes, and whether it can make outbound network connections. A build tool with no untrusted hostname input is lower priority than a customer-facing URL fetcher, but it may still have access to internal build networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trace the vulnerable sequence
&lt;/h2&gt;

&lt;p&gt;Look for request handlers and integration jobs that accept a hostname or URL. Determine whether the value reaches &lt;code&gt;dns.resolve*()&lt;/code&gt; or &lt;code&gt;dns.reverse()&lt;/code&gt; and whether a policy check happens before or after that call. The important question is whether the application validates the full string but resolves the truncated one.&lt;/p&gt;

&lt;p&gt;Review logs for control-character encoding, suspicious suffixes after a NUL, and DNS records returned for a shorter name than the policy object. Compare the approved hostname with the address used by the outbound connection. Preserve the original request representation before any log normalizer removes the byte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containment
&lt;/h2&gt;

&lt;p&gt;If a vulnerable application path is confirmed, restrict outbound access to required destinations. Block metadata, loopback, link-local, private networks, and administrative endpoints where the application has no legitimate need for them. Disable or pause the affected workflow if the business impact is acceptable.&lt;/p&gt;

&lt;p&gt;Upgrade to a fixed Node.js release and rebuild the artifact. Rotate credentials only if the evidence shows that a protected secret was exposed or used. A hostname bypass alone does not prove credential theft. Reset sessions or tokens when suspicious responses or unexpected outbound traffic provide a reason to do so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposure evidence and limits
&lt;/h2&gt;

&lt;p&gt;The ZoomEye Search &lt;code&gt;app="Node.js"&lt;/code&gt; returned 5,537,125 product matches during this review. The CVE Filter &lt;code&gt;vul.cve="CVE-2026-105482"&lt;/code&gt; returned 0. The product count is not a vulnerable-asset count, and the zero Filter result does not override the vendor advisory. Use both as inventory context, not as incident proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence to collect
&lt;/h2&gt;

&lt;p&gt;Preserve the application version, runtime version, deployment revision, and image digest. Collect request and DNS logs that cover the suspected time range, along with proxy and network-flow records for outbound destinations. Record the exact query used in ZoomEye and the observation time if asset data is part of the investigation.&lt;/p&gt;

&lt;p&gt;Keep a timeline that separates a scanner match, an affected runtime, a vulnerable code path, and an actual security action. Those are different levels of confidence. A system can match the runtime product and still have no exploitable workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery criteria
&lt;/h2&gt;

&lt;p&gt;The runtime upgrade is deployed to every affected artifact. The vulnerable DNS path rejects NUL input or canonicalizes it before resolution. Outbound policy checks the resolved address. Tests cover the complete request path, and monitoring records a mismatch between the approved name and the connection target.&lt;/p&gt;

&lt;p&gt;After those steps, retain a review item for application logic that still treats a boolean hostname check as authorization for a later network action. CVE-2026-105482 can be fixed in the runtime, but that architectural assumption can survive the patch.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/blog/vulnerability/october-2026-security-releases" rel="noopener noreferrer"&gt;Node.js October 2026 security releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/advisories/GHSA-4qmx-59c6-fr6r" rel="noopener noreferrer"&gt;GitHub Advisory GHSA-4qmx-59c6-fr6r&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nodejs/node/blob/main/doc/api/dns.md" rel="noopener noreferrer"&gt;Node.js DNS API documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/blog/release/v22.23.4" rel="noopener noreferrer"&gt;Node.js 22.23.4 release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/blog/release/v24.22.1" rel="noopener noreferrer"&gt;Node.js 24.22.1 release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/blog/release/v26.12.1" rel="noopener noreferrer"&gt;Node.js 26.12.1 release&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>dns</category>
      <category>vulnerability</category>
      <category>ssrf</category>
    </item>
    <item>
      <title>Upgrade and Verify Netty 4.1.137 or 4.2.17</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:20:27 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/upgrade-and-verify-netty-41137-or-4217-4i4a</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/upgrade-and-verify-netty-41137-or-4217-4i4a</guid>
      <description>&lt;h1&gt;
  
  
  Upgrade and Verify Netty 4.1.137 or 4.2.17
&lt;/h1&gt;

&lt;p&gt;A version change in the build file is only one part of remediating CVE-2026-75595. The fixed release must reach the packaged application, and the deployed TLS listener must keep its intended client-authentication policy. The affected &lt;code&gt;io.netty:netty-handler&lt;/code&gt; ranges are up to &lt;code&gt;4.1.136.Final&lt;/code&gt;, and &lt;code&gt;4.2.0.Final&lt;/code&gt; through &lt;code&gt;4.2.16.Final&lt;/code&gt;. The patched releases are &lt;code&gt;4.1.137.Final&lt;/code&gt; and &lt;code&gt;4.2.17.Final&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the correct release line
&lt;/h2&gt;

&lt;p&gt;Select the fixed version that matches the application's supported Netty branch. Do not downgrade a newer major line merely to satisfy a version string. Check the framework's compatibility notes and its dependency-management rules before changing the version.&lt;/p&gt;

&lt;p&gt;If the vulnerable package arrives through a platform BOM, update the BOM or add a narrowly scoped constraint. If the application shades Netty, rebuild the shaded artifact. If a container base image supplies the class, rebuild the image from a patched parent rather than copying a replacement class into the running filesystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect before and after
&lt;/h2&gt;

&lt;p&gt;Before the change, record the resolved &lt;code&gt;netty-handler&lt;/code&gt; version and the service owner. After the build, inspect the artifact again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn dependency:tree -Dincludes=io.netty:netty-handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Gradle, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./gradlew dependencyInsight --dependency netty-handler --configuration runtimeClasspath
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the output with the affected ranges. Then verify the file inside the deployable image or executable jar. The source build can be correct while a stale layer or alternate class path leaves the vulnerable copy in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test mTLS behavior
&lt;/h2&gt;

&lt;p&gt;Prepare test clients for the intended SNI route, a missing or unrecognized SNI, and the fallback context. Verify that a client with a valid certificate reaches the protected service when expected. Verify that a client without a certificate is rejected. Use controlled test credentials and avoid reading production client keys.&lt;/p&gt;

&lt;p&gt;Review the default &lt;code&gt;SslContext&lt;/code&gt; as part of the deployment. If it permits clients without certificates and there is no application-level peer-certificate check, treat that configuration as a separate access-control finding, even after the library is patched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roll out with observable checks
&lt;/h2&gt;

&lt;p&gt;Use a canary or small service slice to compare TLS handshake outcomes before and after the upgrade. Track certificate-authentication failures, TLS parsing errors and route-selection failures. A jump in valid-client failures can indicate a certificate or SNI mapping problem. A drop in required-auth rejections can indicate that policy changed.&lt;/p&gt;

&lt;p&gt;Do not use a successful health check as proof that mTLS works. Health endpoints may use a different listener or context. Add a dedicated test that exercises the same SNI mapping and client-auth settings as the protected workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handle the fallback as a temporary control
&lt;/h2&gt;

&lt;p&gt;If the upgrade is delayed, review whether the default context can require a client certificate. That change can remove the permissive fallback condition described by the advisory. It may break clients that rely on the fallback route, so test it and keep the library upgrade in the remediation plan.&lt;/p&gt;

&lt;p&gt;The temporary control does not fix the parser error. It changes the surrounding policy so a selection failure is less likely to grant access. Record the residual affected version until the dependency is updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Close the finding with evidence
&lt;/h2&gt;

&lt;p&gt;A complete record contains the application identity, resolved fixed version, packaged artifact hash, deployment time and mTLS test result. The owner should be able to show that the affected range is gone from the running artifact and that the protected route still requires the intended certificate.&lt;/p&gt;

&lt;p&gt;ZoomEye Search &lt;code&gt;app="Netty"&lt;/code&gt; returned 505 product fingerprints on 2026-10-31, with a CVE Filter result of 0. Those values support external discovery but do not replace the rollout evidence. Use them to look for forgotten public services, while the upgrade record remains the basis for closure.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/netty/netty/security/advisories/GHSA-c4c3-7fpv-j4q5" rel="noopener noreferrer"&gt;Netty security advisory GHSA-c4c3-7fpv-j4q5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/netty/netty/commit/1b5abc6443b63726c72cdd285af2feb7ddbb8ff7" rel="noopener noreferrer"&gt;Netty fixing commit 1b5abc6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=2519953" rel="noopener noreferrer"&gt;Red Hat CVE-2026-75595 record&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>vulnerability</category>
      <category>remediation</category>
      <category>netty</category>
    </item>
    <item>
      <title>SuiteCRM exposes a role-and-group review problem, not one product verdict</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 14:00:48 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/suitecrm-exposes-a-role-and-group-review-problem-not-one-product-verdict-98b</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/suitecrm-exposes-a-role-and-group-review-problem-not-one-product-verdict-98b</guid>
      <description>&lt;h1&gt;
  
  
  SuiteCRM exposes a role-and-group review problem, not one product verdict
&lt;/h1&gt;

&lt;p&gt;A CRM login page is an entry point to customer records, sales activity, support cases, and sometimes integration credentials. SuiteCRM deployments can combine direct user roles, security groups, record assignments, and two-factor authentication. Discovery should therefore produce an owner and a permission review, not a label that every visible instance is vulnerable.&lt;/p&gt;

&lt;p&gt;A ZoomEye count-only measurement on October 31, 2026 at 06:44 Beijing time used page 1, page size 1, and &lt;code&gt;sub_type=all&lt;/code&gt;. &lt;code&gt;app="SuiteCRM"&lt;/code&gt; returned 23,040 matches and &lt;code&gt;title="SuiteCRM"&lt;/code&gt; returned 11,426. These are separate visible fingerprint observations. They do not show that any matching instance has weak authentication or exposed customer data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat both queries as evidence
&lt;/h2&gt;

&lt;p&gt;The app query identifies a larger candidate set in this sample. The title query finds a different set of pages and can catch custom branding or a deployment whose app signature is absent. Neither set is authoritative for an owned inventory, and neither count should be added to the other. Some assets may appear in both results, while others appear in only one.&lt;/p&gt;

&lt;p&gt;The useful follow-up is an ownership match. Compare hostnames against DNS zones, certificate issuance, cloud accounts, and the organization's service catalog. A host outside all known inventories may be a shadow deployment or simply a third-party page that mentions the product. Resolve that ambiguity without touching someone else's account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review roles and security groups
&lt;/h2&gt;

&lt;p&gt;SuiteCRM's administrator documentation explains that roles define access and security groups assign users to records. Direct user roles can take precedence over group roles. That interaction makes a simple review of one role matrix insufficient. Test users with group membership, direct assignment, multiple roles, and no role.&lt;/p&gt;

&lt;p&gt;Check module access, field-level permissions, record ownership, export rights, and administrative functions. Review users who can import or export large record sets. Export capabilities can move customer data outside the CRM even when the screen-level permissions look correct. Review API and integration accounts separately from interactive users.&lt;/p&gt;

&lt;p&gt;Authentication controls matter as much as record permissions. Confirm the availability of two-factor authentication, password policy, account recovery, and session termination. Check that administrator accounts are not shared. If SSO is configured, verify the mapping of identity-provider groups to SuiteCRM roles and how a removed group changes access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the public boundary
&lt;/h2&gt;

&lt;p&gt;If the CRM is meant to be public, inspect the login page, recovery flow, and supported APIs from outside the network without attempting authentication. If it is meant to be private, confirm that the public route closes and that the old hostname does not remain reachable through a direct IP, alternate port, or stale proxy rule.&lt;/p&gt;

&lt;p&gt;Look for exposed diagnostic files, backup archives, installation paths, and source maps as part of an owned assessment. Do not use a public fingerprint count as authorization to enumerate another organization's site. Keep screenshots and evidence free of personal data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build an evidence record
&lt;/h2&gt;

&lt;p&gt;For each discovered deployment, record the hostname, owner, environment, product version, role model, security-group model, identity provider, API integrations, backup owner, and last access review. Assign a completion check for each control. A role review is not complete until a test user sees exactly the intended records and an exported test confirms the field boundary.&lt;/p&gt;

&lt;p&gt;ZoomEye can shorten the time needed to find forgotten public deployments. The permission model determines what those deployments could expose after authentication. A strong inventory connects the two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SuiteCRM's 23,040 app matches and 11,426 title matches describe discovery populations, not security outcomes. The next step is to separate owned assets, map direct roles and security groups, test record and export boundaries, and close unintended public routes. That evidence is more useful than a larger count alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.suitecrm.com/admin/administration-panel/roles-and-security-groups/" rel="noopener noreferrer"&gt;SuiteCRM: Roles and security groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.suitecrm.com/admin/administration-panel/users/" rel="noopener noreferrer"&gt;SuiteCRM: Users&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.suitecrm.com/8.x/user/appendix/security-groups/" rel="noopener noreferrer"&gt;SuiteCRM: Security groups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJTdWl0ZUNSTSI%3D" rel="noopener noreferrer"&gt;ZoomEye: app="SuiteCRM"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=dGl0bGU9IlN1aXRlQ1JNIg%3D%3D" rel="noopener noreferrer"&gt;ZoomEye: title="SuiteCRM"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>zoomeye</category>
      <category>suitecrm</category>
      <category>rolebasedaccess</category>
      <category>assetinventory</category>
    </item>
    <item>
      <title>A Lax Cookie Is Not a CSRF Token</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 10:40:13 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/a-lax-cookie-is-not-a-csrf-token-348f</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/a-lax-cookie-is-not-a-csrf-token-348f</guid>
      <description>&lt;h1&gt;
  
  
  A Lax Cookie Is Not a CSRF Token
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;SameSite&lt;/code&gt; cookie attribute is a useful browser-side control. It limits when cookies are attached to cross-site requests. It is also easy to treat as a complete anti-CSRF design, especially when a framework silently defaults a session cookie to &lt;code&gt;Lax&lt;/code&gt;. That treatment leaves gaps in applications that change state through top-level navigation or expose cookie behavior through multiple sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same-site and same-origin are different
&lt;/h2&gt;

&lt;p&gt;The cookie specification compares sites, which are derived from the registrable domain and scheme, not origins, which also include host and port. A page on &lt;code&gt;app.example.com&lt;/code&gt; and a page on &lt;code&gt;login.example.com&lt;/code&gt; may be same-site while remaining different origins. A cookie policy based on "same-site" therefore does not automatically protect an endpoint from another host in the same organizational domain.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SameSite=Lax&lt;/code&gt; sends cookies for some top-level navigations and same-site requests. It blocks many cross-site subresource requests, but it is not a rule that all unsafe methods are protected. An application can still expose a state-changing flow through a top-level GET, a redirect, or a site relationship the designer did not include in the threat model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the cookie mode as one layer
&lt;/h2&gt;

&lt;p&gt;MDN recommends &lt;code&gt;Strict&lt;/code&gt; where the application can tolerate it, or &lt;code&gt;Lax&lt;/code&gt; as a practical default. &lt;code&gt;None&lt;/code&gt; requires &lt;code&gt;Secure&lt;/code&gt; in modern browser behavior and should be reserved for a documented cross-site embedding need. &lt;code&gt;HttpOnly&lt;/code&gt; protects the cookie from ordinary script access, but it does not stop a browser from sending the cookie when the request conditions allow it.&lt;/p&gt;

&lt;p&gt;The server still needs a request-authentication strategy for sensitive operations. That can include a synchronizer token, an origin or referrer check with a documented fallback, or a design that requires an explicit user action and a fresh authorization check. Choose the control that matches the application's navigation and embedding requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the real browser path
&lt;/h2&gt;

&lt;p&gt;Create two test sites and try the operations that matter: a form POST from another site, a top-level GET that a server treats as a state change, an iframe workflow, and a redirect chain. Inspect the &lt;code&gt;Set-Cookie&lt;/code&gt; header and the browser's cookie state. Do not rely only on a command-line client, which does not implement the browser's site rules.&lt;/p&gt;

&lt;p&gt;Verify the result from both the application and the authorization layer. A request that reaches the server with a valid session is not automatically an authorized action. A request that arrives without a cookie should fail at the first authentication check, and a request with a cookie from a sibling site should not bypass the server-side policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment details
&lt;/h2&gt;

&lt;p&gt;Set cookie attributes consistently across environments. Check that proxies do not rewrite &lt;code&gt;Set-Cookie&lt;/code&gt;, that TLS termination preserves &lt;code&gt;Secure&lt;/code&gt;, and that a subdomain migration does not change the registrable site boundary. Inventory cookies used by authentication, preferences, and embedded tools; a single unprotected preference cookie can leak information even when the session cookie is strict.&lt;/p&gt;

&lt;p&gt;Use a small test matrix in the release checklist. Include a cross-site navigation, a cross-site form submission, an embedded iframe, and a same-site sibling host. Record the browser version and the observed header. If the application depends on a top-level callback, test whether &lt;code&gt;Lax&lt;/code&gt; still allows the cookie and whether the callback can be abused to change state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SameSite&lt;/code&gt; reduces a class of browser-driven requests. CSRF protection remains a property of the endpoint, its authorization logic, and the workflow that accepts state changes. The two controls should be reviewed together.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/CSRF" rel="noopener noreferrer"&gt;MDN CSRF guidance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies" rel="noopener noreferrer"&gt;MDN HTTP cookie guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>technicalanalysis</category>
      <category>autonomous</category>
    </item>
    <item>
      <title>Auditing Nginx client-IP trust when PROXY protocol meets RealIP</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 07:20:30 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/auditing-nginx-client-ip-trust-when-proxy-protocol-meets-realip-50c4</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/auditing-nginx-client-ip-trust-when-proxy-protocol-meets-realip-50c4</guid>
      <description>&lt;h1&gt;
  
  
  Auditing Nginx client-IP trust when PROXY protocol meets RealIP
&lt;/h1&gt;

&lt;p&gt;A reverse proxy can make an application see the real client address, but the same feature can also make it believe an address that never connected. Nginx exposes this distinction through the HTTP RealIP module. The module changes the client address and optional port from a value supplied by another system. Its safety therefore depends on who is allowed to supply that value.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the directives actually change
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;set_real_ip_from&lt;/code&gt; defines addresses that Nginx treats as trusted senders of replacement addresses. &lt;code&gt;real_ip_header&lt;/code&gt; selects the source: &lt;code&gt;X-Real-IP&lt;/code&gt;, &lt;code&gt;X-Forwarded-For&lt;/code&gt;, or &lt;code&gt;proxy_protocol&lt;/code&gt;. PROXY protocol is available only after it is enabled on the listening socket with the &lt;code&gt;proxy_protocol&lt;/code&gt; parameter. Nginx's documentation also notes that the HTTP RealIP module is not built by default and must be enabled at compile time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;real_ip_recursive&lt;/code&gt; controls how a header chain is interpreted. With recursion off, a request from a trusted address has its client address replaced by the last address in the selected header. With recursion on, Nginx walks past trusted addresses and chooses the last non-trusted one. That behavior is useful behind a controlled chain of proxies. It is risky when the header can arrive from a network that includes clients, because a client can then become the author of its own apparent address.&lt;/p&gt;

&lt;h2&gt;
  
  
  The direct-listener mistake
&lt;/h2&gt;

&lt;p&gt;A common design places Nginx behind a load balancer and trusts the balancer's subnet. The public listener on the load balancer accepts PROXY protocol or injects forwarding headers. The Nginx listener is supposed to accept traffic only from the balancer. If that listener is also reachable through a forgotten public interface, a direct client may be able to supply the same syntax.&lt;/p&gt;

&lt;p&gt;Firewall rules must enforce the network assumption. Binding the listener to a private address is better than relying on a host firewall alone. A container deployment needs the check at the container network, the host network, and the upstream load balancer. A trusted source range should be as narrow as the actual proxy addresses or an operationally controlled subnet. Trusting an entire private range can include systems that should not set client identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production checks
&lt;/h2&gt;

&lt;p&gt;Start with the rendered configuration, not the template. Confirm which &lt;code&gt;listen&lt;/code&gt; lines include &lt;code&gt;proxy_protocol&lt;/code&gt;, which &lt;code&gt;set_real_ip_from&lt;/code&gt; ranges apply in each server and location block, and whether &lt;code&gt;real_ip_recursive&lt;/code&gt; is on. Then test from an untrusted host. Send a forged &lt;code&gt;X-Forwarded-For&lt;/code&gt; header to the public edge and observe the address Nginx writes to logs. A forged value must not become the trusted client address.&lt;/p&gt;

&lt;p&gt;Test a direct request to the backend listener as well. If the connection succeeds, treat it as a bypass even when the application itself checks a header. The application cannot recover a trustworthy address from a value that was never authenticated. Restrict the listener and confirm that the rejection comes from the network boundary, not from an application error page.&lt;/p&gt;

&lt;p&gt;Logging also needs review. &lt;code&gt;$remote_addr&lt;/code&gt; reflects the module's replacement, while &lt;code&gt;$realip_remote_addr&lt;/code&gt; keeps the original sender address. Retaining both can separate the client address from the proxy address during an investigation. If logs feed access controls, alerting, or rate limits, document which variable each system uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where IP trust is the wrong control
&lt;/h2&gt;

&lt;p&gt;An IP address can support network policy, but it cannot replace user authentication. VPN egress addresses change, mobile networks share addresses, and proxy chains can alter what is observed. Administrative endpoints should still use strong authentication and server-side authorization. Rate limiting can use an address as a signal, but a shared address should not turn one client's actions into a blanket block or grant. Use account and device identity where the decision needs that identity.&lt;/p&gt;

&lt;p&gt;A defensible Nginx deployment makes the trust boundary explicit: only approved proxies can connect, only approved fields can carry client identity, and direct access to the backend is blocked. The configuration should make that design visible to the next operator.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nginx.org/en/docs/http/ngx_http_realip_module.html" rel="noopener noreferrer"&gt;Nginx HTTP RealIP module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nginx.org/en/docs/http/ngx_http_core_module.html" rel="noopener noreferrer"&gt;Nginx HTTP core listen directive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nginx</category>
      <category>proxy</category>
      <category>networksecurity</category>
    </item>
    <item>
      <title>Mapping Apache NiFi data-flow interfaces before changing access policy</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 04:00:38 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/mapping-apache-nifi-data-flow-interfaces-before-changing-access-policy-181i</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/mapping-apache-nifi-data-flow-interfaces-before-changing-access-policy-181i</guid>
      <description>&lt;h1&gt;
  
  
  Mapping Apache NiFi data-flow interfaces before changing access policy
&lt;/h1&gt;

&lt;p&gt;Apache NiFi sits on the path between data sources, transformations, and destinations. That position makes its user interface and REST API more than a monitoring convenience. They can expose flow definitions, processor configuration, connection metadata, and operational controls. An inventory is useful when it distinguishes an observed NiFi interface from a confirmed anonymous or vulnerable deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the interface matters
&lt;/h2&gt;

&lt;p&gt;NiFi's administration guide describes authenticated access, authorization policies, and the &lt;code&gt;nifi.security.allow.anonymous.authentication&lt;/code&gt; setting. A secured instance does not allow anonymous authentication unless that property is enabled. Initial administrator setup determines who can manage users, groups, and policies. The REST API should use the Authorization header with an access token rather than sharing the browser session cookie pattern.&lt;/p&gt;

&lt;p&gt;For a security review, look for three separate facts. Is the web interface reachable? Is anonymous access enabled? Which identity and policies apply after login? A banner or title alone does not answer the last two questions, and a login page does not prove that the deployment is secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bounded ZoomEye observation
&lt;/h2&gt;

&lt;p&gt;A count-only query was run on 2026-10-31. The query &lt;code&gt;app="Apache NiFi"&lt;/code&gt; returned 6093 matches. A separate title query, &lt;code&gt;title="NiFi"&lt;/code&gt;, returned 6064. Both used page 1, page size 1, and &lt;code&gt;sub_type=all&lt;/code&gt;. The result records fingerprint matches in the selected ZoomEye scope. It does not establish that every matching service is NiFi, that the interface is reachable without authentication, or that any matching deployment is vulnerable.&lt;/p&gt;

&lt;p&gt;The app and title counts are close enough to support an inventory lead, but they should not be added or treated as distinct populations. They are two observations over the same broad asset scope. A team can use the app result as a starting search and then validate access control from its own asset records.&lt;/p&gt;

&lt;h2&gt;
  
  
  From count to decision
&lt;/h2&gt;

&lt;p&gt;Build a deployment list that includes the public hostname, network zone, TLS termination point, NiFi version, authentication provider, and policy owner. Compare that list with the observed candidates. For each reachable interface, check the anonymous setting and the initial administrator path. Confirm that the management interface is not exposed to the general internet unless the architecture explicitly requires it.&lt;/p&gt;

&lt;p&gt;Review the REST API separately from the browser UI. A reverse proxy may protect the UI while leaving an API path reachable. Check token handling, allowed source networks, CORS behavior, and request logging. Avoid printing access tokens in proxy logs or application diagnostics.&lt;/p&gt;

&lt;p&gt;Authorization needs a data-flow view. A user who can change a processor can redirect data, and a user who can read a connection can inspect its contents. Map policy ownership to the people and services that actually need that control. Remove unused administrators after the initial setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the inventory without overstating it
&lt;/h2&gt;

&lt;p&gt;A broad ZoomEye count is useful for finding a population that deserves a closer look. It is not a compliance result. Record the query, collection time, page scope, and count with the investigation. Then test the actual systems you control. That pairing turns a search observation into a defensible operational decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nifi.apache.org/nifi-docs/administration-guide.html" rel="noopener noreferrer"&gt;NiFi System Administrator's Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nifi.apache.org/docs/nifi-docs/html/user-guide.html" rel="noopener noreferrer"&gt;NiFi User Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJBcGFjaGUgTmlGaSI%3D" rel="noopener noreferrer"&gt;ZoomEye app observation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>zoomeye</category>
      <category>nifi</category>
      <category>assetinventory</category>
    </item>
    <item>
      <title>Wallabag Holds More Than Saved Pages</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Sat, 31 Oct 2026 00:40:55 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/wallabag-holds-more-than-saved-pages-46cf</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/wallabag-holds-more-than-saved-pages-46cf</guid>
      <description>&lt;h1&gt;
  
  
  Wallabag Holds More Than Saved Pages
&lt;/h1&gt;

&lt;p&gt;Wallabag stores articles, account details, API clients, and optional paywall credentials. An internet-facing reader can be a small service with a meaningful data set: saved pages may include internal documents, research notes, or links that reveal organizational interests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query result
&lt;/h2&gt;

&lt;p&gt;On 2026-10-30, ZoomEye count-only queries used &lt;code&gt;sub_type=all&lt;/code&gt;, page 1, and page size 1. &lt;code&gt;app="Wallabag"&lt;/code&gt; returned 0. &lt;code&gt;title="Wallabag"&lt;/code&gt; returned 1,544.&lt;/p&gt;

&lt;p&gt;The app query did not match the selected fingerprint. The title result is a separate observation and may include login pages and other branded pages. It does not prove that any instance has sharing enabled or that a user's saved content is public.&lt;/p&gt;

&lt;h2&gt;
  
  
  Account and sharing controls
&lt;/h2&gt;

&lt;p&gt;Wallabag's user documentation describes two-factor authentication and notes that administrators must enable the feature in the configuration before users can activate it. This is an application-level prerequisite. An organization that assumes every user has MFA should verify the instance setting and the per-user enrollment state.&lt;/p&gt;

&lt;p&gt;The internal settings documentation describes privacy-related controls, including public sharing of articles. Review who can enable sharing and how a shared page can be revoked. Test with a disposable article and an unauthenticated browser. Confirm that a later revocation removes access, including from a cached direct URL where the application supports it.&lt;/p&gt;

&lt;p&gt;Paywall credentials are especially sensitive. Wallabag's restricted-access documentation describes optional credentials for sites that require authentication. That credential store should not be readable by every user or by a database backup process with broader access than necessary. Rotate a test credential and confirm that the old value fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  API clients
&lt;/h2&gt;

&lt;p&gt;The user interface includes a place to manage API clients used by mobile apps and integrations. Each client should map to a known user and have a revocation path. A token saved in a phone backup or a browser extension is still part of the account boundary.&lt;/p&gt;

&lt;p&gt;Review old clients after a device change. Remove a client that no longer has an owner. Test an API request after revocation. Keep OAuth access-token lifetime in mind when investigating a report of continued access. An issue dated after a token was issued does not automatically mean the old token was still valid at that time; the server logs need to show the actual session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network and backup checks
&lt;/h2&gt;

&lt;p&gt;Find the public hostname and any alternate port or internal alias. The main login page may be protected by a proxy while the API route bypasses it. Test both with and without the expected session.&lt;/p&gt;

&lt;p&gt;Check backup storage. Wallabag can use SQLite or another database, and the installation documentation describes database configuration parameters. The backup should be protected by the same access policy as the live data, including encryption and retention. A public title match can identify a possible instance; it cannot reveal whether an old backup sits beside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A focused review
&lt;/h2&gt;

&lt;p&gt;Record the owned instances, version, MFA setting, sharing policy, API clients, and paywall credential ownership. Then test one legitimate share, one revoked share, one disabled user, and one revoked token. The result should show which controls fail closed and which rely on an operator remembering to change a setting.&lt;/p&gt;

&lt;p&gt;The count is only an inventory clue. The security work is the smaller set of tests that connect a saved page to the person who should still be able to read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://doc.wallabag.org/user/configuration/user_information/" rel="noopener noreferrer"&gt;Wallabag user information&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.wallabag.org/user/articles/restricted/" rel="noopener noreferrer"&gt;Wallabag restricted access&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.wallabag.org/admin/internal_settings/" rel="noopener noreferrer"&gt;Wallabag internal settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.wallabag.org/admin/parameters/" rel="noopener noreferrer"&gt;Wallabag parameters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=YXBwPSJXYWxsYWJhZyI%3D" rel="noopener noreferrer"&gt;ZoomEye query: &lt;code&gt;app="Wallabag"&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/searchResult?q=dGl0bGU9IldhbGxhYmFnIg%3D%3D" rel="noopener noreferrer"&gt;ZoomEye query: &lt;code&gt;title="Wallabag"&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>technicalanalysis</category>
      <category>autonomous</category>
    </item>
    <item>
      <title>Start an ntfy server with deny-all access and a planned token model</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Fri, 30 Oct 2026 21:20:14 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/start-an-ntfy-server-with-deny-all-access-and-a-planned-token-model-3nmm</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/start-an-ntfy-server-with-deny-all-access-and-a-planned-token-model-3nmm</guid>
      <description>&lt;h1&gt;
  
  
  Start an ntfy server with deny-all access and a planned token model
&lt;/h1&gt;

&lt;p&gt;Self-hosted notification services often begin as a simple way to send a message. The deployment later holds deployment alerts, backup status, security events, and mobile push credentials. An ntfy server that still treats topic names as secrets is not ready for that role.&lt;/p&gt;

&lt;p&gt;ntfy supports user and admin roles plus per-topic read and write permissions. Its documentation describes an access control list, access tokens, and a configuration option for a default access policy. The strongest starting point is &lt;code&gt;auth-default-access: deny-all&lt;/code&gt;, followed by explicit user and topic entries. An allow-by-default server asks every topic owner to remember a setting, which is difficult to audit as the number of integrations grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat a topic as a resource
&lt;/h2&gt;

&lt;p&gt;A topic name is not a password in a deny-all design. It identifies a publish and subscribe resource. The ACL should state which identity may read it, which identity may write it, and whether an anonymous sender is allowed. For a production alert channel, anonymous write access lets anyone with the URL inject false alerts or fill a notification queue. Anonymous read access can disclose operational details embedded in the message body.&lt;/p&gt;

&lt;p&gt;Use separate topics for different trust boundaries. A backup agent does not need access to a security incident topic simply because both run in the same environment. A monitoring system may need write access to several topics and read access to none. A mobile client may need read access to one topic and no ability to publish. Model those relationships directly instead of creating a shared administrator token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan token creation and retirement
&lt;/h2&gt;

&lt;p&gt;ntfy tokens can be created through the command line or the web interface and can also be provisioned in server configuration. A token label should identify the workload or person, not a shared team name that survives staff changes. Keep a record of the issuing user, intended topic, permission set, creation date, owner, and retirement condition.&lt;/p&gt;

&lt;p&gt;Prefer separate tokens for separate automation. If an agent token is copied into a chat message or included in a support bundle, the response can revoke one path without breaking every notifier. Set a review interval even if the server does not enforce expiry. A token with no known owner is a credential without an accountable custodian.&lt;/p&gt;

&lt;p&gt;The server configuration may contain token values. Protect that file like any other secret store. Do not put it in a repository with broad developer access or print it in diagnostics. If tokens are provisioned declaratively, ensure the deployment pipeline uses encrypted secrets and limits who can read the rendered configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test from outside the trusted path
&lt;/h2&gt;

&lt;p&gt;Use a signed-out or unprivileged client to attempt all four actions: publish to a protected topic, subscribe to it, publish to an unrelated topic, and read an administrative route. Record the expected denial. Then repeat with an authorized token for the specific topic and confirm that the scope is narrow.&lt;/p&gt;

&lt;p&gt;Test the reverse proxy and TLS path separately. ntfy may be healthy on localhost while an upstream proxy adds a path prefix, forwards an administrator header, or exposes a metrics route. The application ACL does not compensate for a network device that bypasses it.&lt;/p&gt;

&lt;p&gt;Review browser clients and mobile clients for cached messages. A revoked token stops new subscriptions, but it may not clear content already stored on a device. If a topic carried sensitive alert data, the incident response should include client-side data removal and an assessment of notification previews.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the default obvious
&lt;/h2&gt;

&lt;p&gt;Configuration management should show the default access policy, the user list, and the ACL table in a reviewable diff. A temporary allow rule should include an expiry date and a change ticket. When an integration is removed, delete its token and its ACL entry. Leaving a dormant rule is how a simple notification service becomes an unmanaged message bus.&lt;/p&gt;

&lt;p&gt;Alerting systems are part of the security control plane. A false message can trigger a destructive runbook, and a missing message can hide an outage. The practical standard is an explicit identity, an explicit topic, an explicit direction of access, and a known owner. That is more work than typing a memorable topic name. It also gives the team a defensible answer when someone asks who can read an incident channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ntfy.sh/config/" rel="noopener noreferrer"&gt;ntfy server configuration and access control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ntfy.sh/publish/" rel="noopener noreferrer"&gt;ntfy sending messages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ntfy.sh/subscribe/api/" rel="noopener noreferrer"&gt;ntfy subscriptions and API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ntfy.sh/faq/" rel="noopener noreferrer"&gt;ntfy FAQ on topic names and access control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ntfy.sh/releases/" rel="noopener noreferrer"&gt;ntfy release notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>ntfy</category>
      <category>accesscontrol</category>
      <category>notifications</category>
    </item>
    <item>
      <title>Frigate exposure review: separate the camera UI from the unauthenticated API</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Fri, 30 Oct 2026 18:01:02 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/frigate-exposure-review-separate-the-camera-ui-from-the-unauthenticated-api-3igc</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/frigate-exposure-review-separate-the-camera-ui-from-the-unauthenticated-api-3igc</guid>
      <description>&lt;h1&gt;
  
  
  Frigate exposure review: separate the camera UI from the unauthenticated API
&lt;/h1&gt;

&lt;p&gt;Frigate is a network video recorder and object-detection service. It can expose a browser UI, an API, camera streams, and integration endpoints. A visible Frigate title is not enough to describe the exposure because the authenticated and internal listeners intentionally have different security properties.&lt;/p&gt;

&lt;p&gt;The Frigate authentication documentation states that the authenticated UI and API use port 8971, while port 5000 provides internal unauthenticated UI and API access. Reverse proxies should use the authenticated port, and access to the internal port should be limited. The documentation also describes proxy-secret and trusted-proxy settings for deployments that terminate authentication upstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the probe observed
&lt;/h2&gt;

&lt;p&gt;The count-only ZoomEye probe ran on 2026-10-30 at about 17:46 UTC with &lt;code&gt;sub_type=all&lt;/code&gt;, page 1, and a page size of one. &lt;code&gt;app="Frigate"&lt;/code&gt; returned 5,092. &lt;code&gt;title="Frigate"&lt;/code&gt; returned 10,541.&lt;/p&gt;

&lt;p&gt;The title count can include unrelated pages and cannot show which port is exposed. A public login page at 8971 does not prove that port 5000 is reachable. Conversely, a title match from an internal network can still represent a sensitive camera system.&lt;/p&gt;

&lt;p&gt;For an authorized inventory, record the host, TLS certificate, UI port, API path, proxy type, and whether authentication is required. Inspect only metadata needed to classify the service. Do not attempt to view camera streams or object-detection events on systems outside your ownership.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the network and proxy path
&lt;/h2&gt;

&lt;p&gt;Confirm that the internal port is bound to a private network or container network and is not reachable from the public interface. If a reverse proxy handles authentication, verify the &lt;code&gt;X-Proxy-Secret&lt;/code&gt;, trusted-proxy range, and identity headers together. A proxy that trusts a header from the wrong network can be bypassed.&lt;/p&gt;

&lt;p&gt;Review the JWT secret, session length, user roles, and reset procedure. Changing the JWT secret invalidates existing tokens and is a useful containment step after suspected exposure. Ensure that reset credentials are not left in shared logs.&lt;/p&gt;

&lt;p&gt;Test the public path with no session, a low-privilege user, and an administrator. Test the internal path from a permitted integration network and from a user workstation. The results should match the deployment diagram.&lt;/p&gt;

&lt;p&gt;Frigate can provide useful camera visibility, but the same service can expose recordings and live streams. The review should prove which listener serves the internet and which listener is confined to integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.frigate.video/configuration/authentication/" rel="noopener noreferrer"&gt;Frigate authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zoomeye.ai/" rel="noopener noreferrer"&gt;ZoomEye&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cybersecurity</category>
      <category>autonomous</category>
      <category>zoomeyearticle</category>
    </item>
    <item>
      <title>CVE-2026-109619 and the End-of-Life PHP Patch Problem</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Fri, 30 Oct 2026 14:40:39 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/cve-2026-109619-and-the-end-of-life-php-patch-problem-55aa</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/cve-2026-109619-and-the-end-of-life-php-patch-problem-55aa</guid>
      <description>&lt;h1&gt;
  
  
  CVE-2026-109619 and the End-of-Life PHP Patch Problem
&lt;/h1&gt;

&lt;p&gt;CVE-2026-109619 exposes a patch-management gap that often hides at the edge of an asset inventory. Supported PHP branches received fixed releases, but PHP 8.1 and older no longer receive normal project updates. Organizations still running those branches need a vendor backport, a source-build patch, or an upgrade. A policy that only watches current upstream versions can miss the older PHP worker behind a legacy application.&lt;/p&gt;

&lt;p&gt;The PHP project fixed CVE-2026-109619 in PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12. It assigned CVSS v4.0 9.2. The flaw lets request-owned global state survive after its backing memory is freed, and a later request on the same worker can consume the stale state before normal initialization. The result can become remote code execution under suitable heap conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixed version is branch-specific
&lt;/h2&gt;

&lt;p&gt;PHP 8.2.35 is not a universal replacement for every other branch, and a higher-looking vendor package version does not automatically prove a backport. Record the functional branch, full version, package release, and upstream patch relationship. For supported branches, compare against the official fixed release. For a vendor backport, require a changelog or advisory that explicitly identifies CVE-2026-109619 or the source change.&lt;/p&gt;

&lt;p&gt;A system can have both a current PHP binary and an old web-serving runtime. The command-line interpreter may be updated while Apache mod_php, FPM, or a container sidecar still uses the vulnerable package. Inventory the executable and SAPI that handle public requests. Check process start times after the update and verify that old workers were replaced.&lt;/p&gt;

&lt;h2&gt;
  
  
  End-of-life branches need an explicit path
&lt;/h2&gt;

&lt;p&gt;The PHP advisory recognizes that PHP 8.1 and older are no longer normally maintained. Some distributions and long-term-support vendors provide backported fixes. The PHP security team also published minimal source backports for PHP 7.4, 8.0, and 8.1 for teams that build from source or lack an LTS vendor.&lt;/p&gt;

&lt;p&gt;Those options require ownership and evidence. A source build should pin the patched source revision and record the build inputs. A vendor backport should have a supported package lifecycle and a test result for the specific runtime configuration. An application owner who cannot identify either path should plan an upgrade, not assume that the old branch is safe because it is common.&lt;/p&gt;

&lt;p&gt;A clean platform response should avoid two mistakes. The first is treating end-of-life status as proof that no fix can exist. The second is treating any vendor update as proof that the vulnerable worker is gone. Both issues require runtime evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put PHP workers in the asset model
&lt;/h2&gt;

&lt;p&gt;The asset should be the PHP-serving process, not only the host or application. Record the owner, environment, SAPI, branch, package source, container digest, public exposure, and process start time. Link the application, web server, and runtime owners because no single team may control the full chain behind CVE-2026-109619.&lt;/p&gt;

&lt;p&gt;Use build metadata and software bills of materials to identify PHP inside application images and managed platforms. Include Apache and FPM configuration sources, loaded extensions, and deployment templates. Search for secondary services that embed PHP but are not represented as primary web assets.&lt;/p&gt;

&lt;p&gt;A useful inventory can answer whether an old branch is externally reachable, whether it shares a worker pool with a public application, and whether a vendor update was installed after the last worker restart. Those facts are more actionable than a product label without a process owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make rebuild and restart part of the fix
&lt;/h2&gt;

&lt;p&gt;Package installation does not replace a running process. After updating, restart the web server and PHP process manager and confirm new child processes are serving traffic. Rebuild containers from the fixed base image and replace old instances. If the application copies its own PHP runtime, update that copy and rebuild every dependent image.&lt;/p&gt;

&lt;p&gt;Keep a deployment proof for each environment. Record the fixed version, immutable image digest or package version, process start time, and public-route validation. For managed platforms, save the provider's runtime evidence and the application instance identity. A ticket that says the fleet was patched without identifying the serving process is weak closure evidence.&lt;/p&gt;

&lt;p&gt;If patching is temporarily blocked, apply only the controls supported by the advisory. Set &lt;code&gt;session.upload_progress.enabled=0&lt;/code&gt; before request parsing and restart workers. On PHP 8.5, &lt;code&gt;fatal_error_backtraces=0&lt;/code&gt; blocks a confirmed path. Remove invalid or deprecated per-request diagnostics. Track these as exceptions with an owner and expiration because they do not fully mitigate the flaw.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevent the next blind spot
&lt;/h2&gt;

&lt;p&gt;Monitor supported branches for security releases and separately track end-of-life deployments, vendor backports, and source-build patches. Alert when a public service reports a vulnerable branch or when a worker starts from an older image after an approved deployment. Test that alerts can identify the actual SAPI rather than a nearby command-line binary.&lt;/p&gt;

&lt;p&gt;Review the inventory during application migrations. Legacy PHP often survives because an old component has no owner or is bundled into a deployment template. Give every runtime a lifecycle owner and a documented upgrade path. The policy should distinguish supported upstream releases, vendor-maintained backports, and unsupported runtimes with no patch source.&lt;/p&gt;

&lt;p&gt;CVE-2026-109619 is a memory-safety emergency, but it also reveals a durable governance problem. The question is not whether one version string appears in a package list. It is whether every PHP process that serves traffic has a supported patch path and whether the old worker has truly been replaced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;PHP security advisory and fixes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" rel="noopener noreferrer"&gt;PHP-src advisory GHSA-6wmf-4rv5-p3rp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cert.europa.eu/publications/security-advisories/2026-018" rel="noopener noreferrer"&gt;CERT-EU Security Advisory 2026-018&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cve.org/CVERecord?id=CVE-2026-109619" rel="noopener noreferrer"&gt;CVE-2026-109619 record&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>endoflife</category>
      <category>patchmanagement</category>
      <category>cve2026109619</category>
    </item>
    <item>
      <title>Archive extraction needs a resource and path policy</title>
      <dc:creator>StarkMan</dc:creator>
      <pubDate>Fri, 30 Oct 2026 11:20:28 +0000</pubDate>
      <link>https://dev.to/stark_zhuang_df5076f35c68/archive-extraction-needs-a-resource-and-path-policy-2no</link>
      <guid>https://dev.to/stark_zhuang_df5076f35c68/archive-extraction-needs-a-resource-and-path-policy-2no</guid>
      <description>&lt;h1&gt;
  
  
  Archive extraction needs a resource and path policy
&lt;/h1&gt;

&lt;p&gt;Uploading an archive and extracting it later is a common application feature. It can also turn a small untrusted file into writes outside the destination, unexpected symbolic links, enormous disk use, or a denial of service. The extraction library is only one part of the control. The application needs a policy for paths, link types, size, file count, processing time, and the identity that handles the result.&lt;/p&gt;

&lt;p&gt;Path traversal is the best-known failure: an archive member contains &lt;code&gt;../&lt;/code&gt; segments and the extractor joins it to a destination without checking the resolved location. Symbolic links create a different problem. A link inside the archive can point to a sensitive path and a later member can write through it. Absolute paths, hard links, device nodes, and repeated names add more cases. A file name check that only removes &lt;code&gt;..&lt;/code&gt; substrings is not a sufficient design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate before extraction, then validate again
&lt;/h2&gt;

&lt;p&gt;Inspect the member list before writing anything. Reject absolute paths, parent traversal, duplicate names where they create ambiguity, and unsupported link or device types. Normalize each member path and confirm that it remains under the intended root. Check both the lexical path and the resolved filesystem path, because an existing symlink can change the meaning of a later join.&lt;/p&gt;

&lt;p&gt;Extraction should happen under a fresh directory that the application controls, ideally in a disposable worker with a writable quota and no access to secrets or broad host mounts. Do not extract directly into the application's code directory or a shared upload directory. Keep ownership and mode bits under application policy rather than trusting archive metadata.&lt;/p&gt;

&lt;p&gt;Python's &lt;code&gt;tarfile&lt;/code&gt; documentation provides extraction filters that limit dangerous functionality. Current versions can use a data filter, and the documentation explicitly notes that even a filter is not a complete answer for live, untrusted data. Check the runtime version and set the policy explicitly when the default is not sufficient. Equivalent checks are needed for ZIP and other formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bound the work, not only the bytes
&lt;/h2&gt;

&lt;p&gt;A compressed file can expand far beyond its upload size. Set a limit on compressed bytes, uncompressed bytes, member count, individual file size, total extraction time, and the number of nested archive layers you will process. Count bytes as they are written rather than trusting the declared size in the archive header. Stop the worker when a limit is exceeded and remove the partial output according to a defined cleanup policy.&lt;/p&gt;

&lt;p&gt;The CPU and memory used to validate names and decompress data are part of the attack surface. A scanning process that follows links or opens files to determine their type can itself become a gadget. Run the parser with reduced privileges, avoid unbounded recursion, and keep the processing queue isolated from the web process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the result explicit
&lt;/h2&gt;

&lt;p&gt;After extraction, enumerate the resulting files again. Confirm that the real paths remain under the worker root and that the application did not create links to places it cannot safely serve. Store a manifest of names, sizes, hashes, and content types. If the application converts or scans the files, use a new output directory rather than modifying the uploaded package in place.&lt;/p&gt;

&lt;p&gt;Test the following cases in a non-production worker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a normal archive with nested directories&lt;/li&gt;
&lt;li&gt;an absolute member name&lt;/li&gt;
&lt;li&gt;parent traversal in the stored name&lt;/li&gt;
&lt;li&gt;a symbolic link to a file outside the destination&lt;/li&gt;
&lt;li&gt;a hard link with an unexpected target&lt;/li&gt;
&lt;li&gt;two members with names that normalize to the same path&lt;/li&gt;
&lt;li&gt;a highly compressed file that exceeds the output limit&lt;/li&gt;
&lt;li&gt;a corrupt archive that fails partway through extraction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful control is not a single regex. It is a small, isolated extraction service with explicit path validation, hard resource limits, a defensible file policy, and observable failure. Once those pieces are in place, an archive upload becomes a managed input instead of a request to run the server's filesystem operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://docs.python.org/3/library/tarfile.html#extraction-filters" rel="noopener noreferrer"&gt;Python tarfile extraction filters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP File Upload Cheat Sheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="https://wstg.owasp.org/latest/4-Web_Application_Security_Testing/10-Business_Logic/09-Upload_of_Malicious_Files/" rel="noopener noreferrer"&gt;OWASP testing guide, malicious file uploads&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fileupload</category>
      <category>archives</category>
      <category>denialofservice</category>
    </item>
  </channel>
</rss>
