Skip to content

Document SVG denial in generated project upload defaults - #3378

Merged
pwizla merged 9 commits into
mainfrom
cms/document-svg-upload-security-policy
Aug 26, 2026
Merged

Document SVG denial in generated project upload defaults#3378
pwizla merged 9 commits into
mainfrom
cms/document-svg-upload-security-policy

Conversation

@pwizla

@pwizla pwizla commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

This PR updates documentation based on strapi/strapi#27360.

Adds a "SVG upload security" section to the Upload REST API page (cms/api/rest/upload.md) documenting:

  • That image/svg+xml is denied by default in projects generated with create-strapi-app, even though image/* is in allowedTypes
  • The rationale: SVG can contain browser-active content (scripts, event handlers)
  • That explicit deniedTypes entries take precedence over wildcards in allowedTypes
  • That this applies to new projects only — existing projects are not affected
  • How to allow SVG uploads if needed (with a security caveat)
  • A cross-link to the full security configuration reference in the Media Library docs

Generated automatically by the docs self-healing workflow.
Review before merging.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@pwizla pwizla added the auto-doc-healing Automatically generated documentation PR label Aug 21, 2026
@pwizla pwizla self-assigned this Aug 21, 2026
@strapi-cla

strapi-cla commented Aug 21, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ pwizla
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
documentation Ready Ready Preview Aug 26, 2026 10:13am

Request Review

@github-actions github-actions Bot added internal PRs created by the Strapi core team pr: updated content PRs updating existing documentation content source: CMS labels Aug 21, 2026
Comment thread docusaurus/docs/cms/api/rest/upload.md Outdated
@pwizla pwizla added this to the 7.1.0 milestone Aug 21, 2026
@pwizla
pwizla marked this pull request as ready for review August 21, 2026 12:39
@pwizla pwizla added the flag: merge pending release Waiting for the related product PR to be merged before merging this documentation PR label Aug 21, 2026
@pwizla pwizla removed the flag: merge pending release Waiting for the related product PR to be merged before merging this documentation PR label Aug 26, 2026
pwizla added a commit that referenced this pull request Aug 26, 2026
* Mention that you need to restart Strapi after toggling Media Lib beta

* Use Slack link syntax in the unflag notification

The message was built with Markdown links, so Slack rendered them literally as
[#3378](https://…). Slack needs <url|text>, and the GitHub step summary still
needs Markdown, so the two lists are now built separately. Titles are truncated
at 70 characters like auto-respond-issues does, and the values reach the Slack
step through the environment rather than shell interpolation.
The SVG deny policy is project configuration, not REST API surface, so it
belongs in the Media Library security section that already documents
allowedTypes and deniedTypes. Also adds the real generated defaults from the
create-strapi-app templates so readers can match them against their project.
pwizla added 3 commits August 26, 2026 12:05
The supported media types table listed SVG without a caveat, contradicting the Security section 380 lines away. A reader whose SVG upload failed would see SVG listed as supported and conclude it was a bug.
The Upload plugin validates on actual MIME type rather than declared extension, so "dangerous extensions" was inaccurate. The link also pointed at the options table rather than the Security section that explains the policy.
Four blocks in TypeScript tabs were fenced as js while titled .ts and using export default syntax.
The tip carried normative behavior, a security rationale and a remediation procedure, which made it long and easy to scan past. The content now sits under an SVG uploads heading visible in the table of contents, and the tip only points to the generated configuration.

@pwizla pwizla left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

LGTM now

@pwizla
pwizla merged commit 0a3ad3d into main Aug 26, 2026
3 of 4 checks passed
@pwizla
pwizla deleted the cms/document-svg-upload-security-policy branch August 26, 2026 10:15
pwizla added a commit that referenced this pull request Aug 26, 2026
* Mention that you need to restart Strapi after toggling Media Lib beta

* Use Slack link syntax in the unflag notification

The message was built with Markdown links, so Slack rendered them literally as
[#3378](https://…). Slack needs <url|text>, and the GitHub step summary still
needs Markdown, so the two lists are now built separately. Titles are truncated
at 70 characters like auto-respond-issues does, and the values reach the Slack
step through the environment rather than shell interpolation.
pwizla added a commit that referenced this pull request Aug 26, 2026
* Document SVG upload denial in generated project defaults

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Apply suggestion from @pwizla

* Fix broken anchor

* Commit LLMs files

* Move SVG upload denial to Media Library security section

The SVG deny policy is project configuration, not REST API surface, so it
belongs in the Media Library security section that already documents
allowedTypes and deniedTypes. Also adds the real generated defaults from the
create-strapi-app templates so readers can match them against their project.

* Add cross-references to the SVG upload denial policy

The supported media types table listed SVG without a caveat, contradicting the Security section 380 lines away. A reader whose SVG upload failed would see SVG listed as supported and conclude it was a bug.

* Fix upload security wording and link in CLI security defaults

The Upload plugin validates on actual MIME type rather than declared extension, so "dangerous extensions" was inaccurate. The link also pointed at the options table rather than the Security section that explains the policy.

* Fix code fence language on TypeScript configuration examples

Four blocks in TypeScript tabs were fenced as js while titled .ts and using export default syntax.

* Move SVG upload policy out of the admonition into its own subsection

The tip carried normative behavior, a security rationale and a remediation procedure, which made it long and easy to scan past. The content now sits under an SVG uploads heading visible in the table of contents, and the tip only points to the generated configuration.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
pwizla added a commit that referenced this pull request Aug 26, 2026
* Add the auto-merge eligibility check scripts

Twelve checks plus a shared library, one criterion per script. Each takes a PR
number and exits 0 (satisfied), 1 (violated) or 2 (could not run) so a caller can
tell a negative answer from no answer. No workflow uses them yet.

* Apply suggestion from @pwizla

* Auto-ignore 1 rejected PRs from self-healing run

* Add callout to mention the beta Media Library (#3402)

* Refine callout (TS/JS example) + add badge for new Media Lib.

* Mention how to disable the new Media Lib.

* Mention that you need to restart Strapi after toggling Media Lib beta

* 🤖 Update LLMs files [skip ci]

* Remove labels via the REST API so the unflag job survives one failure (#3403)

* Mention that you need to restart Strapi after toggling Media Lib beta

* Remove labels via the REST API so the unflag job survives one failure

gh pr edit goes through GraphQL and reads organisation fields, so it needs the
read:org scope that PAT_TOKEN_PIWI does not carry. The DELETE labels endpoint
needs repo alone. The loop also ran under set -e, so that one failure aborted the
job before the other ten PRs were looked at; it now reports and continues.

* 🤖 Update LLMs files [skip ci]

* Use Slack link syntax in the unflag notification (#3404)

* Mention that you need to restart Strapi after toggling Media Lib beta

* Use Slack link syntax in the unflag notification

The message was built with Markdown links, so Slack rendered them literally as
[#3378](https://…). Slack needs <url|text>, and the GitHub step summary still
needs Markdown, so the two lists are now built separately. Titles are truncated
at 70 characters like auto-respond-issues does, and the values reach the Slack
step through the environment rather than shell interpolation.

* Clarify partial data transfer behavior and restructure the transfer page (#3385)

* docs: clarify partial transfer stage behavior and preserve semantics

Add documentation explaining how --only and --exclude filters work with
data transfer stages (content, files, config). Clarifies that omitted
stages preserve destination data and documents the content-replace-keep-config
workflow with a stage transfer matrix.

Related to strapi/strapi#27322

* Fix stage transfer behavior matrix and partial transfer semantics

The matrix contradicted the upstream engine matrix in strapi/strapi#27322 on
--exclude files, omitted the --exclude media-library row, and claimed nothing is
preserved by default. Media library records travel with content, so excluding
files leaves records pointing at untransferred binaries. Also corrects the two
quoted CLI prompts to match command.ts and scopes the --force caution to the
stages actually transferred.

* Fix contradictory excluded-stage deletion warning in import page

The warning claimed excluded types are deleted in the target instance, the
opposite of the transfer page. Verified that import and transfer share the same
parseRestoreFromOptions call, so the semantics are identical: omitted stages are
preserved.

* Sync transfer option table in CLI reference with the transfer page

Adds the --throttle, --no-checksums and --verbose rows that were missing from
the strapi transfer table, and harmonizes the --exclude-content-types wording
across the export, import and transfer tables.

* Add data transfer stage filtering pitfalls to the known-pitfalls catalog

Four entries derived from the review of this PR, each verified against
parseRestoreFromOptions, TransferGroupPresets and expandMediaLibraryPreset:
the files preset covers binaries only while media library records ride the
content stage, the default command always preserves admin and ignored types,
omitted stages are preserved rather than deleted across import and transfer,
and the quoted CLI confirmation prompts must be checked against command.ts.

* Extract the local transfer walkthrough to its own page

The walkthrough was 121 of the transfer page's 498 lines and teaches
create-strapi-app and git rather than the transfer command, which the page
itself says is not meant for two local instances. It also duplicated the
Generate a transfer token section. Linked from the transfer page with a doc
card and wired into the pagination chain.

* Restructure the transfer page around what a transfer replaces

Reorders the sections so the preserve-versus-replace semantics come before the
--only and --exclude syntax they govern, removing a forward reference. Merges
the two near-duplicate option sections and adds the media-library value their
prose omitted. Reduces the stage-filtering section to a single table with the
media caveat promoted above it. Moves the nginx and localhost notes into a
Troubleshooting section, and adds a section for --throttle, --no-checksums and
--verbose, which existed only as table rows.

* Document badge placement for headings versus inline usage

The noTooltip rule lumped headings together with tables, which led agents to
suppress the tooltip under a heading where it belongs. Adds a placement section
distinguishing the two cases: own line under a heading with the tooltip kept,
versus same line as the content with noTooltip and the version stated in prose.

* Weave the inline badge into the sentence in the placement example

An inline badge parked at the start of the line reads as a heading badge. Show
it inside the sentence instead, which also carries the version in the prose now
that noTooltip removes the tooltip.

* Clarify that the heading badge line holds every badge for that section

"On its own line" could be read as one badge per line, which the chained plan
and version example already contradicted. States that the line under a heading
is a shared slot: all badges go on it, space-separated, never stacked.

* Restore the transfer token permissions note in the token section

Trimming the intro tip dropped the list of role-based token permissions (view,
create, read, regenerate, delete). The Generate a transfer token section never
covered them, so the information was lost rather than deduplicated. Moved it
there, where a reader asking who can manage tokens will look.

* Fix a version badge citing a Strapi release that never shipped

The content-type transfer filters were documented as available since 5.50.3,
but no such release exists: the 5.50.x line stops at 5.50.2. The filters shipped
in 5.51.0 (strapi/strapi#26915), and the Knex connection-function types landed
in the same release (#26949), so database.md carried the same wrong version.

* Replace the removed transfer env variable with the server config option

STRAPI_DISABLE_REMOTE_DATA_TRANSFER no longer works in Strapi 5: the admin
service logs "no longer supported" and reads server.transfer.remote.enabled
instead. The page was teaching a method that has no effect. Also drops --throttle
from the tuning section, since upstream marks it hideHelp() as deliberately
undocumented, scopes assetIdleTimeoutMs to pulls with its real default, restores
pagination to draft-and-publish, and applies the review's smaller fixes.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>

* 🤖 Update LLMs files [skip ci]

* Document migration progress heartbeats feature (#3394)

* Document migration progress heartbeats feature

* Apply suggestion from @pwizla

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>

* Document that MCP actions are recorded in audit logs (#3380)

* Document that MCP actions are recorded in audit logs

* Improve formatting (inline badge without tooltip)

* 🤖 Update LLMs files [skip ci]

* Document SVG denial in generated project upload defaults (#3378)

* Document SVG upload denial in generated project defaults

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Apply suggestion from @pwizla

* Fix broken anchor

* Commit LLMs files

* Move SVG upload denial to Media Library security section

The SVG deny policy is project configuration, not REST API surface, so it
belongs in the Media Library security section that already documents
allowedTypes and deniedTypes. Also adds the real generated defaults from the
create-strapi-app templates so readers can match them against their project.

* Add cross-references to the SVG upload denial policy

The supported media types table listed SVG without a caveat, contradicting the Security section 380 lines away. A reader whose SVG upload failed would see SVG listed as supported and conclude it was a bug.

* Fix upload security wording and link in CLI security defaults

The Upload plugin validates on actual MIME type rather than declared extension, so "dangerous extensions" was inaccurate. The link also pointed at the options table rather than the Security section that explains the policy.

* Fix code fence language on TypeScript configuration examples

Four blocks in TypeScript tabs were fenced as js while titled .ts and using export default syntax.

* Move SVG upload policy out of the admonition into its own subsection

The tip carried normative behavior, a security rationale and a remediation procedure, which made it long and easy to scan past. The content now sits under an SVG uploads heading visible in the table of contents, and the tip only points to the generated configuration.

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* 🤖 Update LLMs files [skip ci]

* Update Media Library UI description in documentation

* Clarify sizeLimit applies to file replacement operations (#3388)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>

* v7.1.0

* Fix media lib UI default mention

* Fix release notes script pagination and complete the 7.1.0 notes (#3405)

* Paginate milestone PR fetching in the release notes script

The GitHub API returns only 30 items per page by default, so any milestone with more PRs than that had the rest silently dropped from the generated notes. Also filters out non-PR issues, which the previous invalid &pull_request query parameter never did.

* Add the 22 PRs missing from the 7.1.0 release notes

The 7.1.0 notes listed only the 30 PRs returned by the first API page, omitting 22 merged PRs and 5 contributors. The section now covers all 52 PRs in the milestone.

* Fix miscategorized item in 7.1.1 release notes

* Add the auto-merge eligibility and cron workflows

automerge-eligibility.yml runs the twelve checks on each self-healing PR and owns
the 'automerge: eligible' label, posting a Slack veto line when a PR first
becomes eligible. automerge-cron.yml merges what has cleared the 24h quarantine
with its required checks green, skipping the run entirely while the maintainer is
away. Absence dates move to .github/absence.json so the two workflows that need
them cannot drift apart.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-doc-healing Automatically generated documentation PR internal PRs created by the Strapi core team pr: updated content PRs updating existing documentation content source: CMS

2 participants