Install
$ agentstack add skill-unboundcompute-security-agent-skills-finding-fail-open-flaws ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Finding fail-open flaws: prove the gate denies by default
A control fails open when its error, empty, or default path grants access instead of refusing it. The check looks present and even passes its happy-path tests, but on the branch that runs when something goes wrong, when a lookup errors, a list is empty, a value is missing, an exception is caught, it lets the request through. These flaws hide in the paths tests rarely cover, and they turn any upstream failure into an authorization bypass.
When to use
- You are reviewing authentication, authorization, or any access gate.
- A check "passes" and you have not confirmed why, or what it does on failure.
- A control depends on an external service, a list, or an input that could be absent.
Scope check
Test gates in code you own or are authorized to test, inducing failures against your own environment. If you can't name the authorization, stop.
The loop
- Enumerate the gates and their failure branches. For each authentication or
authorization check in scope, find not just the allow/deny decision but what happens when the check cannot be completed: the lookup throws, the policy service is unreachable, the input is null or unrecognized, the list is empty. Every gate has a failure branch; find it.
- Determine the default. For each gate, is the default deny (access requires an
explicit, successful allow) or allow (access proceeds unless something explicitly denies)? Default-allow is the root fail-open shape: anything that prevents the deny from firing grants access. State the default for every gate.
- Test the error path. Force the check to fail (an unreachable dependency, a
malformed input, an exception) and observe the outcome. If a caught exception, a timeout, or an error returns or falls through to allow, the gate fails open. A try/catch around a permission check that continues in the catch is the classic instance.
- Test the empty and wildcard cases. Does an empty allowlist match nothing (safe)
or everything (fail-open)? Does a wildcard, a missing filter, or an unset scope collapse to allow-all? Check what the control does with no rules and with a catch-all rule; both are common allow-everything defaults.
- Test the missing-input case. When an identifier, role, or token is absent or
unrecognized, does the gate treat it as unauthorized, or does a missing value skip the check or select a permissive default (an unknown role mapped to allow, a null user treated as trusted)? Absent input must deny.
- Confirm and record. A fail-open flaw is confirmed by driving the gate down its
failure path and observing access granted; name the branch and the trigger. Kill the lead if every failure, empty, and missing case denies. Record with the exact failing branch and the fix: default deny, fail closed on error, treat empty as match-nothing, and reject missing input.
Where controls fail open
- The happy path lies. A gate that allows correctly can still allow on error; the
tests rarely exercise the error branch.
- Empty is ambiguous. An empty allowlist is safe only if empty means deny. Confirm
which it means.
- Catch-and-continue is allow-on-error. Swallowing a denial and proceeding is the
most common fail-open pattern.
- Missing is not trusted. An absent role or token is unauthorized, not
default-privileged.
Worked example (a confirm and a kill)
> Confirm. An authorization middleware calls a policy service and wraps it in a > try/catch; on any exception it logs and continues to the handler, reasoning that the > service is usually up. Making the policy service time out causes every request to be > authorized. Confirmed fail-open on error, critical, remediation = deny on any > policy-check failure, never continue in the catch. > > Kill. A gate requires an explicit allow decision, denies on any exception or > timeout, treats an empty allowlist as matching nothing, rejects requests with a > missing or unrecognized role, and has no catch-all allow. Every forced failure and > empty case results in denial. Killed, kill_reason = "default deny, fail closed > on error, empty means match-nothing, missing input rejected; no branch grants on > failure."
Rationalizations to reject
- "The check is right there." → Presence is not enough. Read its error, empty, and
missing branches.
- "The dependency is reliable." → Reliability is not a control. If its failure grants
access, an attacker will cause the failure.
- "An empty list means nothing is configured yet." → Then it must match nothing. If
empty means allow-all, it is a bypass.
- "We catch the exception so it doesn't crash." → Not crashing by allowing is worse
than crashing. Fail closed.
Executing this in practice
You need to see each gate's failure, empty, and missing branches, and to force those conditions (kill a dependency, send malformed or absent input) while observing whether access is granted. A call graph that shows the guard and its siblings helps you find every gate and compare their defaults; forcing the failure path is the confirmation.
Related
auditing-guard-gaps- the unguarded-peer analysis; this is its failure-path
complement.
auditing-declarative-authorization- fail-open defaults expressed in policy and
configuration.
- [FINDING-SCHEMA.md](../../FINDING-SCHEMA.md) - source = the induced failure or
empty/missing input, sink = the access the gate grants on that branch.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: UnboundCompute
- Source: UnboundCompute/security-agent-skills
- License: MIT
- Homepage: https://security.unboundcompute.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.