Skip to content

fix(zip): make includeSources use allowlist behavior#2111

Closed
kaigritun wants to merge 1 commit intowxt-dev:mainfrom
kaigritun:fix-includesources-behavior
Closed

fix(zip): make includeSources use allowlist behavior#2111
kaigritun wants to merge 1 commit intowxt-dev:mainfrom
kaigritun:fix-includesources-behavior

Conversation

@kaigritun
Copy link

Summary

When includeSources patterns are provided, only files matching those patterns should be included in the sources ZIP. Previously, includeSources patterns were added to the default **/* glob, which could leak sensitive files that weren't explicitly excluded.

Problem

As described in #2059, the current behavior is unintuitive and can lead to data leaks:

// wxt.config.ts
export default defineConfig({
  zip: {
    includeSources: ['entrypoints/**'],
  },
})

Expected: Only entrypoints/** files are included
Actual: ALL files are included, plus the entrypoints patterns override excludeSources

This means sensitive files like secrets/api-key.txt or cache/credentials.json could accidentally be included in the sources ZIP submitted to Firefox.

Solution

This change makes includeSources behave as an allowlist:

  • When includeSources is provided: only matching files are included
  • When includeSources is not provided: all files are included (current behavior)
  • excludeSources still applies on top of include patterns

Changes

  1. packages/wxt/src/core/zip.ts: When include patterns are provided, use only those patterns for globbing instead of combining with **/*
  2. packages/wxt/src/types.ts: Updated documentation to clarify the allowlist behavior
  3. packages/wxt/e2e/tests/zip.test.ts: Added test to verify non-included files are excluded

Breaking Change

If you were using includeSources to add specific files to the default set (e.g., hidden files), you now need to include all files you want in the ZIP:

// Before (old behavior: hidden files added to default)
zip: {
  includeSources: ['.env'],
}

// After (new behavior: explicit allowlist)
zip: {
  includeSources: ['**/*', '.env'],
}

Fixes #2059

When includeSources patterns are provided, only files matching those
patterns should be included in the sources ZIP. Previously, includeSources
patterns were added to the default **/* glob, which could leak sensitive
files that weren't explicitly excluded.

This change makes includeSources behave as an allowlist:
- When includeSources is provided: only matching files are included
- When includeSources is not provided: all files are included (current behavior)

This prevents accidental inclusion of secrets, credentials, or other
sensitive files that might not be covered by excludeSources patterns.

BREAKING CHANGE: If you were using includeSources to add specific files
to the default set (e.g., hidden files), you now need to include all
files you want in the ZIP. The old behavior can be replicated by
explicitly listing all desired patterns.

Fixes wxt-dev#2059
@netlify
Copy link

netlify bot commented Feb 11, 2026

Deploy Preview for creative-fairy-df92c4 ready!

Name Link
🔨 Latest commit 6e10911
🔍 Latest deploy log https://app.netlify.com/projects/creative-fairy-df92c4/deploys/698c1308c7e72e00082f0c6c
😎 Deploy Preview https://deploy-preview-2111--creative-fairy-df92c4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Member

@aklinker1 aklinker1 left a comment

Choose a reason for hiding this comment

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

I've been trying to cleanup random config defaults outside the resolve-config.ts file. So there's a couple more changes this PR needs to make:

  1. Can you move the **/* default into the resolveZipConfig function here:

    includeSources: [],

    includeSources: mergedConfig.zip.includeSources ?? ['**/*'], 
  2. Similarly, if we move the excludeSouces array into the glob's ignore option, we can remove the hard-coded node_modules glob from here

    ignore: ['**/node_modules'],

    because it will already be included. While the zipDir function is called multiple times, the other place it's called doesn't need to ignore the node_modules folder since it's zipping the build output.

Finally, this is a breaking change, so the PR needs to be based off the major branch instead of main, and the PR should target major as well.

Comment on lines 127 to 130
).filter((relativePath) => {
return (
minimatchMultiple(relativePath, options?.include) ||
!minimatchMultiple(relativePath, options?.exclude)
);
// Exclude files that match any exclude pattern
return !minimatchMultiple(relativePath, options?.exclude);
});
Copy link
Member

Choose a reason for hiding this comment

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

We can simplify this and remove the whole filter, moving the options?.exclude globs up to here:

// Ignore node_modules, otherwise this glob step takes forever
ignore: ['**/node_modules'],

@kaigritun
Copy link
Author

Superseded by #2114 which targets the major branch and incorporates the maintainer's requested changes.

@kaigritun kaigritun closed this Feb 11, 2026
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.

zip.includeSources does not behave intuitively, can lead to data leak

2 participants