{"id":13827174,"url":"https://github.com/argos83/ritm","last_synced_at":"2025-07-09T03:31:03.143Z","repository":{"id":38961893,"uuid":"59457295","full_name":"argos83/ritm","owner":"argos83","description":"Ruby In The Middle (HTTP/HTTPS interception proxy)","archived":false,"fork":false,"pushed_at":"2021-12-13T09:04:18.000Z","size":185,"stargazers_count":99,"open_issues_count":7,"forks_count":31,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-21T12:21:24.143Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/argos83.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-23T06:24:18.000Z","updated_at":"2025-05-12T03:46:21.000Z","dependencies_parsed_at":"2022-08-21T01:20:52.746Z","dependency_job_id":null,"html_url":"https://github.com/argos83/ritm","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/argos83/ritm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argos83%2Fritm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argos83%2Fritm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argos83%2Fritm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argos83%2Fritm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/argos83","download_url":"https://codeload.github.com/argos83/ritm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/argos83%2Fritm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261374062,"owners_count":23148948,"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":[],"created_at":"2024-08-04T09:01:51.542Z","updated_at":"2025-07-09T03:31:02.792Z","avatar_url":"https://github.com/argos83.png","language":"Ruby","funding_links":[],"categories":["\u003ca id=\"42f9e068b6511bcbb47d6b2b273097da\"\u003e\u003c/a\u003e未分类"],"sub_categories":["\u003ca id=\"3bd67ee9f322e2c85854991c85ed6da0\"\u003e\u003c/a\u003e投毒\u0026\u0026Poisoning"],"readme":"\n# Ruby In The Middle (HTTP/HTTPS interception proxy)\n\n\u003cimg src=\"docs/ritm.png\" width=\"500\"\u003e\n\n**Ruby in the middle** (RITM) is an HTTP/HTTPS interception proxy with\non-the-fly certificate generation and signing, which leaves the user\nwith the full power of the Ruby language to intercept and even modify\nrequests and responses as she pleases.\n\n## Installation\n\n`gem install ritm`\n\n## Basic usage\n\n1. **Write your interception handlers**\n\n  ```ruby\n  require 'ritm'\n  \n  # A single answer for all your google searches\n  Ritm.on_request do |req|\n    if req.request_uri.host.start_with? 'www.google.'\n      new_query_string = req.request_uri.query.gsub(/(?\u003c=^q=|\u0026q=)(((?!\u0026|$).)*)(?=\u0026|$)/, 'RubyInTheMiddle')\n      req.request_uri.query = new_query_string\n    end\n  end\n  \n  my_picture = File.read('i_am_famous.jpg')\n  \n  # Replaces every picture on the web with my pretty face\n  Ritm.on_response do |_req, res|\n    if res.header['content-type'] \u0026\u0026 res.header['content-type'].start_with?('image/')\n      res.header['content-type'] = 'image/jpeg'\n      res.body = my_picture\n    end\n  end\n  ```\n2. **Start the proxy server**\n\n  ```ruby\n  Ritm.start\n   \n  puts 'Hit enter to finish'\n  gets\n  \n  Ritm.shutdown\n  ```\n\n3. **Configure your browser**\n\n  Or whatever HTTP client you want to intercept traffic from, to connect\n  to the proxy in `localhost:8080`\n\n4. **Browse the web!**\n\n  For the examples above, search anything in google and also visit your\n  favorite newspaper website.\n\n## Trusting self-signed certificates generated by RITM\n\nWith the previous example your client might have encountered issues when\ntrying to access HTTPS resources. In some cases you can add an exception\nto your browser (or instruct your http client not to verify\ncertificates) but \n[in some other cases](https://tools.ietf.org/html/rfc6797) you won't be\nable to add exceptions. The reason for this is that in order to decrypt\nand to be able to modify SSL traffic, RITM will have to be the one doing\nthe SSL negotiatiation with the client (using its own set of\ncertificates) and then it will establish a separate SSL session towards\nthe server. I.e.:\n\n```\nClient \u003c--- SSL session ---\u003e RITM \u003c--- SSL session ---\u003e Server\n```\n\nFor every different server's hostname your client tries to communicate\nwith, RITM will generate a certificate on the fly and sign it with a\npre-configured Certificate Authority (CA). So, in order to be able to\nestablish a secure connection you will need to configure your client\n(e.g. browser) to trust RITM's CA.\n\nFor security reasons, every time you start RITM's proxy with the default\nsettings it will generate a new internal Certificate Authority. To use\nyour own CA instead (so it can be loaded and trusted by your browser)\nperform the following steps:\n\n1. **Generate a Certificate Authority PEM and Private Key files**\n\n  You can use\n  [OpenSSL](https://www.openssl.org/docs/manmaster/apps/ca.html) or RITM\n  to generate these two files. With OpenSSL:\n\n  ```\n  openssl req -new -nodes -x509 -days 365 -extensions v3_ca -keyout insecure_ca.key -out insecure_ca.crt\n  ```\n\n  Or with RITM:\n\n  ```ruby\n  require 'ritm/certs/ca'\n  \n  ca = Ritm::CA.create common_name: 'InsecureCA'\n  \n  File.write('insecure_ca.crt', ca.pem)\n  File.write('insecure_ca.key', ca.private_key.to_s)\n  ```\n2. **Repeat step 2 from the previous example, this time indicating what\nCA should be used to sign certificates**\n\n  ```ruby\n  Ritm.configure do\n    ssl_reverse_proxy.ca[:pem] = 'path/to/insecure_ca.crt'\n    ssl_reverse_proxy.ca[:key] = 'path/to/insecure_ca.key'\n  end\n  \n  Ritm.start\n  \n  puts 'Hit enter to finish'\n  gets\n  \n  Ritm.shutdown\n  ```\n3. **Trust the CA certificate into your browser or client**\n\n  I'll leave it to you to figure out how this is done in your browser or\n  client.\n4. **Surf the web!**\n\n5. When you are done **Remove the CA from your trusted authorities!** \n\n  Or take really good care of the CA private key since anyone in\n  possession of that key will be capable of decrypting all your traffic!\n  Also notice that when using the proxy every server will be\n  automatically trusted even if the end server certificate is not valid.\n\n## Running multiple sessions with different settings\n\nIn the examples above we've been using the default global session. If\nyou don't like using a statically configured global session, or you want\nto have multiple sessions coexisting (e.g. multiple proxies listening on\ndifferent ports and using different interception handlers) you can\ncreate different session instances this way:\n\n\n```ruby\nsession = Ritm::Session.new\n\n# Now you can use the same methods but on the session instance\n\nsession.configure { proxy[:bind_port] = 7777 }\nsession.on_request { |req| ...do something here ... }\n\nanother_session = Ritm::Session.new\nanother_session.configure { proxy[:bind_port] = 8888 }\nanother_session.on_request { |req| ...do something else ... }\n\nsession.start\nanother_session.start\n\nputs 'Hit enter to finish'\ngets\n\nsession.shutdown\nanother_session.shutdown\n```\n\n## License\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may\nnot use this file except in compliance with the License. You may obtain\na copy of the License at\n\n[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargos83%2Fritm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fargos83%2Fritm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fargos83%2Fritm/lists"}