7f353b73 reworded ValidateDownloadURL's rejection from "下载地址必须是
受信任域名上的 HTTPS URL" to "下载地址必须是合法的 HTTPS URL" when
the IP-literal refusal was removed, but missed that the string is a
test contract: paramAliasExpectedCaptureBoundaryError treats the URL
validation stop as the expected capture boundary for drive +download
and +version-download fixture runs. The stale assertion failed those
subtests and the alias-count invariant (58 active, want 64), which
also failed the Coverage jobs running the same tests.
- update the boundary matcher to the new message
Confirmed with the product team that the official GUI client applies no
client-side SSRF interception to downloads, so the IP-literal refusal
was the last remaining client-side interception beyond transport
hygiene. Dedicated deployments make every host dimension (domain,
port, network location) unenumerable, and an IP-literal host is just
another network location.
- ValidateDownloadURL accepts any HTTPS host, IP literals included;
HTTPS scheme, userinfo refusal, and per-hop redirect re-validation
stay as the transport baseline
- this retires the third and last interception layer after the host
allowlist removal and the dial-time public-IP refusal (be52ca5d)
- upload targets stay unaffected: trustedUploadHost keeps rejecting
non-DingTalk/OSS hosts, so local file bytes cannot be PUT to an IP
- regressions: IP-literal URLs pass validation on the shared and chat
download paths; userinfo and plain-HTTP URLs stay rejected
Customer round-2 testing on the dedicated deployment (Jingbo) found the
storage domain resolving to a customer-intranet address (10.254.87.52),
which the dial-time public-IP policy refused: dedicated storage can be
deployed inside the customer network, so its resolved network location
is as unenumerable as its domain and port.
- delete the public-IP policy, the IANA special-purpose denylist, and
the NAT64 embedded-IPv4 re-validation introduced in 617b780a;
downloads now dial the service-issued host directly, still ignoring
environment proxies
- align with the official GUI client, which applies no client-side
SSRF interception to downloads: no command accepts a user-supplied
download URL, TLS hostname verification pins the connection to the
requested domain, redirects are re-validated per hop, and credential
headers are stripped once a redirect leaves the original origin
- uploads keep the static DingTalk/OSS default-port trust boundary
- simplify SetSecureDownloadDialTargetForTest to a single dial seam
Review finding on 1ba6bec8: relaxing ValidateDownloadURL to accept
non-default HTTPS ports also widened upload targets, because the upload
validator reuses it and only re-imposed the host trust set.
- validateUploadURL now also rejects non-default ports, making the
upload trust boundary identical to the pre-removal policy (trusted
DingTalk/OSS hosts on the default port)
- DingTalk/OSS upload endpoints always serve HTTPS on 443, so unlike
dedicated-deployment downloads there is no legitimate non-default
port scenario for uploads
- regressions: trusted-host:8443 upload targets are rejected for both
public-cloud and dedicated hosts
Customer testing on a dedicated deployment found real download URLs served
on a non-default HTTPS port (e.g. 8443) by the dedicated storage domain,
which the inherited default-port-only rule rejected.
- drop the 443-only restriction from ValidateDownloadURL; HTTPS scheme,
domain-only hosts (no IP literals), and no-userinfo rules stay
- the port is not a trust signal: SSRF protection lives at dial time in
the port-agnostic public-IP policy
- redirect hygiene unchanged: a port change is a cross-origin redirect
and still strips service credential headers (new regression guard)
- dedicated-deployment regression: same host on a non-default port is
accepted by URL validation and downloads successfully
- re-validate NAT64 well-known prefix answers (64:ff9b::/96) against the
embedded IPv4 address: DNS64-synthesized answers for public IPv4-only
hosts keep working while embedded loopback/private/special addresses
are refused before dialing
- refuse NAT64 local-use (64:ff9b:1::/48) outright: the IPv4 embedding
is deployment-specific and cannot be extracted reliably
- refuse Teredo (2001::/32) outright as part of the transition-mechanism
audit; 6to4 (2002::/16) was already refused and IPv4-mapped addresses
are normalized via Unmap before checks
- add dial-layer regression: a hostile AAAA answer embedding 127.0.0.1
fails before any dial attempt
- restore the pre-existing DingTalk/OSS trusted host requirement for
upload target URLs via a dedicated upload validator
- extend the dial-time non-public IP denylist with IANA special-purpose
ranges (0.0.0.0/8, 192.88.99.0/24, 100::/64, 2002::/16, 3fff::/20,
5f00::/16)
- document that download credential headers follow the service-issued
URL as-is on the first hop (same authenticated response issues both);
cross-host redirects keep stripping them
Reject report submissions without visible recipients at the CLI layer
(Cobra required flag + fail-closed on blank values) while keeping the
openAPI create_report parameter optional (bug 85724185).
- drop shareScope.required=["linkShare"] from the result schema: the
production response omits linkShare unless link sharing is configured;
document the conditional presence in the schema description, tests,
and both skill references
- spell out policy value tiers in skill docs (READER_AND_ABOVE /
DOWNLOADER_AND_ABOVE / EDITOR_AND_ABOVE / MANAGER_AND_ABOVE) so the
shorthand no longer diverges from the schema enums
Sync the get-setting schema descriptions and skill references with the
server-side finalized policy texts: policy code semantics now quote the
product permission-settings page labels (e.g. external_share=add
external collaborators, watermark=show watermark, node_spread_scope=
download and distribution scope), the node_spread_scope binary values
read ALL_NODES=all documents and PREVIEWABLE_ONLY=previewable documents
only (online documents, images, videos, etc.), and the contract test
value-semantic fragments follow the same wording. Both mono and multi
drive references also list per-policy name/description examples
(external_share, node_spread with NOBODY, node_move_forbidden) quoted
verbatim from the server i18n single source.
Sync the get_permission_setting result contract with the finalized
server-side enums: switch values ON/OFF become ENABLED/DISABLED and the
node_spread_scope binary ALL_CONTENT becomes ALL_NODES (restriction
applies to all nodes vs previewable-only nodes), while policy codes,
threshold domains, permissionMode and shareScope stay unchanged.
Policies now carry per-entry name and description fields (Chinese label
and value semantics from the server i18n single source) as deterministic
required members, mirrored in the contract test assertions and both mono
and multi drive skill quick references.
Declare the drive.permission get_setting ResultSpec data schema from the
server-side output metadata so the field-level contract (permissionMode,
shareScope, policy codes and their typed value domains, inherited /
allowedValues semantics) is reviewed code guarded by contract tests, and
add field-quick-reference rows for the get-setting section in both mono
and multi drive skill references.