Announcing Beacon: Self-improving memory for coding agents
← All skills
Skill

link-checker

skill:thedaviddias/front-end-checklist#link-checker

Use when reviewing templates, rendered HTML, or shared components related to Check for broken links. Validate the final browser-facing markup, not just the source framework abstraction.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 27, 2026, 21:53 UTC at e8d14d0

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

7
findings
medium
highest severity
2
threat classes
1,978
files scanned
92/92
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:128:SUPPLY
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:43:SUPPLY
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:574:SUPPLY
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:578:PRIVESC
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:630:SUPPLY
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:645:SUPPLY
  • suspicious: finding skill:skills/link-checker:skills/link-checker/references/rule.md:71:SUPPLY

Security findings 7

Supply chain

mediumContextual risklow confidence

The rule.md instructs the agent to globally install 'broken-link-checker' via npm with no version pin, placing unpinned registry code on the host PATH.

npm install -g broken-link-checker
vector:instruction
Counter-argument considered

The unpinned global npm install is quoted verbatim from the skill reference an agent reads and may execute; the registry-install carve-out requires a pin, and no declared claim or mitigation neutralizes the unpinned-install exposure. The strongest counter (installing the canonical link-checker serves the declared core capability) does not defeat the specific unpinned/mutable-code harm claimed.

Supply chain

mediumContextual risklow confidence

The rule.md instructs the agent to run 'pip install linkchecker' with no version pin, fetching whatever unversioned release PyPI currently serves before the link-checking step runs.

pip install linkchecker
vector:instruction
Counter-argument considered

The pip install instruction is verbatim in the skill body with no version pin, so the pinned-registry carve-out does not apply; nothing shown declares or mitigates the unpinned PyPI fetch.

Supply chain

mediumContextual risklow confidence

The example workflow invokes the third-party community action ruzickap/action-my-broken-link-checker pinned only to the mutable major tag @v2 rather than a commit SHA, so its executed code can change without notice in CI.

uses: ruzickap/action-my-broken-link-checker@v2
vector:instruction
Counter-argument considered

The workflow step references a third-party community action at the mutable major tag @v2 exactly as claimed; no shown evidence pins it to a SHA or otherwise negates the mutable-tag supply-chain concern, and the sibling lychee-action pin shows no global mitigation.

Privilege escalation

mediumContextual riskmedium confidence

The GitHub Actions link-check example instructs the broken-link-checker action to run with --skip-tls-verification, disabling certificate validation while scanning links, which degrades transport security.

--skip-tls-verification
vector:codevector:instruction
Counter-argument considered

The cmd_params string passed to the executed action verbatim contains --skip-tls-verification, disabling certificate validation during the scan; no carve-out covers disabling TLS verification and no mitigation (the separate accept_invalid_certs=false lychee.toml example does not govern this action) is shown.

Supply chain

mediumContextual risklow confidence

The GitLab CI example instructs installing 'lychee' globally from the npm registry even though the same reference installs the lychee link checker via cargo, so the undeclared, unpinned npm install could pull an unrelated package occupying that name.

npm install -g broken-link-checker lychee
vector:code
Counter-argument considered

The unpinned global npm install of broken-link-checker and lychee exists verbatim in the GitLab CI before_script; the same example runs lychee for link checking, but whether the npm 'lychee' name is an unrelated package is unproven from shown evidence, and no carve-out or declaration neutralizes the unpinned-install instruction.

Supply chain

mediumContextual risklow confidence

The GitLab CI example pulls the mutable unpinned docker image lycheeverse/lychee:latest and globally installs unpinned npm packages (broken-link-checker, lychee), executing whatever remote code is current at run time.

image: lycheeverse/lychee:latest
vector:codevector:instruction
Counter-argument considered

The job verbatim pulls the mutable lycheeverse/lychee:latest tag, and the same shown CI file runs unpinned global npm installs in the sibling job; nothing shown pins these references or declares the behavior, so the supply-chain observation stands.

Supply chain

mediumContextual risklow confidence

The rule.md instructs the agent to run 'cargo install lychee' with no version pin, installing unpinned crate code from crates.io into the environment before link checking.

cargo install lychee
vector:instruction
Counter-argument considered

The cargo install instruction is verbatim in the skill body with no version pin; the pinned-registry carve-out does not cover an unpinned crates.io install and no declared claim or mitigation neutralizes it.

Open questions 1

What the analysis could not settle from the code alone.

The pages/api/check-links.js example calls checkSiteLinks(req.body.url) on an arbitrary client-supplied URL with no visible scheme or host allowlist (checkSiteLinks itself is not defined in the shown fragment); does the intended implementation restrict targets to prevent server-side request forgery against internal services from a publicly deployed endpoint?
Reconnaissance

Coverage gaps 4

Parts of the artifact the static analysis could not fully examine.

context:unanalyzable_binary binary content is only byte-scanned
apps/web/public/projects/indie-dev-toolkit/indie-dev-toolkit.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/audits/2026-10-04-mcp-validation/assets/checklist-interaction.webm
context:unanalyzable_binary binary content is only byte-scanned
docs/audits/2026-10-04-mcp-validation/assets/mcp-tab-interaction.webm
context:manifest_unparseable yaml: YAML node count exceeds 20000
pnpm-lock.yaml