SSWConsulting / SSWConsulting/SSW.MeetupMCP
upload_event_image will read any file path on the machine
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Summary
upload_event_image takes an arbitrary imagePath from the model, reads it, and uploads the bytes to Meetup. There is no root directory, no traversal check, and no symlink resolution.
Evidence
src/meetup/image-service.ts:38 accepts imagePath as an unconstrained string, then stats it at line 48 and reads it at line 60. The only filter is a JPEG/WebP magic-byte check on the file contents at src/meetup/image-service.ts:13.
Confirmed against the real handler with a mocked Meetup API: an imagePath of ../../../../Users/victim/.ssh/id_rsa is read and PUT to the upload URL without error.
Impact
The effective primitive is "upload any image file anywhere on this machine to the internet". That includes screenshots, photos of whiteboards, and scanned documents sitting in ~/Pictures or ~/Downloads.
This becomes materially worse when combined with the injection surface described in the untrusted-content issue, because the path can be chosen by text that an attacker controls rather than by the operator.
Worth confirming with Meetup separately: the placeholder is created with photoType: 'GROUP_PHOTO' against the group ID at src/meetup/image-service.ts:69, which suggests the bytes land in the group's photo scope before they are attached to the event. If so, a failed attach still leaves the uploaded file on Meetup.
Suggested fix
Add a required MEETUP_IMAGE_ROOT config value. Resolve the supplied path with realpath so symlinks are followed, then reject anything that does not resolve underneath that root. Fail closed if the variable is unset.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/meetup/image-service.ts, especially the imagePath handling at lines 38, 48, and 60, and review how configuration is supplied. Confirm that an unset MEETUP_IMAGE_ROOT fails closed, resolved paths remain beneath the configured root after realpath and symlink handling, and the existing mocked Meetup upload no longer accepts outside files.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100