Skip to content

Add ContrastAPI security intelligence plugin#2254

Merged
crazywoola merged 4 commits intolanggenius:mainfrom
UPinar:add-contrastapi
Apr 13, 2026
Merged

Add ContrastAPI security intelligence plugin#2254
crazywoola merged 4 commits intolanggenius:mainfrom
UPinar:add-contrastapi

Conversation

@UPinar
Copy link
Copy Markdown
Contributor

@UPinar UPinar commented Apr 7, 2026

What

Adds ContrastAPI — a free security intelligence plugin with 29 tools.

Tools (29)

Domain Intelligence (10): whois_lookup, dns_lookup, ssl_check, subdomain_enum, domain_report, audit_domain (orchestrated full audit), tech_fingerprint, scan_headers, wayback_lookup, threat_intel

CVE Intelligence (4): cve_lookup, cve_search, exploit_lookup, bulk_cve_lookup (up to 50 CVEs in one call)

Threat Intelligence / IOC (5): ioc_lookup, bulk_ioc_lookup (up to 50 indicators in one call), hash_lookup, phishing_check, threat_report (orchestrated IP threat report — Shodan + AbuseIPDB + ASN)

Network / OSINT (6): ip_lookup, asn_lookup, email_mx, email_disposable, phone_lookup, username_lookup

Code Security (3): check_secrets, check_injection, check_headers

Authentication (1): password_check — HIBP-style breach check. The plain-text password is SHA-1 hashed inside the plugin process before any network call. The raw password never leaves the user's host.

Details

  • Free API — no API key required, 100 requests/hour rate limit per IP (1,000/hr Pro)
  • REST API: https://api.contrastcyber.com
  • GitHub: https://github.com/UPinar/contrastapi
  • Also available as: MCP server (29 tools), VS Code extension, npm SDK
  • Listed on: Official MCP Registry (DNS-verified), Smithery (98/100), awesome-mcp-servers, mcp.so, mcpservers.org

Privacy & Data Handling

ContrastAPI does not store the values you submit (domains, IPs, CVE IDs, hashes, code, etc.). Only the endpoint category and a salted HMAC hash of the caller's IP are logged for rate limiting. Verify in real time:

curl https://api.contrastcyber.com/v1/privacy/my-data

This transparency endpoint returns every row the database has about the caller, with deep links back to the source code that enforces the privacy guarantees.

Full data-handling details, including the trust model for password_check, are in DATA_HANDLING.md inside the plugin package (added in response to review feedback).

Plugin Privacy Policy

Full policy: https://contrastcyber.com/privacy

@xtaq
Copy link
Copy Markdown

xtaq commented Apr 8, 2026

This is one of the clearer security-intel submissions I’ve seen because it already exposes the tool surface, free-tier/rate limit, repo/API links, and a concrete privacy stance.

I’m trying to understand what single proof artifact actually closes the trust gap for a buyer deciding whether to wire a security plugin into a real workflow.

If a marketplace listing could only add one more artifact, which would matter most to your users?

  1. Data-handling boundary — what is / isn’t logged, retained, or shared
  2. Update cadence + source history — how often the intelligence is refreshed and from where
  3. Quality proof — example evals, precision/false-positive evidence, known limitations
  4. Isolation options — self-hosting / private deployment / network boundary

My guess for security workflows is data-handling boundary first, quality proof second, but I’d love to hear what serious users ask about first in practice.

@UPinar
Copy link
Copy Markdown
Contributor Author

UPinar commented Apr 8, 2026

Thanks for the thoughtful review.

To answer directly — data-handling boundary is what users ask about first in practice. Here's ours:

  • No query logging — submitted domains/IPs/code are not stored or retained
  • No API key required for free tier — no identity binding
  • All sources are public (NVD, abuse.ch, HIBP via k-anonymity) — no opaque proprietary feeds
  • CVE/EPSS/KEV syncs every 2 hours, threat feeds are near-realtime

For the plugin specifically: it makes read-only GET/POST calls to api.contrastcyber.com and passes results back to the Dify workflow — nothing is cached or stored on our side.

Self-hosted deployment (local MCP server + local API) is on the roadmap for enterprise users who need full network isolation.

Happy to add a DATA_HANDLING.md to the plugin if that helps the review.

…ts, add DATA_HANDLING.md

Adds 4 new tools: audit_domain, threat_report, bulk_cve_lookup, bulk_ioc_lookup.

Fixes 11 tools that called the wrong API path/method/body and would have
404'd or 422'd in production: domain_report, email_mx, email_disposable,
exploit_lookup, wayback_lookup, phishing_check, scan_headers, check_secrets,
check_injection, check_headers, cve_search.

password_check: SHA-1 hashes the password locally before any network call,
so the plain-text password no longer leaves the user's host. Matches the
HIBP k-anonymity threat model.

Updates manifest/provider/README/version to 0.2.0, rate limit 60→100/hr,
tool count 25→29.

Adds DATA_HANDLING.md responding to the data-handling boundary review,
including a verifiable transparency endpoint reference
(GET https://api.contrastcyber.com/v1/privacy/my-data).
@UPinar
Copy link
Copy Markdown
Contributor Author

UPinar commented Apr 11, 2026

@xtaq Following up on your data-handling boundary question — thanks again, it pushed us to write this down properly instead of leaving it implicit.

The plugin package now ships with a DATA_HANDLING.md that covers the trust boundary, the exact fields the upstream API stores, what is deliberately not stored, and the specific threat model for the password_check tool (HIBP-style with one extra trust hop — documented honestly rather than papered over).

The headline answer to "what does the buyer need?": you can now verify the privacy claims in real time rather than trust them. We added a transparency endpoint:

curl https://api.contrastcyber.com/v1/privacy/my-data

It returns every row the database has about the caller — hashed IP, last 24h of endpoint activity (aggregated by category, no query parameters), rate-limit window state, and a not_stored list with deep links to the source lines that enforce each guarantee. So instead of "trust the policy," reviewers can audit the code.

Other things in this push:

  • 25 → 29 tools (added orchestrated audit_domain, threat_report, plus bulk_cve_lookup and bulk_ioc_lookup)
  • Fixed 11 broken tools that called the wrong API path/method/body in the original submission — these would have 404'd in production. Caught during a re-review pass before merge
  • password_check privacy fix — now SHA-1 hashes the password locally before any network call. The plain-text password no longer leaves the user's host. Old behavior was sending raw password in a POST body, which would have been a real bug if a user had hit it
  • Rate limit corrected to 100 req/hr (the original PR body said 60, that was outdated)
  • Self-hosted / private deployment path documented for users who can't trust any intermediary — point the plugin's API_BASE at your own ContrastAPI host (the entire upstream is MIT-licensed at https://github.com/UPinar/contrastapi)

Plugin version bumped to 0.2.0. Happy to keep iterating if there's anything in DATA_HANDLING.md that's unclear or that doesn't match the bar Dify expects for security plugins.

Copy link
Copy Markdown
Member

@crazywoola crazywoola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Request Changes

Decision: Request changes

Review Status

Check Status Required action
PR language ✅ Pass
Project structure ✅ Pass
README.md ✅ Pass
PRIVACY.md ❌ Fail Add a non-empty top-level PRIVACY.md file. Detail: PRIVACY.md not found or empty. Please include a non-empty PRIVACY.md file.
Manifest author ✅ Pass
Icon validation ✅ Pass
Version check ✅ Pass
README language ✅ Pass
dify_plugin version ❌ Fail Pin or bump dify_plugin to >= 0.5.0 in requirements.txt or pyproject.toml. Detail: Could not find a pinned dify_plugin dependency in requirements.txt or pyproject.toml.

Next steps

  • PRIVACY.md: Add a non-empty top-level PRIVACY.md file.
  • dify_plugin version: Pin or bump dify_plugin to >= 0.5.0 in requirements.txt or pyproject.toml.

Please address the issues above and push an updated submission.

- Add top-level PRIVACY.md (data handling summary, transparency endpoint, privacy controls)
- Fix dify_plugin dependency: hyphen → underscore for checker compatibility (>=0.5.1)
@UPinar
Copy link
Copy Markdown
Contributor Author

UPinar commented Apr 12, 2026

@crazywoola Thanks for the review! Both issues are fixed:

PRIVACY.md — Added a top-level PRIVACY.md covering: what the plugin and upstream API store (and don't store), the password_check trust boundary, transparency endpoint (/v1/privacy/my-data), privacy controls (DNT/GPC, log rotation, IP hashing), and self-hosted deployment option. Full details remain in DATA_HANDLING.md.

dify_plugin version — Fixed dependency name to dify_plugin>=0.5.1 in pyproject.toml.

Ready for re-review.

Replace unsupported manifest tags (security, threat-intelligence, osint)
with Dify allowlist values: search, agent, utilities. CI pre-check plugin
validation enforces a fixed tag enum; the previous values caused
PluginDeclaration.Tags[*] validation failures.
@UPinar
Copy link
Copy Markdown
Contributor Author

UPinar commented Apr 13, 2026

Pushed a fix for the plugin_tag validation errors in commit 80324c4.

Root cause: The previous manifest used security, threat-intelligence, and osint tags, which are not in Dify's plugin_tag enum allowlist (the daemon's manifest_entities package only accepts: search, image, videos, weather, finance, design, travel, social, news, medical, productivity, education, business, entertainment, utilities, agent, other).

Fix: Replaced with search, agent, utilities — closest semantic match for a security-intelligence API with 29 MCP tools covering CVE lookup, domain recon, OSINT, etc.

The workflow is currently in action_required state waiting on a maintainer approval. @crazywoola could you kindly approve the workflow run when you have a moment? Thanks!

Copy link
Copy Markdown
Member

@crazywoola crazywoola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@crazywoola crazywoola merged commit fd4973f into langgenius:main Apr 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants