Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions gems/resque-scheduler/GHSA-56gg-9g3j-m653.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
gem: resque-scheduler
ghsa: 56gg-9g3j-m653
url: https://github.com/resque/resque-scheduler/security/advisories/GHSA-56gg-9g3j-m653
title: Stored XSS in resque-scheduler web UI through job class and queue names
date: 2026-10-11
description: |
### Summary

Job class names and queue names read back out of Redis were rendered
into the resque-scheduler web UI without escaping, in both text nodes
and `value` attributes. Anyone able to enqueue a job (or otherwise
write to Redis) can store markup that executes when an operator views
the delayed jobs pages.

### Details

The affected surfaces:

- **`/delayed/:timestamp`**: the job class of every delayed job at
that timestamp
- **`/delayed/search` results**: the job class of matching delayed
jobs, both as text and inside the hidden `klass` input of the
"Cancel Job" form, plus the queue and class of matching queued and
working jobs

Neither the class nor the queue name is validated when a job is
enqueued, so any string an application passes through ends up in the
page as-is.

Fixed in https://github.com/resque/resque-scheduler/pull/830

### Impact

Script runs in the operator's browser with their resque-web session.
It can do anything the operator can do there: read job arguments,
delete queues, clear delayed and failed jobs, and queue scheduled
jobs. When resque-web is mounted inside a Rails app, it runs on the
app's origin, so it has the operator's session there as well.
cvss_v4: 5.1
patched_versions:
- ">= 5.0.1"
related:
url:
- https://github.com/resque/resque-scheduler/security/advisories/GHSA-56gg-9g3j-m653
- https://github.com/resque/resque-scheduler/pull/830
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
44 changes: 44 additions & 0 deletions gems/resque-scheduler/GHSA-g7vm-3ppj-xxrj.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
gem: resque-scheduler
ghsa: g7vm-3ppj-xxrj
url: https://github.com/resque/resque-scheduler/security/advisories/GHSA-g7vm-3ppj-xxrj
title: >-
Stored XSS in resque-scheduler requeue page through schedule names
and parameters
date: 2026-10-11
description: |
### Summary

The page shown when queueing a parameterized schedule rendered the
schedule name and its `parameters` keys, descriptions and defaults
without escaping, both as text and inside HTML attributes. An
application that builds dynamic schedules from user input lets that
input run as script in an operator's browser.

Fixed in: https://github.com/resque/resque-scheduler/pull/831

### Details

Clicking "Queue now" on `/schedule` for a schedule that defines
`parameters` posts to `/schedule/requeue`. That renders a form built
from the schedule's name and parameter definitions. The schedule list
on `/schedule` itself was already escaped, so the payload only runs
once the operator clicks through.

### Impact

Script runs in the operator's browser with their resque-web session.
It can do anything the operator can do there: read job arguments,
delete queues, clear delayed and failed jobs, and queue scheduled jobs
with chosen parameters. When resque-web is mounted inside a Rails app,
it runs on the app's origin, so it has the operator's session there as
well.
cvss_v4: 2.0
patched_versions:
- ">= 5.0.1"
related:
url:
- https://github.com/resque/resque-scheduler/security/advisories/GHSA-g7vm-3ppj-xxrj
- https://github.com/resque/resque-scheduler/pull/831
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
53 changes: 53 additions & 0 deletions gems/resque/GHSA-5r7x-x5pm-94xj.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
gem: resque
ghsa: 5r7x-x5pm-94xj
url: https://github.com/resque/resque/security/advisories/GHSA-5r7x-x5pm-94xj
title: Reflected XSS through the request path in the resque-web poll link
date: 2026-09-09
description: |
### Impact

The "Live Poll!!" link rendered on the `/overview` and `/workers`
pages interpolated the raw request path into an `href` attribute
without escaping it.

Browsers do not percent-encode apostrophes in a URL path, so an
apostrophe reaches `PATH_INFO` literally and breaks out of the
single-quoted attribute:

```
/overview/x'onmouseover='alert(document.domain)
/workers/x'onmouseover='alert(document.domain)
```

Which renders as:

```html
<a href='/overview/x'onmouseover='alert(document.domain).poll' rel='poll'>Live Poll!!</a>
```

No prior access to the application is required — a single crafted
link is enough.

### Patches

v3.0.2

### Workarounds

No known workarounds at this time. It is recommended to not click
on 3rd party or untrusted links to the resque-web interface until
you have patched your application.

### References

https://github.com/resque/resque/pull/1946
cvss_v4: 5.1
patched_versions:
- ">= 3.0.2"
related:
url:
- https://github.com/resque/resque/security/advisories/GHSA-5r7x-x5pm-94xj
- https://github.com/resque/resque/pull/1946
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
38 changes: 38 additions & 0 deletions gems/resque/GHSA-m39q-9jm7-xp4q.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
gem: resque
ghsa: m39q-9jm7-xp4q
url: https://github.com/resque/resque/security/advisories/GHSA-m39q-9jm7-xp4q
title: Reflected XSS in the resque-web stats/keys endpoint
date: 2026-09-09
description: |
### Impact

The following paths in resque-web have been found to be vulnerable
to reflected XSS:

```
/stats/keys/<img src=x onerror=alert(document.domain)>
```

### Patches

v3.0.1

### Workarounds

No known workarounds at this time. It is recommended to not click
on 3rd party or untrusted links to the resque-web interface until
you have patched your application.

### References

https://github.com/resque/resque/pull/1942
cvss_v3: 6.3
patched_versions:
- ">= 3.0.1"
related:
url:
- https://github.com/resque/resque/security/advisories/GHSA-m39q-9jm7-xp4q
- https://github.com/resque/resque/pull/1942
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
65 changes: 65 additions & 0 deletions gems/resque/GHSA-r23w-h6cg-h95q.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
gem: resque
ghsa: r23w-h6cg-h95q
url: https://github.com/resque/resque/security/advisories/GHSA-r23w-h6cg-h95q
title: >-
Stored XSS in resque-web through queue names, worker IDs, and job
payloads
date: 2026-09-09
description: |
### Impact

Values read back out of Redis were rendered into resque-web without
escaping, in both text nodes and `href` attributes. Anyone able to
enqueue a job (or otherwise write to Redis) can store markup that
executes when an operator loads the admin UI.

The affected surfaces:

- **Queue names** — `/queues`, `/queues/:id`, and the queue sidebar
on every page that renders it
- **Worker IDs** (`hostname:pid:queues`) — `/workers`,
`/workers/:id`, `/working`
- **Job class names and payload data** — the shared job class
partial, used by the queues, workers, working and failed pages
- **Failed job details** (worker, queue, exception) — `/failed`
- **Redis key names and values** — `/stats/keys` and
`/stats/keys/:key`
- **`/stats.txt`** — built a plaintext metrics feed but declared
`Content-Type: text/html`, so a queue name containing markup
executed on that endpoint

Queue names are not validated, so enqueueing to a crafted queue name
is enough:

```ruby
Resque.push(%q{"><svg onload=alert(document.domain)>}, 'class' => 'Job', 'args' => [])
```

That payload executes immediately on /queues, /stats/keys, and
/stats.txt. It also reaches /workers and /working once a worker is
registered on that queue, and /failed once a job fails on it.

### Patches

v3.0.2

### Workarounds

Restrict who can enqueue jobs and which queue names they can enqueue
to, and restrict write access to the Redis instance backing Resque.
Access to `/stats/keys` and `/stats.txt` can be blocked at the proxy
as a partial mitigation.

### References

https://github.com/resque/resque/pull/1946
cvss_v4: 5.1
patched_versions:
- ">= 3.0.2"
related:
url:
- https://github.com/resque/resque/security/advisories/GHSA-r23w-h6cg-h95q
- https://github.com/resque/resque/pull/1946
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
93 changes: 93 additions & 0 deletions gems/resque/GHSA-r5h4-xh93-f339.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
gem: resque
ghsa: r5h4-xh93-f339
url: https://github.com/resque/resque/security/advisories/GHSA-r5h4-xh93-f339
title: CSRF in resque-web
date: 2026-10-16
description: |
### Summary

resque-web (`Resque::Server`) does not verify that state-changing
requests come from its own origin. If an authenticated resque-web
user visits a malicious page, that page can make the user's browser
clear failed jobs, retry or remove failed jobs, or delete whole
queues.

### Details

Sinatra enables rack-protection by default, but its default reaction
to a bad `Origin` is to drop the Rack session and let the request
through. resque-web doesn't keep its login in a Sinatra session, so
that reaction protects nothing.

Which setups are exposed depends on how resque-web is authenticated:

- **HTTP basic auth** (`Resque::Server.use Rack::Auth::Basic`, as the
README recommends): browsers resend cached credentials on
cross-site requests, so every action below is exposed.
- **Host app session cookie with `SameSite=Lax`** (the Rails
default): cross-site POSTs are blocked by the browser, but the GET
actions below are still exposed.
- **Cookies with `SameSite=None` or no SameSite attribute**: every
action is exposed.

State-changing POST routes:

- `/queues/:id/remove`, `/queues/:id/remove-job`
- `/failed/clear`, `/failed/clear_retried`, `/failed/:queue/clear`
- `/failed/requeue/all`, `/failed/:queue/requeue/all`

State-changing GET routes (an `<img>` tag is enough to trigger these):

- `/failed/requeue/:index`, `/failed/:queue/requeue/:index`
- `/failed/remove/:index`, `/failed/:queue/remove/:index`

Plugins that add routes to `Resque::Server` (for example
resque-scheduler, resque-cleaner, resque-retry and resque-status)
inherit the same exposure on their POST routes.

### Impact

An attacker who can get a resque-web user to visit a page can change
queue state with that user's access: they can delete pending jobs,
wipe the failed job history, or requeue failed jobs. Requeued jobs
run again, which matters when a job has side effects (charging a
card, sending email). The attacker cannot read anything; this is an
integrity issue, not a disclosure.

### Patches

3.2.0 rejects any non-GET/HEAD request whose `Sec-Fetch-Site` header
is not `same-origin` or `none`. For browsers that don't send
`Sec-Fetch-Site`, it falls back to rejecting a request whose `Origin`
host doesn't match the request host. Requests that send neither
header (scripts, curl) are unaffected. The single-job retry and
remove actions are now POST-only. The check runs on `Resque::Server`
itself, so it also covers plugin routes.

### Workarounds

Upgrade. If you can't upgrade yet, add this filter to your app before
it serves resque-web. It only covers browsers that send
`Sec-Fetch-Site`, which all current browsers do:

```ruby
Resque::Server.before do
site = request.env['HTTP_SEC_FETCH_SITE']
mutating = !request.safe? || request.path_info.match?(%r{\A/failed/(.+/)?(requeue|remove)/\d+/?\z})
halt 403 if mutating && site && !%w[same-origin none].include?(site)
end
```

### References

https://github.com/resque/resque/pull/1980
cvss_v4: 6.9
patched_versions:
- ">= 3.2.0"
related:
url:
- https://github.com/resque/resque/security/advisories/GHSA-r5h4-xh93-f339
- https://github.com/resque/resque/pull/1980
notes: |
- A CVE has been requested for this GHSA and can be added once assigned.
Loading