In a DeepSeek Harness (DSH) environment, agents frequently need to make outbound requests. If these URLs are not controlled, there is a risk of server-side request forgery (SSRF). dsh-ssrf-guard is a DSH function plugin that implements a “deny-all” (fail-closed) security policy by checking the host and scheme allowlists for outbound URLs before the request is opened.

Plugin Scope

This plugin is maintained by jwilson411 and is released under the MIT license. It does not intercept traffic, perform DNS resolution, or act as a reverse proxy or web application firewall (WAF). It decides whether to allow access solely through URL parsing and string matching. The default allowlist configuration is empty, meaning that if no allowlist is configured, all requests are denied.

Installation and Enablement

Install the plugin in the DSH web profile:

dsh plugin --profile web add github:jwilson411/dsh-ssrf-guard

The package manifest declares dsh.bundle.patch. After installation, it is appended to the dsh.profile.bundles list in the profile manifest and causes its cordis.patch.yml to become a configuration layer.

Core Features

  1. Allowlist mechanism: Only hosts explicitly specified in allowHosts (supporting exact and prefix matching) and schemes specified in allowSchemes are allowed.
  2. Precheck: Checks are performed before the request is opened; URLs that fail the check do not leave the current process.
  3. API exposure:
    • Provides an ssrf_check tool for use by models or code.
    • Exports the assertUrlAllowed and SsrfDeniedError library APIs for developers to perform explicit checks in code.
  4. Default blocking: Built-in blocking is provided for loopback addresses (localhost, 127.0.0.1, ::1), link-local addresses (169.254.x.x, fe80::), URLs containing credentials, and similar cases.

Configuration and Usage

1. Configure the Allowlist

Configure the allowed hosts and schemes in cordis.patch.yml. Note that an id-targeted patch replaces the entire configuration line, so all reserved fields must be redeclared.

- id: ssrf-guard
  config:
    allowHosts:
      - .example.com    # 允许所有 *.example.com 子域
      - api.vendor.test # 精确匹配 api.vendor.test
    allowSchemes: [https]

If not specified in the configuration, the environment variables DSH_SSRF_ALLOW_HOSTS and DSH_SSRF_ALLOW_SCHEMES can serve as fallbacks, and they take effect only when the configuration line completely omits the corresponding key.

2. Validate URLs in Code

Use the assertUrlAllowed function to perform validation. If the URL is not allowed, a SsrfDeniedError is thrown.

import { assertUrlAllowed, SsrfDeniedError } from 'dsh-ssrf-guard'

const config = { allowHosts: ['.example.com'], allowSchemes: ['https'] }

try {
  const { host, scheme } = assertUrlAllowed(candidate, config)
  // 校验通过后,再执行 fetch 等操作
  await fetch(candidate)
} catch (error) {
  if (error instanceof SsrfDeniedError) {
    // 处理拒绝逻辑
    return
  }
  throw error
}

If you prefer not to use exceptions, you can use the non-throwing checkUrl function, which returns a result object.

3. Invoke the Tool

In DSH tool-call scenarios, you can directly invoke the ssrf_check tool by passing a url parameter.

Usage Considerations

  • DNS rebinding protection: The plugin does not perform DNS resolution and only matches the hostname written in the URL. If DNS resolution results point to an internal address, the plugin will not block it as long as the hostname is in the allowlist.
  • Port mismatch: Ports are not included in the matching logic. For example, configuring example.com allows https://example.com:8443/.
  • Case insensitivity: Hostname matching is case-insensitive.
  • Version requirement: Node.js version >= 22.14.0 is required. The plugin was written and tested against @deepseek-ai/dsh-tools@0.1.1-rc.2; it is recommended to specify versions explicitly rather than relying on latest.
  • Runtime environment: The plugin runs with the permissions of the current DSH process; review the source code and license before installation.

Summary

dsh-ssrf-guard provides a lightweight SSRF mitigation mechanism at the DSH plugin level. It does not take over network traffic; instead, it requires developers to perform allowlist validation before making requests by using explicit library APIs or tool calls, making it suitable for scenarios that require fine-grained control over outbound URLs.