diff --git a/spec/ParseFile.spec.js b/spec/ParseFile.spec.js
index 7eb7e39b17..5fa13ce9a9 100644
--- a/spec/ParseFile.spec.js
+++ b/spec/ParseFile.spec.js
@@ -1461,6 +1461,63 @@ describe('Parse.File testing', () => {
}
});
+ it('default should block SVG files', async () => {
+ await reconfigureServer({
+ fileUpload: {
+ enableForPublic: true,
+ },
+ });
+ const headers = {
+ 'X-Parse-Application-Id': 'test',
+ 'X-Parse-REST-API-Key': 'rest',
+ };
+ const svgContent = Buffer.from('').toString('base64');
+ for (const extension of ['svg', 'SVG', 'Svg']) {
+ await expectAsync(
+ request({
+ method: 'POST',
+ headers: headers,
+ url: `http://localhost:8378/1/files/malicious.${extension}`,
+ body: JSON.stringify({
+ _ApplicationId: 'test',
+ _JavaScriptKey: 'test',
+ _ContentType: 'image/svg+xml',
+ base64: svgContent,
+ }),
+ }).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('default should block SVG content type without file extension', async () => {
+ await reconfigureServer({
+ fileUpload: {
+ enableForPublic: true,
+ },
+ });
+ const svgContent = Buffer.from('').toString('base64');
+ await expectAsync(
+ request({
+ method: 'POST',
+ url: 'http://localhost:8378/1/files/file',
+ body: JSON.stringify({
+ _ApplicationId: 'test',
+ _JavaScriptKey: 'test',
+ _ContentType: 'image/svg+xml',
+ base64: svgContent,
+ }),
+ }).catch(e => {
+ throw new Error(e.data.error);
+ })
+ ).toBeRejectedWith(
+ new Parse.Error(Parse.Error.FILE_SAVE_ERROR, `File upload of extension svg+xml is disabled.`)
+ );
+ });
+
it('works with a period in the file name', async () => {
await reconfigureServer({
fileUpload: {
diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js
index f6f2e6450b..fe1d67fda3 100644
--- a/src/Options/Definitions.js
+++ b/src/Options/Definitions.js
@@ -1059,9 +1059,9 @@ 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.
It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form 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.
Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website 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.
It is recommended to restrict the file upload extensions as much as possible. HTML and SVG files are especially problematic as they may be used by an attacker who uploads a HTML form or SVG image 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.
Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?|[sS][vV][gG](\\\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.",
action: parsers.arrayParser,
- default: ['^(?![xXsS]?[hH][tT][mM][lL]?$)'],
+ default: ['^(?!([xXsS]?[hH][tT][mM][lL]?|[sS][vV][gG](\\+[xX][mM][lL])?)$)'],
},
};
/* The available log levels for Parse Server logging. Valid values are: - `'error'` - Error level (highest priority) - `'warn'` - Warning level - `'info'` - Info level (default) - `'verbose'` - Verbose level - `'debug'` - Debug level - `'silly'` - Silly level (lowest priority) */
diff --git a/src/Options/docs.js b/src/Options/docs.js
index 30d5722313..2b66fdb04d 100644
--- a/src/Options/docs.js
+++ b/src/Options/docs.js
@@ -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.
It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form 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.
Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website 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.
It is recommended to restrict the file upload extensions as much as possible. HTML and SVG files are especially problematic as they may be used by an attacker who uploads a HTML form or SVG image 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.
Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?|[sS][vV][gG](\\+[xX][mM][lL])?)$)` which allows any file extension except those that are rendered as website or active content by a web browser.
*/
/**
diff --git a/src/Options/index.js b/src/Options/index.js
index fc1d40d366..c23092485d 100644
--- a/src/Options/index.js
+++ b/src/Options/index.js
@@ -648,8 +648,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.
It is recommended to restrict the file upload extensions as much as possible. HTML files are especially problematic as they may be used by an attacker who uploads a HTML form 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.
Defaults to `^(?![xXsS]?[hH][tT][mM][lL]?$)` which allows any file extension except those MIME types that are mapped to `text/html` and are rendered as website by a web browser.
- :DEFAULT: ["^(?![xXsS]?[hH][tT][mM][lL]?$)"] */
+ /* Sets the allowed file extensions for uploading files. The extension is defined as an array of file extensions, or a regex pattern.
It is recommended to restrict the file upload extensions as much as possible. HTML and SVG files are especially problematic as they may be used by an attacker who uploads a HTML form or SVG image 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.
Defaults to `^(?!([xXsS]?[hH][tT][mM][lL]?|[sS][vV][gG](\\+[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]?|[sS][vV][gG](\\+[xX][mM][lL])?)$)"] */
fileExtensions: ?(string[]);
/* Is true if file upload should be allowed for anonymous users.
:DEFAULT: false */