{"id":14638113,"url":"https://github.com/ivan-sincek/forbidden","last_synced_at":"2025-05-15T20:07:24.775Z","repository":{"id":37772825,"uuid":"413325418","full_name":"ivan-sincek/forbidden","owner":"ivan-sincek","description":"Bypass 4xx HTTP response status codes and more. The tool is based on Python Requests, PycURL, and HTTP Client.","archived":false,"fork":false,"pushed_at":"2025-03-17T10:15:54.000Z","size":1027,"stargazers_count":241,"open_issues_count":0,"forks_count":42,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-08T10:13:42.603Z","etag":null,"topics":["401","403","broken-access-controls","brute-force","bug-bounty","bypass","curl","ethical-hacking","fuzzing","offensive-security","open-redirect","owasp-top-10","penetration-testing","pycurl","python","python-requests","red-team-engagement","security","web","web-penetration-testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivan-sincek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-04T07:53:58.000Z","updated_at":"2025-04-07T15:28:59.000Z","dependencies_parsed_at":"2023-11-25T14:24:15.948Z","dependency_job_id":"deda837d-f493-4ee3-ad4c-90ba044d3bdf","html_url":"https://github.com/ivan-sincek/forbidden","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"619410475e3a38450cac38219bc71bfaa81f5d61"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivan-sincek%2Fforbidden","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivan-sincek%2Fforbidden/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivan-sincek%2Fforbidden/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivan-sincek%2Fforbidden/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivan-sincek","download_url":"https://codeload.github.com/ivan-sincek/forbidden/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414499,"owners_count":22067272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["401","403","broken-access-controls","brute-force","bug-bounty","bypass","curl","ethical-hacking","fuzzing","offensive-security","open-redirect","owasp-top-10","penetration-testing","pycurl","python","python-requests","red-team-engagement","security","web","web-penetration-testing"],"created_at":"2024-09-10T02:01:43.253Z","updated_at":"2025-05-15T20:07:19.697Z","avatar_url":"https://github.com/ivan-sincek.png","language":"Python","readme":"# Forbidden\n\nBypass 4xx HTTP response status codes and more.\n\nThe tool is based on `Python Requests`, `PycURL`, and `HTTP Client`.\n\nThe stress testing tool was inspired by this infosec [write-up](https://amineaboud.medium.com/story-of-a-weird-vulnerability-i-found-on-facebook-fc0875eb5125).\n\nTested on Kali Linux v2024.2 (64-bit).\n\nMade for educational purposes. I hope it will help!\n\n**Future plans:**\n\n* Add the `silent` option to suppress console output.\n* Add the `no color` option to disable colored console output.\n* Add tests for `hop-by-hop` HTTP request headers.\n* Add tests for the `User-Agent` HTTP request header.\n* Add tests for HTTP cookies.\n* Add tests for HTTP smuggling.\n* Add tests for CRLF.\n* Add tests for Log4j.\n* Add tests for AWS metadata SSRF.\n\n## Table of Contents\n\n* [How to Install](#how-to-install)\n    * [Install PycURL](#install-pycurl)\n    * [Standard Install](#standard-install)\n    * [Build and Install From the Source](#build-and-install-from-the-source)\n* [How to Use](#how-to-use)\n* [Tests](#tests)\n    * [HTTP Methods](#http-methods)\n    * [HTTP Request Headers](#http-request-headers)\n* [Results](#results)\n* [Usage](#usage)\n* [Images](#images)\n\n## How to Install\n\n### Install PycURL\n\nOn Kali Linux, this should work without issues; otherwise, run:\n\n```bash\napt-get -y install libcurl4-gnutls-dev librtmp-dev\n\npip3 install --upgrade pycurl\n```\n\n---\n\nPycURL on Windows OS is not supported.\n\n---\n\nOn macOS, run:\n\n```bash\nbrew uninstall curl\nbrew uninstall openssl\n\nbrew install curl\nbrew install openssl\n\necho 'export PATH=\"/opt/homebrew/opt/curl/bin:$PATH\"' \u003e\u003e ~/.zshrc\necho 'export PATH=\"/opt/homebrew/opt/openssl@3/bin:$PATH\"' \u003e\u003e ~/.zshrc\nsource ~/.zshrc\n\nexport LDFLAGS=\"-L/opt/homebrew/opt/curl/lib\"\nexport CPPFLAGS=\"-I/opt/homebrew/opt/curl/include\"\nexport PYCURL_SSL_LIBRARY=openssl\n\npip3 install --no-cache-dir --compile --ignore-installed --config-setting=\"--with-openssl=\" --config-setting=\"--openssl-dir=/opt/homebrew/opt/openssl@3\" pycurl\n```\n\nAlternatively, install using [Homebrew](https://formulae.brew.sh/formula/forbidden) (not maintained by me):\n\n```fundamental\nbrew install forbidden\n```\n\n### Standard Install\n\n```bash\npip3 install --upgrade forbidden\n```\n\n### Build and Install From the Source\n\n```bash\ngit clone https://github.com/ivan-sincek/forbidden \u0026\u0026 cd forbidden\n\npython3 -m pip install --upgrade build\n\npython3 -m build\n\npython3 -m pip install dist/forbidden-13.2-py3-none-any.whl\n```\n\n## How to Use\n\nBypass `403 Forbidden` HTTP response status code:\n\n```fundamental\nforbidden -u https://example.com/admin -t protocols,methods,uploads,overrides,headers,paths-ram,encodings -f GET -l initial,path -o forbidden_403_results.json\n```\n\nBypass `403 Forbidden` HTTP response status code with stress testing:\n\n```fundamental\nmkdir stresser_403_results\n\nstresser -u https://example.com/admin -r 1000 -th 200 -f GET -l initial -dir stresser_403_results -o stresser_403_results.json\n```\n\nBypass `401 Unauthorized` HTTP response status code:\n\n```fundamental\nforbidden -u https://example.com/admin -t auths -f GET -l initial -o forbidden_401_results.json\n```\n\nTest for open redirects and broken URL parsers, i.e., test for out-of-band (OOB) interactions:\n\n```fundamental\nforbidden -u https://example.com/admin -t redirects,parsers -f GET -l initial -e xyz.interact.sh -o forbidden_oob_results.json\n```\n\n## Tests\n\n**`protocols`**\n\n* Test HTTP and HTTPS protocols using an IP address and domain name.\n* Test an HTTP/1.0 protocol downgrade without the `Host` HTTP request header, using an IP address and domain name.\n\n**`methods`**\n\n* Test the allowed HTTP methods, also using the `Content-Length: 0` HTTP request header.\n* Test Cross-Site Tracing (XST) using the HTTP TRACE and TRACK methods.\n\n**`uploads`**\n\n* Test a text file upload recursively for each directory in the URL path using the HTTP PUT method.\n\n**`overrides`**\n\n* Test HTTP method overrides using URL query string parameters, HTTP request headers, and HTTP request bodies.\n* Test URL scheme overrides using HTTP request headers, from HTTPS to HTTP and from HTTP to HTTPS.\n* Test port overrides using HTTP request headers.\n* Test HTTP host overrides using HTTP request headers, also using two `Host` HTTP request headers.\n* Test URL path overrides using HTTP request headers with relative URL paths, using the following URLs: an accessible URL, root URL, and full URL.\n\n**`headers`**\n\n* Test HTTP request headers with IP addresses, comma-separated IP addresses, domain names, root URLs, full URLs, and more.\n\n**`values`**\n\n* Test HTTP request headers with user-supplied IP addresses, domain names, root URLs, and full URLs.\n\n**`paths`**\n\n* Test URL path bypasses.\n\n**`encodings`**\n\n* Test URL host and path transformations and encodings.\n\n**`auths`**\n\n* Test basic authentication/authorization using HTTP request headers with null values and predefined Base64 encoded credentials.\n* Test bearer authentication/authorization using HTTP request headers with null values, malformed JWTs, and predefined JWTs.\n\n**`redirects`**\n\n* Test open redirects using HTTP request headers with redirect IP addresses, domain names, root URLs, and full URLs.\n\n**`parsers`**\n\n* Test broken URL parsers using HTTP request headers with broken IP addresses, domain names, root URLs, and full URLs.\n\n---\n\nIf you're interested in more details, see:\n\n* [/src/forbidden/utils/forbidden.py](https://github.com/ivan-sincek/forbidden/blob/main/src/forbidden/utils/forbidden.py#L601)\n* [/src/forbidden/utils/test.py](https://github.com/ivan-sincek/forbidden/blob/main/src/forbidden/utils/test.py)\n* [/src/forbidden/utils/value.py](https://github.com/ivan-sincek/forbidden/blob/main/src/forbidden/utils/value.py)\n\n---\n\n**Remarks:**\n\n* All the tests are based on public infosec and bug bounty write-ups.\n* Some of the tests overlap; however, a `unique filter` is applied before anything is sent.\n* All the HTTP request headers, URL query string parameters, etc., were validated based on official documentation.\n* By default, both `Forbidden` and `Stresser` use the `Python Requests` engine.\n* Testing the HTTP/1.0 protocol downgrade without the `Host` HTTP request header is locked to the `HTTP Client` engine. Additionally, the provided cURL command will not work properly because cURL does not allow removing the `Host` HTTP request header.\n* Testing the HTTP host override using two `Host` HTTP request headers is locked to the `Python Requests` engine. Additionally, the provided cURL command will not work properly because cURL does not allow using two `Host` HTTP request headers.\n* Testing URL host and path transformations and encodings is locked to the `PycURL` engine.\n* Some web proxies might `normalize` URLs (e.g., when testing `encodings`), modify HTTP requests, or drop HTTP requests entirely.\n* Some websites might require a valid or very specific `User-Agent` HTTP request header.\n* Cross-Site Tracing (XST) is no longer considered a vulnerability.\n* Beware of `rate limiting` and other similar anti-bot protections; take some time before running the tool again on the same domain.\n\n### HTTP Methods\n\n_This is just a quick overview of what is used, but not how it is used._\n\n```fundamental\nACL\nARBITRARY\nBASELINE-CONTROL\nBIND\nCHECKIN\nCHECKOUT\nCONNECT\nCOPY\nDELETE\nGET\nHEAD\nINDEX\nLABEL\nLINK\nLOCK\nMERGE\nMKACTIVITY\nMKCALENDAR\nMKCOL\nMKREDIRECTREF\nMKWORKSPACE\nMOVE\nOPTIONS\nORDERPATCH\nPATCH\nPOST\nPRI\nPROPFIND\nPROPPATCH\nPUT\nREBIND\nREPORT\nSEARCH\nSHOWMETHOD\nSPACEJUMP\nTEXTSEARCH\nTRACE\nTRACK\nUNBIND\nUNCHECKOUT\nUNLINK\nUNLOCK\nUPDATE\nUPDATEREDIRECTREF\nVERSION-CONTROL\n```\n\n### HTTP Request Headers\n\n_This is just a quick overview of what is used, but not how it is used._\n\n```fundamental\n19-Profile\nAccept\nBase-URL\nCF-Connecting-IP\nClient-IP\nCluster-Client-IP\nDestination\nForwarded-For\nForwarded-For-IP\nFrom\nFront-End-HTTPS\nHost\nIncap-Client-IP\nOrigin\nProfile\nProxy\nProxy-Client-IP\nRedirect\nReferer\nRemote-Addr\nRequest-URI\nTrue-Client-IP\nURI\nURL\nWAP-Profile\nWL-Proxy-Client-IP\nX-Client-IP\nX-Cluster-Client-IP\nX-Forward\nX-Forward-For\nX-Forwarded\nX-Forwarded-By\nX-Forwarded-For\nX-Forwarded-For-IP\nX-Forwarded-For-Original\nX-Forwarded-Host\nX-Forwarded-Path\nX-Forwarded-Port\nX-Forwarded-Proto\nX-Forwarded-Protocol\nX-Forwarded-SSL\nX-Forwarded-Scheme\nX-Forwarded-Server\nX-HTTP-DestinationURL\nX-HTTP-Host-Override\nX-HTTP-Method\nX-HTTP-Method-Override\nX-Host\nX-Host-Override\nX-Method\nX-Method-Override\nX-Original-Forwarded-For\nX-Original-Remote-Addr\nX-Original-URL\nX-Originally-Forwarded-For\nX-Originating-IP\nX-Override-URL\nX-Proxy-Host\nX-Proxy-URL\nX-ProxyUser-IP\nX-Real-IP\nX-Referer\nX-Remote-Addr\nX-Remote-IP\nX-Rewrite-URL\nX-Scheme\nX-Server-IP\nX-True-Client-IP\nX-True-IP\nX-URL-Scheme\nX-Wap-Profile\n```\n\n## Results\n\n**Remarks:**\n\n* Results will be sorted by HTTP response status code `ascending`, HTTP response body length `descending`, and test ID `ascending`.\n* By default, only `2xx` and `3xx` HTTP response status codes are included in the results and shown in the console output.\n* The `length` attribute in the results refers to the HTTP response body length.\n* To manually filter out `false positive` results, for each unique HTTP response content length, run the provided cURL command and check if the HTTP response results in bypass; if not, simply ignore all the results with the same content length.\n\n```json\n[\n   {\n      \"id\":\"595-HOST-OVERRIDES-1\",\n      \"url\":\"https://example.com:443/admin\",\n      \"method\":\"GET\",\n      \"headers\":[\n         \"Host: 127.0.0.1\"\n      ],\n      \"cookies\":[],\n      \"body\":\"\",\n      \"user_agent\":\"Forbidden/13.2\",\n      \"command\":\"curl --path-as-is -iskL -A 'Forbidden/13.2' -H 'Host: 127.0.0.1' -X 'GET' 'https://example.com:443/admin'\",\n      \"status\":200,\n      \"length\":14301\n   },\n   {\n      \"id\":\"596-HOST-OVERRIDES-1\",\n      \"url\":\"https://example.com:443/admin\",\n      \"method\":\"GET\",\n      \"headers\":[\n         \"Host: 127.0.0.1:443\"\n      ],\n      \"cookies\":[],\n      \"body\":\"\",\n      \"user_agent\":\"Forbidden/13.2\",\n      \"command\":\"curl --path-as-is -iskL -A 'Forbidden/13.2' -H 'Host: 127.0.0.1:443' -X 'GET' 'https://example.com:443/admin'\",\n      \"status\":200,\n      \"length\":14301\n   }\n]\n```\n\n## Usage\n\n```fundamental\nForbidden v13.2 ( github.com/ivan-sincek/forbidden )\n\nUsage:   forbidden -u url                       -t tests [-f force] [-o out         ]\nExample: forbidden -u https://example.com/admin -t all   [-f GET  ] [-o results.json]\n\nDESCRIPTION\n    Bypass 4xx HTTP response status codes and more\nURL\n    Inaccessible URL\n    -u, --url = https://example.com/admin | etc.\nIGNORE PARAMETERS\n    Ignore URL query string and fragment\n    -ip, --ignore-parameters\nIGNORE REQUESTS\n    Where applicable, use PycURL instead of the default Python Requests engine\n    -ir, --ignore-requests\nTESTS\n    Tests to run\n    Specify '[ip-|host-|url-]values' to test HTTP request headers using only user-supplied values passed with the '-v' option\n    Specify 'paths-ram' to use the battering ram attack or 'paths' to use the default cluster bomb attack\n    Use comma-separated values\n    -t, --tests = protocols | methods | uploads | [method-|scheme-|port-|host-|path-]overrides | headers | [ip-|host-|url-]values | paths[-ram] | encodings | [basic-|bearer-]auths | redirects | parsers | all\nVALUES\n    File containing HTTP request header values or a single value, e.g., internal IP, etc.\n    Tests: all-values\n    -v, --values = values.txt | 10.10.15.20 | example.local | https://example.local | etc.\nFORCE\n    Force an HTTP method for all non-specific tests\n    -f, --force = GET | POST | CUSTOM | etc.\nPATH\n    Accessible URL path to test URL path overrides\n    Tests: path-overrides\n    Default: /robots.txt, /index.html, /sitemap.xml, /README.txt\n    -p, --path = /home | etc.\nEVIL\n    Evil URL or collaborator service\n    Tests: host-overrides, headers, bearer-auths, redirects, parsers\n    Default: https://github.com\n    -e, --evil = https://xyz.interact.sh | https://xyz.burpcollaborator.net | etc.\nHEADER\n    Any number of extra HTTP request headers\n    Extra HTTP request headers will not override test-specific HTTP request headers\n    Semi-colon in, e.g., 'Content-Type;' will expand to an empty HTTP request header\n    -H, --header = \"Authorization: Bearer ey...\" | Content-Type; | etc.\nCOOKIE\n    Any number of extra HTTP cookies\n    Extra HTTP cookies will not override test-specific HTTP cookies\n    -b, --cookie = PHPSESSIONID=3301 | etc.\nIGNORE\n    RegEx to filter out false positive 200 OK results\n    -i, --ignore = Inaccessible | \"Access Denied\" | \"Error: .+\" | etc.\nCONTENT LENGTHS\n    HTTP response content lengths to filter out false positive 200 OK results\n    Specify 'initial' to ignore the content length of the initial HTTP response\n    Specify 'path' to ignore the content length of the accessible URL's response\n    Use comma-separated values\n    -l, --content-lengths = 12 | initial | path | etc.\nREQUEST TIMEOUT\n    Request timeout in seconds\n    Default: 60\n    -rt, --request-timeout = 30 | 90 | etc.\nTHREADS\n    Number of parallel threads to run\n    Default: 5\n    -th, --threads = 20 | etc.\nSLEEP\n    Sleep time in milliseconds before sending an HTTP request\n    Intended for a single-thread use\n    -s, --sleep = 500 | etc.\nUSER AGENT\n    User agent to use\n    Default: Forbidden/13.2\n    -a, --user-agent = random[-all] | curl/3.30.1 | etc.\nPROXY\n    Web proxy to use\n    -x, --proxy = http://127.0.0.1:8080 | etc.\nHTTP RESPONSE STATUS CODES\n    Include only specific HTTP response status codes in the results\n    Default: 2xx, 3xx\n    Use comma-separated values\n    -sc, --status-codes = 1xx | 2xx | 3xx | 4xx | 5xx | all\nSHOW TABLE\n    Display the results in a table format instead of JSON format\n    Intended for use on a wide screen\n    -st, --show-table\nOUT\n    Output file\n    -o, --out = results.json | etc.\nDUMP\n    Dump all the test records into the output file without running any\n    -dmp, --dump\nDEBUG\n    Enable debug output\n    -dbg, --debug\n```\n\n```fundamental\nStresser v13.2 ( github.com/ivan-sincek/forbidden )\n\nUsage:   stresser -u url                       -r repeat -th threads -dir directory [-f force] [-o out         ]\nExample: stresser -u https://example.com/admin -r 1000   -th 200     -dir results   [-f GET  ] [-o results.json]\n\nDESCRIPTION\n    Bypass 4xx HTTP response status codes with stress testing\nURL\n    Inaccessible URL\n    -u, --url = https://example.com/admin | etc.\nIGNORE PARAMETERS\n    Ignore URL query string and fragment\n    -ip, --ignore-parameters\nIGNORE REQUESTS\n    Where applicable, use PycURL instead of the default Python Requests engine\n    -ir, --ignore-requests\nFORCE\n    Force an HTTP method for all non-specific tests\n    -f, --force = GET | POST | CUSTOM | etc.\nHEADER\n    Any number of extra HTTP request headers\n    Extra HTTP request headers will not override test-specific HTTP request headers\n    Semi-colon in, e.g., 'Content-Type;' will expand to an empty HTTP request header\n    -H, --header = \"Authorization: Bearer ey...\" | Content-Type; | etc.\nCOOKIE\n    Any number of extra HTTP cookies\n    Extra HTTP cookies will not override test-specific HTTP cookies\n    -b, --cookie = PHPSESSIONID=3301 | etc.\nIGNORE\n    RegEx to filter out false positive 200 OK results\n    -i, --ignore = Inaccessible | \"Access Denied\" | \"Error: .+\" | etc.\nCONTENT LENGTHS\n    HTTP response content lengths to filter out false positive 200 OK results\n    Specify 'initial' to ignore the content length of the initial HTTP response\n    Use comma-separated values\n    -l, --content-lengths = 12 | initial | etc.\nREQUEST TIMEOUT\n    Request timeout in seconds\n    Default: 60\n    -rt, --request-timeout = 30 | 90 | etc.\nREPEAT\n    Number of HTTP requests per test\n    -r, --repeat = 1000 | etc.\nTHREADS\n    Number of parallel threads to run\n    -th, --threads = 20 | etc.\nUSER AGENT\n    User agent to use\n    Default: Stresser/13.2\n    -a, --user-agent = random[-all] | curl/3.30.1 | etc.\nPROXY\n    Web proxy to use\n    -x, --proxy = http://127.0.0.1:8080 | etc.\nHTTP RESPONSE STATUS CODES\n    Include only specific HTTP response status codes in the results\n    Default: 2xx, 3xx\n    Use comma-separated values\n    -sc, --status-codes = 1xx | 2xx | 3xx | 4xx | 5xx | all\nSHOW TABLE\n    Display the results in a table format instead of JSON format\n    Intended for use on a wide screen\n    -st, --show-table\nOUT\n    Output file\n    -o, --out = results.json | etc.\nDIRECTORY\n    Output directory\n    All valid and unique HTTP responses will be saved in this directory\n    -dir, --directory = results | etc.\nDUMP\n    Dump all the test records into the output file without running any\n    -dmp, --dump\nDEBUG\n    Enable debug output\n    -dbg, --debug\n```\n\n## Images\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/ivan-sincek/forbidden/blob/main/img/real_example.png\" alt=\"Real Example\"\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eFigure 1 - Real Example\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/ivan-sincek/forbidden/blob/main/img/simple_example.png\" alt=\"Simple Example\"\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eFigure 2 - Simple Example\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://github.com/ivan-sincek/forbidden/blob/main/img/simple_example_table_output.png\" alt=\"Simple Example (Table Output)\"\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eFigure 3 - Simple Example (Table Output)\u003c/p\u003e\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivan-sincek%2Fforbidden","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivan-sincek%2Fforbidden","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivan-sincek%2Fforbidden/lists"}