<?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[ResaHost]]></title><description><![CDATA[ResaHost]]></description><link>https://resahost.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 13 Nov 2026 19:49:28 GMT</lastBuildDate><atom:link href="https://resahost.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Keep secrets out of reach of your coding agent]]></title><description><![CDATA[Coding agents that run in a terminal can read files, run commands and commit code. That is the point of them, and it is also why they change where secrets…]]></description><link>https://resahost.hashnode.dev/keep-secrets-out-of-reach-of-your-coding-agent</link><guid isPermaLink="true">https://resahost.hashnode.dev/keep-secrets-out-of-reach-of-your-coding-agent</guid><category><![CDATA[Security]]></category><category><![CDATA[AI]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Git]]></category><dc:creator><![CDATA[Olli Junes]]></dc:creator><pubDate>Thu, 12 Nov 2026 14:02:31 GMT</pubDate><content:encoded><![CDATA[<p>Coding agents that run in a terminal can read files, run commands and commit code. That is the point of them, and it is also why they change where secrets are exposed. A <code>.env</code> file that was a harmless local convenience becomes something an automated process can read, and anything the process can read can end up in a prompt, a log or a command someone else steered it into running.</p>
<p>We provide managed hosting and website maintenance at ResaHost, and we set up and manage 1Password Business for customers, so we have a commercial interest in how teams handle secrets. This article uses 1Password only as one documented example, and the principles apply to any secrets manager.</p>
<h2>The risk is not only a bad model, it is untrusted input</h2>
<p><a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">OWASP's LLM01 entry on prompt injection</a> describes indirect prompt injection: the model accepts input from external sources such as websites or files, and that content alters its behaviour. OWASP lists disclosure of sensitive information, unauthorised access to functions available to the model and executing arbitrary commands in connected systems among the possible outcomes. It also states that it is unclear whether fool-proof prevention exists, and recommends limiting the impact instead.</p>
<p>For a developer this means a README, an issue comment, a dependency's documentation or a web page the agent fetches can contain text meant for the agent. You cannot rely on reading every input yourself. The design question becomes: if the agent follows a hostile instruction, what can it reach?</p>
<p>OWASP's mitigations map directly onto that question. They include enforcing privilege control and least privilege access, requiring human approval for high-risk actions, and segregating untrusted external content from instructions.</p>
<h2>Principle 1: the agent should not hold more than the task needs</h2>
<p>The <a href="https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html">OWASP Secrets Management Cheat Sheet</a> notes that many organisations hard-code secrets in source or leave them in configuration files, and recommends centralising storage, provisioning, auditing and rotation. It also says engineers should not have access to all secrets in the system, and that fine-grained access control should apply least privilege.</p>
<p>For an agent session, apply the same rule:</p>
<ul>
<li>Use a separate, low-privilege credential for the agent, not your personal admin token.</li>
<li>Do not give it production credentials unless the task is a production task.</li>
<li>Prefer credentials that are limited to one repository, one environment or one API scope.</li>
</ul>
<h2>Principle 2: short-lived beats long-lived</h2>
<p>OWASP recommends dynamic secrets where possible, with a short lease and revocation when they are no longer needed, and automated rotation for static secrets. An API key that expires after an hour is worth much less to anyone who extracts it than a key that lives for years. If your provider supports scoped, expiring tokens, use them for agent sessions.</p>
<h2>Principle 3: keep secrets off disk and out of history</h2>
<p>Plaintext <code>.env</code> files get committed, copied, backed up and read by whatever runs in the directory. Two documented ways to reduce that:</p>
<ol>
<li>Secret references. With the <a href="https://developer.1password.com/docs/cli/secret-references/">1Password CLI</a>, you store a reference such as <code>op://vault/item/field</code> in your configuration instead of the secret. <code>op run</code> replaces the reference with the real value only for the subprocess it starts. The documentation recommends service accounts that are restricted to specific vaults, so processes in the session can only access the items needed.</li>
<li>An SSH agent. The <a href="https://developer.1password.com/docs/ssh/agent/">1Password SSH agent</a> lets Git and SSH clients authenticate without being able to read the private key, and only clients you explicitly authorise can use the key until 1Password locks.</li>
</ol>
<p>Be precise about what this achieves. Secret references keep the value out of files and shell history. They do not make the value invisible to a process you start with them. A subprocess that receives a secret as an environment variable can print it, and an agent that can run arbitrary commands in that environment can be asked to. So the second half of the defence is scope: the vault or service account behind the reference should contain only what that session needs.</p>
<h2>Principle 4: catch what leaks anyway</h2>
<p>Mistakes happen, so add detection. OWASP suggests secrets detection at developer level, in the IDE or through a pre-commit hook, so secrets are not committed. On the repository side, <a href="https://docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning">GitHub secret scanning</a> detects credentials committed to repositories, and push protection is a related feature. When a secret is exposed, rotate or revoke it. OWASP is explicit that removing it from the exposed system is part of the response.</p>
<h2>Principle 5: keep a human at the risky steps</h2>
<p>Do not run an agent in an auto-approve mode with broad credentials. Require review of the diff before a commit lands, and approval before the agent runs commands that touch deployment, billing, DNS or credentials. If an agent suddenly asks for access to something the task does not need, stop the session and look at what it read before that point. This is the OWASP recommendation of human approval for high-risk actions, applied to a terminal.</p>
<p>Also keep an audit trail. OWASP lists what to log at a minimum: who requested a secret and for which system, whether the request was approved, when it was used, and when it expired.</p>
<h2>A starting checklist</h2>
<ol>
<li>Move every long-lived key out of <code>.env</code> files and into a secrets manager.</li>
<li>Create a dedicated, scoped credential for agent sessions.</li>
<li>Turn on secret scanning and push protection for your repositories.</li>
<li>Keep production credentials out of agent sessions by default.</li>
<li>Review diffs before commits, and require approval for high-risk commands.</li>
<li>Rotate any key an agent session may have seen.</li>
</ol>
<p>We list eight related controls for terminal-based coding in our article on <a href="https://resahost.net/en/blog/ai-coding-security/">AI-assisted coding in the terminal</a>. The ones above are the part that concerns secrets, and each rests on a public source.</p>
<h2>Sources</h2>
<ol>
<li><a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">OWASP GenAI: LLM01 Prompt Injection</a></li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html">OWASP Secrets Management Cheat Sheet</a></li>
<li><a href="https://developer.1password.com/docs/cli/secret-references/">1Password Developer: Use secret references with 1Password CLI</a></li>
<li><a href="https://developer.1password.com/docs/ssh/agent/">1Password Developer: 1Password SSH Agent</a></li>
<li><a href="https://docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning">GitHub Docs: About secret scanning</a></li>
<li><a href="https://resahost.net/en/blog/ai-coding-security/">ResaHost: AI-assisted coding in the terminal (commercial source)</a></li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Rolling out a password manager in a small company: the order matters]]></title><description><![CDATA[Installing a password manager takes an afternoon. The benefit arrives only when the shared logins are inside it and no longer sit in chat threads…]]></description><link>https://resahost.hashnode.dev/rolling-out-a-password-manager-in-a-small-company-the-order-matters</link><guid isPermaLink="true">https://resahost.hashnode.dev/rolling-out-a-password-manager-in-a-small-company-the-order-matters</guid><category><![CDATA[Security]]></category><category><![CDATA[passwords]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Olli Junes]]></dc:creator><pubDate>Thu, 12 Nov 2026 14:01:37 GMT</pubDate><content:encoded><![CDATA[<p>Installing a password manager takes an afternoon. The benefit arrives only when the shared logins are inside it and no longer sit in chat threads, spreadsheets and one person's browser. This is a rollout order for a small company, with the reasoning behind each step.</p>
<p>We provide managed hosting and website maintenance at ResaHost, and we set up and manage 1Password Business for customers, so we have a commercial interest in this subject. The steps below are not specific to one product, and where we describe product behaviour we link the vendor's own documentation.</p>
<h2>Why reuse is the problem to solve</h2>
<p>The attack to design against is credential stuffing: the <a href="https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html">OWASP Credential Stuffing Prevention Cheat Sheet</a> defines it as testing username and password pairs obtained from the breach of another site. If an employee uses the same password for a supplier portal and for the company mailbox, the portal's breach becomes your incident. OWASP names multi-factor authentication as by far the best defence against password attacks of this kind, so a password manager and MFA belong together.</p>
<p>The <a href="https://www.ncsc.gov.uk/collection/top-tips-for-staying-secure-online/password-managers">UK NCSC</a> gives the same reasoning for a unique password per account, notes that nobody can remember that many, and recommends turning on two-step verification on the password manager account as well. NIST's authentication guideline, <a href="https://pages.nist.gov/800-63-4/sp800-63b.html">SP 800-63B</a>, goes further for service owners: verifiers shall allow password managers and autofill, and should permit pasting into password fields. If you run a login form for your own product, blocking paste works against your users' security.</p>
<h2>1. Inventory where the logins live today</h2>
<p>List the services your team signs in to, and for each one note where the login is kept and who uses it. Developers and site owners should include the less obvious ones: domain registrar, DNS provider, hosting control panel, SSH and database credentials, payment and analytics accounts, and the shared inbox that receives password resets. Mark the email accounts used to reset other passwords. Whoever controls those can usually reach everything else.</p>
<h2>2. Decide on vaults and two administrators</h2>
<p>Keep the vault structure small. A shared vault for logins everyone uses, one for finance, and one for website, domain and infrastructure access is enough for a small company. Vaults should follow who needs to see what, not mirror a list of services.</p>
<p>Name at least two administrators. If the only administrator is away or leaves, nobody can add users or recover a locked-out account. Check how recovery works in the product you pick before you rely on it.</p>
<h2>3. Understand what protects the vault</h2>
<p>With 1Password, for example, the data is encrypted with a key derived from two things: the account password and a Secret Key. According to 1Password's <a href="https://support.1password.com/secret-key-security/">documentation</a>, the Secret Key has 128 bits of entropy and is stored on the user's devices and in the Emergency Kit rather than with the vendor, and the account password, which has to be memorised, has about 40 bits of entropy on average. Those two figures explain why the account password still has to be long and unique, and why losing the Secret Key without a saved Emergency Kit can lock you out. Other products design this differently, so read the vendor's security model before you decide.</p>
<h2>4. Move the logins, then delete the old copies</h2>
<p>Import from browsers or spreadsheets, check the result, and then remove the originals. If you skip the deletion step, the logins live in two places again, which is worse than before because nobody knows which copy is current. A browser export is an unencrypted file, so delete it, including from the trash, as soon as the import is verified.</p>
<h2>5. Replace the reused and weak passwords</h2>
<p>Moving a weak password into a vault only stores it neatly. Work through the manager's warnings for reused, weak and breached passwords in order of importance: email first, then the domain registrar, bank, accounting, cloud storage and the website admin. Generate random replacements and turn on MFA at the same time where the service supports it. The NCSC also recommends passkeys as the first choice wherever a service offers them, with a unique password plus two-step verification elsewhere.</p>
<p>This step does not have to happen in one day. Agree who handles the list and by when.</p>
<h2>6. Share with outsiders through the manager</h2>
<p>Accountants, freelancers and stand-in staff sometimes need a login. Sending it by email or text puts a secret in two mailboxes with no expiry. Many business password managers can share an item with a time limit or give a guest access to a single vault. Use that and review it when the engagement ends.</p>
<h2>7. Write the leaver checklist</h2>
<p>Removing a departing employee's account is not enough, because they may have seen or copied shared passwords. Because the logins now sit in vaults, you can list which vaults they could open and rotate the most important credentials in those vaults. Without a password manager that list usually does not exist, which is why old shared passwords stay in use for years.</p>
<h2>When to ask for help</h2>
<p>A ten-person company can do all of this itself if someone has the time. We describe the same rollout, step by step, in our guide to <a href="https://resahost.net/en/guides/password-manager-rollout-for-small-businesses/">rolling out a password manager in a small business</a>. It is written around 1Password Business because that is the product we deliver, and we say so there as well.</p>
<h2>Sources</h2>
<ol>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html">OWASP: Credential Stuffing Prevention Cheat Sheet</a></li>
<li><a href="https://www.ncsc.gov.uk/collection/top-tips-for-staying-secure-online/password-managers">UK NCSC: Password managers</a></li>
<li><a href="https://pages.nist.gov/800-63-4/sp800-63b.html">NIST SP 800-63B: Authentication and Authenticator Management</a></li>
<li><a href="https://support.1password.com/secret-key-security/">1Password Support: About your Secret Key</a></li>
<li><a href="https://resahost.net/en/guides/password-manager-rollout-for-small-businesses/">ResaHost guide: Rolling out a password manager in a small business (commercial source)</a></li>
</ol>
]]></content:encoded></item><item><title><![CDATA[A website audit is a starting point, not a verdict]]></title><description><![CDATA[We examined 209 retained website audit reports covering 165 distinct domains. We use the findings to frame maintenance questions, not to declare which…]]></description><link>https://resahost.hashnode.dev/a-website-audit-is-a-starting-point-not-a-verdict</link><guid isPermaLink="true">https://resahost.hashnode.dev/a-website-audit-is-a-starting-point-not-a-verdict</guid><category><![CDATA[Security]]></category><category><![CDATA[WordPress]]></category><category><![CDATA[email]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Olli Junes]]></dc:creator><pubDate>Wed, 11 Nov 2026 06:17:15 GMT</pubDate><content:encoded><![CDATA[<p>We examined 209 retained website audit reports covering 165 distinct domains. We use the findings to frame maintenance questions, not to declare which websites have been breached. A useful report separates an observation from its interpretation and gives the responsible person a next step.</p>
<p>We provide managed hosting and website maintenance at ResaHost, so we have a commercial interest in this subject. We also produced the research discussed here. Our sample came from our own analysis service, not a random survey of Finnish businesses. It cannot tell us how common these issues are across the country.</p>
<p>We used reports stored between 12 August and 10 September 2026 and selected the latest retained report for each domain. Stored time is not necessarily measurement time. Of those reports, 128 contained eligible structured diagnostics. We cannot establish the number of separate companies from these records. We did not independently recheck the original measurements through the published aggregate.</p>
<p>We kept a separate denominator for each check. We did not count missing diagnostics as missing protection, and we do not add overlapping groups or percentages together. We did not investigate actual break-ins, fraud losses or whether a specific weakness had been exploited. These findings do not establish a legal violation.</p>
<h2>We start with what the test actually observed</h2>
<p>We found no DMARC record at the queried DNS name for 51 of 85 eligible email domains. Another 22 used p=none. Together, 73 of those same 85 domains had no record found at that name or a policy requesting neither quarantine nor rejection. We keep that combined count within its original eligible group.</p>
<p>We do not interpret those observations as proof that a fraudulent invoice would reach someone’s inbox. Recipient filtering and a policy inherited from a parent domain can affect the result. Our statistical analysis did not verify those factors.</p>
<p>We would turn the finding into a practical question: which systems legitimately send email for this domain, and who checks their authentication? That includes billing software and marketing platforms, not just the everyday mailbox. We would review the legitimate senders before tightening the policy. The UK NCSC recommends introducing DMARC gradually, starting with a monitoring phase.</p>
<h2>We separate an old version from a confirmed vulnerability</h2>
<p>We observed at least one publicly detected plugin version older than its <a href="http://WordPress.org">WordPress.org</a> comparison version on 46 of 73 eligible websites. We identified versions from public files or resource information. We did not sign in to verify the installed plugin inventory. A public version string may not describe the installation accurately, so we would confirm it before deciding what to change.</p>
<p>We therefore treat this as a maintenance lead, not a vulnerability finding. A newer release may contain a security fix, a feature change or both. We would verify the installed version, review the release information and known issues, then plan the update with a backup and a functional check.</p>
<h2>We distinguish a missing header from browser behaviour</h2>
<p>We found HSTS absent from 84 of 127 saved HTTP responses eligible for this check. Those records had saved headers and an HTTP status from 200 to 399. We describe the response that was recorded, not every connection a visitor might make or every way a browser might enforce HTTPS.</p>
<p>We would not turn that count into a claim that 84 websites left their visitors unprotected. A previously stored HSTS policy, a parent-domain policy covering subdomains or a preload entry can affect the browser’s behaviour. We would check the actual hostname and applicable policies before choosing a change.</p>
<p>We would also review subdomains before extending a policy to them. A setting that enforces HTTPS needs to match the services people actually use. We would verify the intended behaviour rather than adding a header simply to improve a report’s appearance.</p>
<h2>We turn the report into an owner and a next action</h2>
<p>We would record each observation in a short work list: what we saw, what still needs verification, who owns the check and how we will confirm the result. For email, that might mean reviewing senders and authentication reports. For WordPress, it might mean verifying plugin versions and testing an update.</p>
<p>We would also record uncertainty. A missing result is not automatically a missing control. A clean-looking page is not evidence that its underlying software is maintained. Neither a red indicator nor a green one should replace a discussion with the responsible administrator.</p>
<p>We published the full counts and methodology in our research article, now available in English and linked below. The Finnish version describes the same study, not a second dataset. We use these observations as a technical starting point, not a penetration test, a legal compliance assessment or a promise that a website is safe.</p>
<h2>Sources</h2>
<ol>
<li><a href="https://resahost.net/en/blog/website-audit-study-2026/">Our research: counts, methodology and limitations · English · commercial source</a></li>
<li><a href="https://resahost.net/blogit/audit-tutkimus-2026/tilasto.json">Published aggregate counts and calculation notes · Finnish</a></li>
<li><a href="https://www.ncsc.gov.uk/collection/email-security-and-anti-spoofing/implement-a-dmarc-policy-of-none">UK NCSC: implement a DMARC policy of none</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security">MDN: Strict-Transport-Security</a></li>
</ol>
]]></content:encoded></item></channel></rss>