VYPR
High severityNVD Advisory· Published Mar 18, 2026· Updated Mar 19, 2026

Parse Server has a stored XSS filter bypass via Content-Type MIME parameter and missing XML extension blocklist entries

CVE-2026-32728

Description

Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Prior to 9.6.0-alpha.15 and 8.6.41, an attacker who is allowed to upload files can bypass the file extension filter by appending a MIME parameter (e.g. ;charset=utf-8) to the Content-Type header. This causes the extension validation to fail matching against the blocklist, allowing active content to be stored and served under the application's domain. In addition, certain XML-based file extensions that can render scripts in web browsers are not included in the default blocklist. This can lead to stored XSS attacks, compromising session tokens, user credentials, or other sensitive data accessible via the browser's local storage. The fix in versions 9.6.0-alpha.15 and 8.6.41 strips MIME parameters from the Content-Type header before validating the file extension against the blocklist. The default blocklist has also been extended to include additional XML-based extensions (xsd, rng, rdf, rdf+xml, owl, mathml, mathml+xml) that can render active content in web browsers. Note that the fileUpload.fileExtensions option is intended to be configured as an allowlist of file extensions that are valid for a specific application, not as a denylist. The default denylist is provided only as a basic default that covers most common problematic extensions. It is not intended to be an exhaustive list of all potentially dangerous extensions. Developers should not rely on the default value, as new extensions that can render active content in browsers might emerge in the future. As a workaround, configure the fileUpload.fileExtensions option to use an allowlist of only the file extensions that your application needs, rather than relying on the default blocklist.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
parse-servernpm
>= 9.0.0, < 9.6.0-alpha.159.6.0-alpha.15
parse-servernpm
< 8.6.418.6.41

Affected products

1

Patches

2
c7599c577a02

fix: Stored XSS filter bypass via Content-Type MIME parameter and missing XML extension blocklist entries ([GHSA-42ph-pf9q-cr72](https://github.com/parse-community/parse-server/security/advisories/GHSA-42ph-pf9q-cr72)) (#10192)

5 files changed · +94 6
  • spec/vulnerabilities.spec.js+87 0 modified
    @@ -2424,3 +2424,90 @@ describe('(GHSA-c442-97qw-j6c6) SQL Injection via $regex query operator field na
         });
       });
     });
    +
    +describe('(GHSA-42ph-pf9q-cr72) Stored XSS filter bypass via parameterized Content-Type and additional XML extensions', () => {
    +  const headers = {
    +    'X-Parse-Application-Id': 'test',
    +    'X-Parse-REST-API-Key': 'rest',
    +  };
    +
    +  beforeEach(async () => {
    +    await reconfigureServer({
    +      fileUpload: {
    +        enableForPublic: true,
    +      },
    +    });
    +  });
    +
    +  for (const { ext, contentType } of [
    +    { ext: 'xsd', contentType: 'application/xml' },
    +    { ext: 'rng', contentType: 'application/xml' },
    +    { ext: 'rdf', contentType: 'application/rdf+xml' },
    +    { ext: 'owl', contentType: 'application/rdf+xml' },
    +    { ext: 'mathml', contentType: 'application/mathml+xml' },
    +  ]) {
    +    it(`blocks .${ext} file upload by default`, async () => {
    +      const content = Buffer.from(
    +        '<?xml version="1.0"?><html xmlns="http://www.w3.org/1999/xhtml"><body><script>alert(1)</script></body></html>'
    +      ).toString('base64');
    +      for (const extension of [ext, ext.toUpperCase(), ext[0].toUpperCase() + ext.slice(1)]) {
    +        await expectAsync(
    +          request({
    +            method: 'POST',
    +            headers,
    +            url: `http://localhost:8378/1/files/malicious.${extension}`,
    +            body: JSON.stringify({
    +              _ApplicationId: 'test',
    +              _JavaScriptKey: 'test',
    +              _ContentType: contentType,
    +              base64: content,
    +            }),
    +          }).catch(e => {
    +            throw new Error(e.data.error);
    +          })
    +        ).toBeRejectedWith(
    +          new Parse.Error(
    +            Parse.Error.FILE_SAVE_ERROR,
    +            `File upload of extension ${extension} is disabled.`
    +          )
    +        );
    +      }
    +    });
    +  }
    +
    +  it('blocks extensionless upload with parameterized Content-Type that bypasses regex', async () => {
    +    const content = Buffer.from(
    +      '<?xml version="1.0"?><html xmlns="http://www.w3.org/1999/xhtml"><body><script>alert(1)</script></body></html>'
    +    ).toString('base64');
    +    // MIME parameters like ;charset=utf-8 should not bypass the extension filter
    +    const dangerousContentTypes = [
    +      'application/xhtml+xml;charset=utf-8',
    +      'application/xhtml+xml; charset=utf-8',
    +      'application/xhtml+xml\t;charset=utf-8',
    +      'image/svg+xml;charset=utf-8',
    +      'application/xml;charset=utf-8',
    +      'text/html;charset=utf-8',
    +      'application/xslt+xml;charset=utf-8',
    +      'application/rdf+xml;charset=utf-8',
    +      'application/mathml+xml;charset=utf-8',
    +    ];
    +    for (const contentType of dangerousContentTypes) {
    +      await expectAsync(
    +        request({
    +          method: 'POST',
    +          url: 'http://localhost:8378/1/files/payload',
    +          body: JSON.stringify({
    +            _ApplicationId: 'test',
    +            _JavaScriptKey: 'test',
    +            _ContentType: contentType,
    +            base64: content,
    +          }),
    +        }).catch(e => {
    +          throw new Error(e.data.error);
    +        })
    +      ).toBeRejectedWith(jasmine.objectContaining({
    +        message: jasmine.stringMatching(/File upload of extension .+ is disabled/),
    +      }));
    +    }
    +  });
    +});
    
  • src/Options/Definitions.js+2 2 modified
    @@ -1145,10 +1145,10 @@ module.exports.FileUploadOptions = {
       fileExtensions: {
         env: 'PARSE_SERVER_FILE_UPLOAD_FILE_EXTENSIONS',
         help:
    -      "Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.",
    +      'Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser\'s local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\\\+[xX][mM][lL])?)$)"]`.',
         action: parsers.arrayParser,
         default: [
    -      '^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)',
    +      '^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)',
         ],
       },
     };
    
  • src/Options/docs.js+1 1 modified
    @@ -248,7 +248,7 @@
      * @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users.
      * @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users.
      * @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication.
    - * @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.
    + * @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser's local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"]`.
      */
     
     /**
    
  • src/Options/index.js+2 2 modified
    @@ -630,8 +630,8 @@ export interface PasswordPolicyOptions {
     }
     
     export interface FileUploadOptions {
    -  /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.
    -  :DEFAULT: ["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)"] */
    +  /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser's local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"]`.
    +  :DEFAULT: ["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"] */
       fileExtensions: ?(string[]);
       /*  Is true if file upload should be allowed for anonymous users.
       :DEFAULT: false */
    
  • src/Routers/FilesRouter.js+2 1 modified
    @@ -176,7 +176,8 @@ export class FilesRouter {
           } else if (contentType && contentType.includes('/')) {
             extension = contentType.split('/')[1];
           }
    -      extension = extension?.split(' ')?.join('');
    +      // Strip MIME parameters (e.g. ";charset=utf-8") and whitespace
    +      extension = extension?.split(';')[0]?.replace(/\s+/g, '');
     
           if (extension && !isValidExtension(extension)) {
             next(
    
4f53ab3cad55

fix: Stored XSS filter bypass via Content-Type MIME parameter and missing XML extension blocklist entries ([GHSA-42ph-pf9q-cr72](https://github.com/parse-community/parse-server/security/advisories/GHSA-42ph-pf9q-cr72)) (#10191)

5 files changed · +94 6
  • spec/vulnerabilities.spec.js+87 0 modified
    @@ -1289,6 +1289,93 @@ describe('(GHSA-v5hf-f4c3-m5rv) Stored XSS via .svgz, .xht, .xml, .xsl, .xslt fi
       });
     });
     
    +describe('(GHSA-42ph-pf9q-cr72) Stored XSS filter bypass via parameterized Content-Type and additional XML extensions', () => {
    +  const headers = {
    +    'X-Parse-Application-Id': 'test',
    +    'X-Parse-REST-API-Key': 'rest',
    +  };
    +
    +  beforeEach(async () => {
    +    await reconfigureServer({
    +      fileUpload: {
    +        enableForPublic: true,
    +      },
    +    });
    +  });
    +
    +  for (const { ext, contentType } of [
    +    { ext: 'xsd', contentType: 'application/xml' },
    +    { ext: 'rng', contentType: 'application/xml' },
    +    { ext: 'rdf', contentType: 'application/rdf+xml' },
    +    { ext: 'owl', contentType: 'application/rdf+xml' },
    +    { ext: 'mathml', contentType: 'application/mathml+xml' },
    +  ]) {
    +    it(`blocks .${ext} file upload by default`, async () => {
    +      const content = Buffer.from(
    +        '<?xml version="1.0"?><html xmlns="http://www.w3.org/1999/xhtml"><body><script>alert(1)</script></body></html>'
    +      ).toString('base64');
    +      for (const extension of [ext, ext.toUpperCase(), ext[0].toUpperCase() + ext.slice(1)]) {
    +        await expectAsync(
    +          request({
    +            method: 'POST',
    +            headers,
    +            url: `http://localhost:8378/1/files/malicious.${extension}`,
    +            body: JSON.stringify({
    +              _ApplicationId: 'test',
    +              _JavaScriptKey: 'test',
    +              _ContentType: contentType,
    +              base64: content,
    +            }),
    +          }).catch(e => {
    +            throw new Error(e.data.error);
    +          })
    +        ).toBeRejectedWith(
    +          new Parse.Error(
    +            Parse.Error.FILE_SAVE_ERROR,
    +            `File upload of extension ${extension} is disabled.`
    +          )
    +        );
    +      }
    +    });
    +  }
    +
    +  it('blocks extensionless upload with parameterized Content-Type that bypasses regex', async () => {
    +    const content = Buffer.from(
    +      '<?xml version="1.0"?><html xmlns="http://www.w3.org/1999/xhtml"><body><script>alert(1)</script></body></html>'
    +    ).toString('base64');
    +    // MIME parameters like ;charset=utf-8 should not bypass the extension filter
    +    const dangerousContentTypes = [
    +      'application/xhtml+xml;charset=utf-8',
    +      'application/xhtml+xml; charset=utf-8',
    +      'application/xhtml+xml\t;charset=utf-8',
    +      'image/svg+xml;charset=utf-8',
    +      'application/xml;charset=utf-8',
    +      'text/html;charset=utf-8',
    +      'application/xslt+xml;charset=utf-8',
    +      'application/rdf+xml;charset=utf-8',
    +      'application/mathml+xml;charset=utf-8',
    +    ];
    +    for (const contentType of dangerousContentTypes) {
    +      await expectAsync(
    +        request({
    +          method: 'POST',
    +          url: 'http://localhost:8378/1/files/payload',
    +          body: JSON.stringify({
    +            _ApplicationId: 'test',
    +            _JavaScriptKey: 'test',
    +            _ContentType: contentType,
    +            base64: content,
    +          }),
    +        }).catch(e => {
    +          throw new Error(e.data.error);
    +        })
    +      ).toBeRejectedWith(jasmine.objectContaining({
    +        message: jasmine.stringMatching(/File upload of extension .+ is disabled/),
    +      }));
    +    }
    +  });
    +});
    +
     describe('(GHSA-3jmq-rrxf-gqrg) Stored XSS via file serving', () => {
       it('sets X-Content-Type-Options: nosniff on file GET response', async () => {
         const file = new Parse.File('hello.txt', [1, 2, 3], 'text/plain');
    
  • src/Options/Definitions.js+2 2 modified
    @@ -1065,10 +1065,10 @@ module.exports.FileUploadOptions = {
       },
       fileExtensions: {
         env: 'PARSE_SERVER_FILE_UPLOAD_FILE_EXTENSIONS',
    -    help: "Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.",
    +    help: 'Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser\'s local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\\\+[xX][mM][lL])?)$)"]`.',
         action: parsers.arrayParser,
         default: [
    -      '^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)',
    +      '^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)',
         ],
       },
     };
    
  • src/Options/docs.js+1 1 modified
    @@ -249,7 +249,7 @@
      * @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users.
      * @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users.
      * @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication.
    - * @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.
    + * @property {String[]} fileExtensions Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser's local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"]`.
      */
     
     /**
    
  • src/Options/index.js+2 2 modified
    @@ -657,8 +657,8 @@ export interface PasswordPolicyOptions {
     }
     
     export interface FileUploadOptions {
    -  /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to restrict the file upload extensions as much as possible. HTML, SVG, and XML files are especially problematic as they may be used by an attacker who uploads a HTML form, SVG image, or XML document to look legitimate under your app's domain name, or to compromise the session token of another user via accessing the browser's local storage.<br><br>Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.
    -  :DEFAULT: ["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?)$)"] */
    +  /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.<br><br>It is recommended to only allow the file extensions that your app actually needs, rather than relying on blocking dangerous extensions. This allowlist approach is more secure because new dangerous file extensions may emerge that are not covered by the default blocklist.<br><br>The default blocks the most common file extensions that are known to be rendered as active content by web browsers, such as HTML, SVG, and XML files, which may be used by an attacker to compromise the session token of another user via accessing the browser's local storage. The blocked extensions are: `html`, `htm`, `shtml`, `xhtml`, `xhtml+xml`, `xht`, `svg`, `svgz`, `svg+xml`, `xml`, `xsl`, `xslt`, `xslt+xml`, `xsd`, `rng`, `rdf`, `rdf+xml`, `owl`, `mathml`, `mathml+xml`.<br><br>Defaults to `["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"]`.
    +  :DEFAULT: ["^(?!([xXsS]?[hH][tT][mM][lL]?(\\+[xX][mM][lL])?|[xX][hH][tT]|[sS][vV][gG]([zZ]|\\+[xX][mM][lL])?|[xX][mM][lL]|[xX][sS][lL][tT]?(\\+[xX][mM][lL])?|[xX][sS][dD]|[rR][nN][gG]|[rR][dD][fF](\\+[xX][mM][lL])?|[oO][wW][lL]|[mM][aA][tT][hH][mM][lL](\\+[xX][mM][lL])?)$)"] */
       fileExtensions: ?(string[]);
       /*  Is true if file upload should be allowed for anonymous users.
       :DEFAULT: false */
    
  • src/Routers/FilesRouter.js+2 1 modified
    @@ -368,7 +368,8 @@ export class FilesRouter {
           } else if (contentType && contentType.includes('/')) {
             extension = contentType.split('/')[1];
           }
    -      extension = extension?.split(' ')?.join('');
    +      // Strip MIME parameters (e.g. ";charset=utf-8") and whitespace
    +      extension = extension?.split(';')[0]?.replace(/\s+/g, '');
     
           if (extension && !isValidExtension(extension)) {
             next(
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.