← Back to blog
Attack SurfaceInternal ToolsAI SecuritySelf-Hosted

Your Internal Tools Are Not Internal

by Hennadii Ahanesian·4 Sept 2026·8 min read

Every company runs two estates. The first is the product customers see: the marketing site, the app, the API. Teams know it is public, so they harden it. The second estate is everything the team uses to run the first one: dashboards, admin panels, observability stacks, dev environments, support consoles. Teams think of it as private.

The internet disagrees.

In our latest batch of assessments, 30 out of 101 applications we attacked, almost a third, exposed at least one internal tool to the public internet. Not the product. The machinery behind the product. Last post we covered endpoints that never ask who you are. This post is about entire applications that were never supposed to answer you at all.

What exposed internal tooling is

An exposed internal tool is software built for employees only that answers requests from the public internet. Monitoring dashboards, BI tools, admin panels, LLM observability, development environments, remote access portals. Each one is installed to help the team operate the product, and each one quietly becomes part of the attack surface the moment it resolves a public hostname. MITRE tracks the pattern as CWE-668, Exposure of Resource to Wrong Sphere.

The pattern shows up in every stack. A Grafana dashboard for monitoring. A Metabase instance for BI. A Retool panel for operations. A Langfuse deployment for LLM observability. A Coder instance for development environments. An OpenVPN portal for remote access. Each is a real application with its own login, its own CVEs, and its own idea of what "internal" means.

What an attacker finds inside

No exploit required. Most of these tools answer with a login page, a version number, or an open registration form. Real findings from recent engagements, anonymized:

  • An LLM observability instance at a company handling medical data answered anyone on the internet, and let strangers register their own accounts. A free signup, and you were reading the traces: production prompts, completions, tool calls, and the customer data flowing through them.
  • An operations panel built in Retool sat on a bare cloud VM: no WAF, no SSO, just a username and password form protecting a tool wired into internal workflows.
  • An analytics database answered unauthenticated queries on a direct origin IP, bypassing the company's Cloudflare entirely, and served its query UI and server telemetry to anyone who connected.
  • An internal wiki at a hardware company was anonymously readable. Product architecture and commercial strategy, no account needed.
  • An AI company had committed its production agent-trace dataset, thousands of real user sessions with outputs and tool calls, to a public repository.
  • BI dashboards at several companies answered with exact version numbers. That is not a compromise by itself, but it tells the attacker precisely which public CVEs to try.
  • A monitoring stack's metrics endpoint answered without authentication, disclosing internal topology: datasource names, instance counts, usernames.

Sometimes the exposure is the whole tool. Sometimes it is one unauthenticated route on an otherwise gated tool. Both start the same way:

curl https://grafana.example.com/api/health
{"commit":"e5f6a7b","version":"11.2.1"}

One request, and the attacker knows what you run, which version, and which exploits apply.

Worth saying: in most of these companies, the product itself held up under direct testing. The login flows and tenant isolation did their jobs. The exposure was the machinery around the product, not the product.

Why this is a real problem

Internal tools are not less sensitive than the product. They are usually more sensitive, because they exist to operate the product.

Observability platforms hold production prompts, responses, and API keys. Admin panels manage users and reset passwords. Operations panels touch billing and customer records. Development environments contain source code and the credentials that were convenient at the time. A metrics endpoint looks harmless until it maps your entire internal architecture for someone.

There is a chaining problem too. An exposed tool is rarely the end of an attack path. It is step one: the version number selects the CVE, the open registration hands over an account, the dashboard reveals the next internal hostname. In our reports, the path from "public login page" to "meaningful access" is often shorter than the team expects. The companies with the most to lose feel this hardest: a clinic's traces contain patient conversations, a fintech's ops panel touches money movement, a chip designer's wiki is its product roadmap.

Why internal tools end up public

The reason is not carelessness. It is how these tools get adopted.

They arrive outside the release process. Someone spins up Grafana to debug an outage, a developer self-hosts an LLM observability stack to evaluate it, a contractor deploys an admin panel for a launch. There is no security review because there is no release. The tool solves the problem, becomes load-bearing, and nobody comes back to put it behind the identity layer.

Vendor defaults make it worse. Many self-hosted tools listen on all interfaces out of the box, enable registration on first run, and treat a login page as sufficient security. A password form on the public internet is not a boundary. It is a speed bump: credentials get phished and reused, and the software behind the form has its own CVE history.

Finally, nobody owns the inventory. The product estate has an owner. The second estate grew organically, and in most companies we assess, no single person can list it.

How to secure internal tools

The fix is well understood. Some of the companies we assess already do it, and their estates look completely different from the outside: uniform 401s, everything behind an identity-aware proxy, nothing answering anonymous requests. Four steps get you there.

Step one. Build the inventory. You cannot gate what you cannot list. Query Certificate Transparency logs for your domains, enumerate subdomains, scan your own ranges, and ask every team what they have deployed. Do it from the outside, the way an attacker does. The list will surprise you. It surprises almost everyone.

Step two. Put identity in front of everything. An identity-aware proxy, Cloudflare Access, or SSO gate in front of each internal tool, so the tool is unreachable until the caller authenticates as an employee. The tool's own login stops being the boundary. This one change does the most, and it is why well-run estates return the same 401 for every internal hostname we probe.

Step three. Take the tools off the public internet where you can. Bind them to private addresses, reachable over VPN or a mesh network. A tool that does not resolve publicly does not need to survive the internet. For anything that must stay public: disable open registration, patch on a schedule, and strip version banners.

Step four. Re-run the inventory after every change. New tools appear the same way the old ones did: quickly, for a good reason, without a ticket. The inventory from last quarter describes last quarter. This is the same lesson as every finding class we report: the test has to return when the software changes, because the software always changes.

Frequently asked questions

What counts as an internal tool?

Any software deployed for employees rather than customers: monitoring dashboards, BI platforms, admin panels, observability stacks, development environments, remote access portals, and support consoles. If your customers were never meant to see it, it belongs behind your identity layer.

Is a login page enough to protect an internal tool?

No. A password form on the public internet can be phished, brute-forced, or bypassed with a credential from an unrelated breach. The software behind the form also has its own CVEs, and a public version banner tells an attacker exactly which ones to try. Put an identity-aware proxy in front, or take the tool off the public internet.

What is LLM observability, and why is it sensitive?

LLM observability tools record every prompt, completion, and tool call your AI features make, so engineers can debug and evaluate them. That record contains customer data, internal prompts, and often API keys. An exposed instance is a live feed of everything your AI does, readable by whoever finds it.

How do I find my company's exposed internal tools?

Start with Certificate Transparency logs: search crt.sh for your domains and look for hostnames like grafana, admin, vpn, metrics, retool, or langfuse. Enumerate subdomains, check what resolves publicly, and compare the result against what your teams know they deployed. The difference is your exposure.

What is an identity-aware proxy?

A gateway that sits in front of internal applications and authenticates users against your company identity provider before any request reaches the tool. The application never sees anonymous traffic, so its own login and CVEs stop mattering to the outside world.

The point

We keep finding internal tools in the open because they were never part of the product's security story. They just appeared, one urgent deploy at a time, until the second estate was bigger than the first.

If you want to know where you stand, it takes a few minutes. Search crt.sh for your domain and read the hostname list. Grafana. Admin. Metrics. VPN. Langfuse. Retool. If any of them resolve and answer, that is the finding.

And if you would rather have someone map the whole second estate for you, and keep mapping it as it grows, that is exactly what we do.

Related reading: The Finding We Report More Than Any Other, the endpoint-level version of this problem, in 45 percent of the applications we attack. And The Email Finding We Keep Reporting, the DNS record that lets anyone send email as your company.