ID FEDORA:0C00D30A5240 Type fedora Reporter Fedora Modified 2020-09-25T17:10:51
Description
REST on Rails. Wrap your RESTful web app with Ruby classes and work with th em like Active Record models.
{"id": "FEDORA:0C00D30A5240", "type": "fedora", "bulletinFamily": "unix", "title": "[SECURITY] Fedora 33 Update: rubygem-activeresource-5.1.1-1.fc33", "description": "REST on Rails. Wrap your RESTful web app with Ruby classes and work with th em like Active Record models. ", "published": "2020-09-25T17:10:51", "modified": "2020-09-25T17:10:51", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}, "href": "", "reporter": "Fedora", "references": [], "cvelist": ["CVE-2020-8151"], "lastseen": "2020-12-21T08:17:56", "viewCount": 0, "enchantments": {"dependencies": {"references": [{"type": "cve", "idList": ["CVE-2020-8151"]}, {"type": "hackerone", "idList": ["H1:800231", "H1:803922"]}, {"type": "github", "idList": ["GHSA-46J2-XJGP-JRFM"]}], "modified": "2020-12-21T08:17:56", "rev": 2}, "score": {"value": 4.5, "vector": "NONE", "modified": "2020-12-21T08:17:56", "rev": 2}, "vulnersScore": 4.5}, "affectedPackage": [{"OS": "Fedora", "OSVersion": "33", "arch": "any", "packageName": "rubygem-activeresource", "packageVersion": "5.1.1", "packageFilename": "UNKNOWN", "operator": "lt"}]}
{"cve": [{"lastseen": "2021-02-02T07:37:12", "description": "There is a possible information disclosure issue in Active Resource <v5.1.1 that could allow an attacker to create specially crafted requests to access data in an unexpected way and possibly leak information.", "edition": 8, "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "HIGH", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "NONE", "integrityImpact": "NONE", "baseScore": 7.5, "privilegesRequired": "NONE", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", "userInteraction": "NONE", "version": "3.1"}, "impactScore": 3.6}, "published": "2020-05-12T13:15:00", "title": "CVE-2020-8151", "type": "cve", "cwe": ["CWE-200"], "bulletinFamily": "NVD", "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "NONE", "integrityImpact": "NONE", "baseScore": 5.0, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:N", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "acInsufInfo": false, "impactScore": 2.9, "obtainUserPrivilege": false}, "cvelist": ["CVE-2020-8151"], "modified": "2020-09-25T19:15:00", "cpe": [], "id": "CVE-2020-8151", "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-8151", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}, "cpe23": []}], "hackerone": [{"lastseen": "2020-05-14T08:05:27", "bulletinFamily": "bugbounty", "bounty": 0.0, "cvelist": ["CVE-2020-8151"], "description": "HackerOne exposes a small number of ActiveResource objects through its GraphQL `node` interface. [ActiveResource](https://github.com/rails/activeresource) objects use HTTP as transport layer in order to fetch data. Four of these models, `TaxForm`, `Payout`, `Payment`, and `PayoutPreference` are fetched from an internal Payments backend system with a REST interface. Due to the lack of encoding the resource identifier, it is possible to inject additional parameters and point a `find` call to a difference resource endpoint.\n\n# Proof of concept\nConsider the following GraphQL query:\n\n```\nquery {\n node(id: \"gid://hackerone/PaymentsLibrary::Payment/1\") {\n ... on User { \n id\n }\n }\n}\n```\n\n**Note**: it's important to note that the model the node identifier would return does **not** correspond with the expected GraphQL type. This is important for the exploit later in the report. This query would send the following HTTP request to HackerOne's Payments backend:\n\n```\nGET /payments/1 HTTP/1.1\n...\n```\n\nBecause ActiveResource does not have an opinion on identifiers, it won't encode it (e.g. it doesn't raise an exception when a string is passed instead of an integer). This means that the following GraphQL query:\n\n```\nquery {\n node(id: \"gid://hackerone/PaymentsLibrary::Payment/something\") {\n ... on User {\n id\n }\n }\n}\n```\n\nWill result in the following HTTP request:\n\n```\nGET /payments/something HTTP/1.1\n...\n```\n\nBecause the Payments backend uses a REST interface, the `/payments` endpoint can be used to filter by the entire set of `Payment` objects. This particular controller (and corresponding controllers for the other models) have a number of parameters that can be used to filter objects. There are 16 parameters, but the two that we'll use for the exploit:\n\n * core_hacker_username\n * core_team_handle\n\nA global ID (the identifier used in the `node` interface) uses forward slashes to separate the different components (i.e. it's a URI). This means that any URL encoded character in the identifier (last) part of a global ID should be URL encoded and will be decoded when uses. This means that:\n\n```\nquery {\n node(id: \"gid://hackerone/PaymentsLibrary::Payment/%31\") {\n ... on User {\n id\n }\n }\n}\n```\n\nWill result in:\n\n```\nGET /payments/1.json HTTP/1.1\n...\n```\n\nNow consider the following GraphQL query:\n\n```\nquery {\n node(id: \"gid://hackerone/PaymentsLibrary::Payment/%3fcore_hacker_username%3djobert%26core_team_handle%3dsecurity%26\") {\n ... on User {\n id\n }\n }\n}\n```\n\nWill result in:\n\n```\nGET /payments/?core_hacker_username=jobert&core_team_handle=security%26.json HTTP/1.1\n...\n```\n\n**Note**: the trailing ampersand (`%26`) is used to let the router ignore the appended `.json` extension. The `PaymentsController#index` method will, as expected, return a serialized array of Payment objects that match the given parameters. The timing difference between a response without objects and a response with objects is significant enough to distinguish the two:\n\n| Identifier | Number of objects | RTT |\n| ------ | ------ | ------ |\n| `%3fcore_hacker_username%3djobert%26core_team_handle%3dsecurity%26` | 0 | ~400ms |\n| `%3fcore_hacker_username%3dfransrosen%26core_team_handle%3dsecurity%26` | 2 | ~2000ms |\n\nGoing back to the original query, it can be seen that it'll try to serialize a `User` object. This was necessary because not all ActiveResource models translate to a GraphQL type, such as `Payment`. Because this vulnerability can only be exploited with a timing attack it therefor doesn't matter what the response from the server is. In all cases, the server will respond with a 500 internal server error because the index endpoints of the REST interface will return an array, while the code expects a single record to be returned.\n\nBecause HackerOne exposes a sitemap with programs and user handles (and their ID), it would be rather straightforward to enumerate these and determine the information shown in the impact section of this report.\n\n# Preliminary hypothesis on root cause\nIt's rather unexpected that the ActiveResource gem does not encode the resource identifier before using it in the path of an HTTP request. This behavior is also not documented from our initial investigation. Given the identifiers shown above, the expectation would be that this query:\n\n```\nquery {\n node(id: \"gid://hackerone/PaymentsLibrary::Payment/%3fsomething%26\") {\n ... on User {\n id\n }\n }\n}\n```\n\nWould result in:\n\n```\nGET /payments/%3fsomething%26.json HTTP/1.1\n...\n```\n\nHowever, as described earlier, it results in:\n\n```\nGET /payments/?something&.json HTTP/1.1\n...\n```\n\nThe current thinking is that the ActiveResource gem should properly (re)encode the resource identifier before making the HTTP request.\n\n## Impact\n\nThe timing attack can be used to determine the following information:\n\n* roughly how many payments a user has received (not the amount, only total count!)\n* the existence of a private bug bounty program\n* the type of tax form a user has signed\n* the default payout preference type of a user", "modified": "2020-05-11T17:53:34", "published": "2020-02-20T03:25:44", "id": "H1:800231", "href": "https://hackerone.com/reports/800231", "type": "hackerone", "title": "HackerOne: GraphQL node interface for ActiveResource models lacks encoding for resource identifier, enabling parameter injection in Payments backend", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}, {"lastseen": "2020-05-14T08:05:26", "bulletinFamily": "bugbounty", "bounty": 0.0, "cvelist": ["CVE-2020-8151"], "description": "(I initially submitted this to the GitHub repository because the ActiveResource repository is not listed in scope. I was redirected here by @rafaelfranca)\n\nA number of methods in the ActiveResource library, such as `ActiveResource::Base#find` and `ActiveResource::Base#exists?` don't URL encode the resource identifier that is passed to them. Consider the following code:\n\n```ruby\nrequire 'activeresource'\n \n class Test < ActiveResource::Base\n self.site = 'http://127.0.0.1:8080'\nend\n\nTest.exists? '?a=1'\n```\n\nThe code above is expected to make a request to `http://127.0.0.1:8080/tests/%3fa%3d1.json` by properly URL encoding the resource identifier. Instead, it makes a request to `http://127.0.0.1:8080/tests/?a=1.json`.\n\nThis was tested against ActiveResource 5.1.0 and 5.0.0, both have the same unexpected behavior.\n\n## Impact\n\nBecause the index `/tests/` returns an array of objects, the code will throw an exception. However, due to the time difference that could be observed, an attacker could potentially exploit this by injecting a filter parameter to index endpoint of the resource. E.g.\n\n| Resource identifier | Objects returned | RTT |\n| ---- | ---- | ---- |\n| `?type=a&` | 1 | 500ms |\n| `?type=b&` | 0 | 100ms |", "modified": "2020-05-13T18:18:36", "published": "2020-02-24T20:41:03", "id": "H1:803922", "href": "https://hackerone.com/reports/803922", "type": "hackerone", "title": "Ruby on Rails: Missing resource identifier encoding may lead to security vulnerabilities", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}], "github": [{"lastseen": "2021-01-09T01:27:14", "bulletinFamily": "software", "cvelist": ["CVE-2020-8151"], "description": "There is a possible information disclosure issue in Active Resource <v5.1.1 that could allow an attacker to create specially crafted requests to access data in an unexpected way and possibly leak information.", "edition": 2, "modified": "2021-01-08T21:29:37", "published": "2020-05-21T21:09:38", "id": "GHSA-46J2-XJGP-JRFM", "href": "https://github.com/advisories/GHSA-46j2-xjgp-jrfm", "title": "Information disclosure issue in Active Resource", "type": "github", "cvss": {"score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N"}}]}