Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add server side validation for uploaded file types #173960

Merged

Conversation

SiddharthMantri
Copy link
Contributor

@SiddharthMantri SiddharthMantri commented Dec 26, 2023

Summary

Closes https://github.com/elastic/security/issues/1839

Fixes

  • Introduced a MIME type check for the server endpoint for image upload. The check runs against the same allowed file types for the UI and returns an error if not matched.

Tesing

  1. Use the POST kbn://internal/security/user_profile/_data endpoint with a body as follows (substituting your own base64 image string):
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
  1. The beginning of the base64 string should look something like "data:image/png;base64,...", where 'png' is the image format. Verify that all supported image formats work and the API returns 200 for each.

  2. In the base64 string, change the image format (e.g. 'png') to a non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media Type" error occurs.

  3. In the base64 string, change the "data:image/png;base64" to "data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error occurs.

Release notes

@SiddharthMantri SiddharthMantri added Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! Feature:Users/Roles/API Keys release_note:fix labels Dec 28, 2023
@SiddharthMantri SiddharthMantri marked this pull request as ready for review December 28, 2023 12:06
@SiddharthMantri SiddharthMantri requested a review from a team as a code owner December 28, 2023 12:06
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-security (Team:Security)

@jeramysoucy
Copy link
Contributor

/ci

@jeramysoucy jeramysoucy self-requested a review December 28, 2023 16:24
Copy link
Contributor

@jeramysoucy jeramysoucy left a comment

Choose a reason for hiding this comment

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

Overall looks good! I just had couple of comments/questions.


const [, mimeType] = matches;

if (!IMAGE_FILE_TYPES.includes(mimeType)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also constrain the image size (automatically resize) as we do via the UI?
https://github.com/elastic/kibana/blob/079db3e7ebcbed934c39d0efe67821317fe9eaec/x-pack/plugins/security/public/account_management/user_profile/utils.ts#L63C8-L63C8

I did notice that at some point the payload max size kicks in, which would limit the incoming image size, but not to same degree that the UI resizes.

{
"statusCode": 413,
"error": "Request Entity Too Large",
"message": "Payload content length greater than maximum allowed: 1048576"
}

Copy link
Contributor

Choose a reason for hiding this comment

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

You can see that if I upload via API, the image is much more clear because it is not resized:
Screenshot 2023-12-28 at 1 24 26 PM

But if I upload via the UI, it gets resized:
Screenshot 2023-12-28 at 1 24 02 PM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! As image resizing is done via the Image and Canvas APIs on the browser, we'll need to use libraries to do the same for the node server which means adding a new dependency. Where does this dependency go? Top level package.json?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding a separate issue for this. https://github.com/elastic/security/issues/1868

@jeramysoucy
Copy link
Contributor

In testing this PR I noticed that the Avatar image upload on the Edit User Profile page behaves not as I would expect. So long as you've uploaded an image file, any subsequent non-supported file dragged to the image input does not provide any feedback. I will create an issue for this.

@SiddharthMantri SiddharthMantri requested a review from a team as a code owner January 12, 2024 12:41
@SiddharthMantri
Copy link
Contributor Author

/ci

@SiddharthMantri
Copy link
Contributor Author

/ci

Copy link
Contributor

@jeramysoucy jeramysoucy left a comment

Choose a reason for hiding this comment

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

LGTM! I tested with various good and bad inputs, including large images which get rejected due to the payload size.

@SiddharthMantri
Copy link
Contributor Author

@elasticmachine merge upstream

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
security 580.3KB 580.2KB -35.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
security 64.6KB 64.7KB +91.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@SiddharthMantri SiddharthMantri merged commit 9ab8b1d into elastic:main Jan 30, 2024
17 checks passed
@kibanamachine kibanamachine added v8.13.0 backport:skip This commit does not require backporting labels Jan 30, 2024
nreese pushed a commit to nreese/kibana that referenced this pull request Jan 31, 2024
## Summary

Closes elastic/security#1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
WafaaNasr pushed a commit to WafaaNasr/kibana that referenced this pull request Feb 5, 2024
## Summary

Closes https://github.com/elastic/security/issues/1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
WafaaNasr pushed a commit to WafaaNasr/kibana that referenced this pull request Feb 6, 2024
## Summary

Closes https://github.com/elastic/security/issues/1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
## Summary

Closes https://github.com/elastic/security/issues/1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
## Summary

Closes https://github.com/elastic/security/issues/1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
fkanout pushed a commit to fkanout/kibana that referenced this pull request Mar 4, 2024
## Summary

Closes elastic/security#1839


## Fixes

- Introduced a MIME type check for the server endpoint for image upload.
The check runs against the same allowed file types for the UI and
returns an error if not matched.

### Tesing

1. Use the `POST kbn://internal/security/user_profile/_data` endpoint
with a body as follows (substituting your own base64 image string):

```
{
  "avatar": {
    "imageUrl": "[image as base64 encoded string]"
   }
}
```

2. The beginning of the base64 string should look something like
"data:image/png;base64,...", where 'png' is the image format. Verify
that all supported image formats work and the API returns 200 for each.

3. In the base64 string, change the image format (e.g. 'png') to a
non-supported format (e.g. 'gnp') and verify a 415 "Unsupported Media
Type" error occurs.
4. In the base64 string, change the "data:image/png;base64" to
"data:file/pdf;base64" and verify a 415 "Unsupported Media Type" error
occurs.

## Release notes

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Users/Roles/API Keys release_note:fix Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more! v8.13.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants