{"id":13493179,"url":"https://github.com/baldowl/rack_csrf","last_synced_at":"2025-03-28T11:31:53.142Z","repository":{"id":543955,"uuid":"173950","full_name":"baldowl/rack_csrf","owner":"baldowl","description":"Anti-CSRF Rack middleware","archived":false,"fork":false,"pushed_at":"2025-01-13T08:13:37.000Z","size":221,"stargazers_count":190,"open_issues_count":2,"forks_count":19,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-07T16:17:58.107Z","etag":null,"topics":["csrf-prevention","rack","rack-middleware","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/baldowl.png","metadata":{"files":{"readme":"README.rdoc","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE.rdoc","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":"2009-04-12T07:44:12.000Z","updated_at":"2025-01-24T05:50:30.000Z","dependencies_parsed_at":"2024-01-03T14:25:46.348Z","dependency_job_id":"66367d05-bb02-4c75-9372-a1b3d956b080","html_url":"https://github.com/baldowl/rack_csrf","commit_stats":{"total_commits":192,"total_committers":9,"mean_commits":"21.333333333333332","dds":"0.10416666666666663","last_synced_commit":"0c2c6b206a5e67f7ebbbe50da59ac2c5c6609528"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baldowl%2Frack_csrf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baldowl%2Frack_csrf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baldowl%2Frack_csrf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baldowl%2Frack_csrf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baldowl","download_url":"https://codeload.github.com/baldowl/rack_csrf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246021042,"owners_count":20710872,"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":["csrf-prevention","rack","rack-middleware","ruby"],"created_at":"2024-07-31T19:01:12.960Z","updated_at":"2025-03-28T11:31:52.893Z","avatar_url":"https://github.com/baldowl.png","language":"Ruby","readme":"= Rack::Csrf {rdoc-image:https://circleci.com/gh/baldowl/rack_csrf.svg?style=svg}[https://circleci.com/gh/baldowl/rack_csrf] {rdoc-image:https://github.com/baldowl/rack_csrf/actions/workflows/ci.yml/badge.svg?branch=master}[https://github.com/baldowl/rack_csrf/actions?query=workflow%3ACI+branch%3Amaster] {rdoc-image:https://badge.fury.io/rb/rack_csrf.svg}[http://badge.fury.io/rb/rack_csrf]\n\nThis is just a small Rack middleware whose only goal is to lessen the hazards\nposed by CSRF attacks by trying to ensure that all requests of particular\ntypes come from the right client, not from a mischievous impersonator.\n\nRack::Csrf is not tailored to any particular web framework, so it can be used\nwith your preferred Rack-based framework.\n\n== Usage\n\nFirst of all, beyond Rack itself, there is only one prerequisite: you must set\nup your rack with a session middleware, inserted anywhere before Rack::Csrf.\n\nEvery POST, PUT, DELETE and PATCH request will be searched for the\nanti-forging token, randomly generated by Rack::Csrf and stored inside the\nsession. If there's a token and it matches with the stored one, then the\nrequest is handed over to the next rack component; if not, Rack::Csrf\nimmediately replies with an empty response.\n\nThe anti-forging token can be passed as a request parameter or a header.\n\n== Options\n\nThe following options allow you to tweak Rack::Csrf.\n\n[\u003ctt\u003e:raise\u003c/tt\u003e]\n  Set it to true to change the handling of bad requests: instead of producing\n  an empty response, Rack::Csrf will raise an exception of class\n  Rack::Csrf::InvalidCsrfToken.\n\n    use Rack::Csrf, :raise =\u003e true\n\n  Default value: false.\n\n[\u003ctt\u003e:check_only\u003c/tt\u003e]\n  By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request;\n  passing an array of HTTP method/URL (regular expressions allowed) to this\n  option you can change this behavior to *only* check the items on this list.\n\n    use Rack::Csrf, :check_only =\u003e ['POST:/checking', 'PUT:/me_too',\n      'DELETE:/cars/.*\\.xml', 'PATCH:/this/.*/too']\n\n  Please, note that the regular expressions are not escaped and it is your\n  duty to write them correctly. Empty PATH_INFO (see Rack's spec for details)\n  is treated as '/' for this check.\n\n  Default value: empty.\n\n[\u003ctt\u003e:skip\u003c/tt\u003e]\n  By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request;\n  passing an array of HTTP method/URL (regular expressions allowed) to this\n  option you can choose what to let pass unchecked:\n\n    use Rack::Csrf, :skip =\u003e ['POST:/not_checking', 'PUT:/me_too',\n      'DELETE:/cars/.*\\.xml', 'PATCH:/this/.*/too']\n\n  Please, note that the regular expressions are not escaped and it is your\n  duty to write them correctly. Empty PATH_INFO (see Rack's spec for details)\n  is treated as '/' for this check.\n\n  Default value: empty.\n\n[\u003ctt\u003e:skip_if\u003c/tt\u003e]\n  Sets a lambda/Proc executed on every request to determine if that request\n  should be let pass untouched:\n\n    use Rack::Csrf, :skip_if =\u003e lambda { |request|\n      request.env.key?('HTTP_X_VERY_SPECIAL_HEADER')\n    }\n\n  Your code will receive a request object (see Rack's documentation for\n  details); if it returns anything but nil or false, no further checking is\n  performed and the request is let pass.\n\n  This option is useful if a guarded resource can be accessed by clients who\n  support CSRF token (e.g. browsers) and by ones who don't (e.g. API clients).\n\n  Don't try to check the CSRF token: it could exist or not at this stage and\n  you should always let it alone.\n\n  Default value: empty.\n\n[\u003ctt\u003e:field\u003c/tt\u003e]\n  Default field name (see below) is \u003ctt\u003e_csrf\u003c/tt\u003e; you can adapt it to\n  specific needs.\n\n    use Rack::Csrf, :field =\u003e '_my_own_csrf_field'\n\n  Default value: _csrf\n\n[\u003ctt\u003e:key\u003c/tt\u003e]\n  The key used to store/retrieve the token from the Rack session; you can\n  adapt it to specific needs.\n\n    use Rack::Csrf, :key =\u003e 'my.own_session.key'\n\n  Default value: csrf.token\n\n[\u003ctt\u003e:header\u003c/tt\u003e]\n  Default header name (see below) is \u003ctt\u003eX_CSRF_TOKEN\u003c/tt\u003e; you can adapt it\n  to specific needs.\n\n    use Rack::Csrf, :header =\u003e 'MY_CSRF_TOKEN_HEADER'\n\n  This is useful if we want to configure our application to send the CSRF\n  token in all of our AJAX requests via a header. We could implement something\n  along the lines of the following:\n\n    (function(jQuery) {\n      /*\n       * Set the CSRF token for each AJAX request, Rack::Csrf handle the rest.\n       * Assumes your layout has a metatag with name of \"_csrf\" and you're\n       * using the default Rack:Csrf header setup.\n       */\n      jQuery.ajaxSetup({\n        beforeSend: function(xhr) {\n          var token = jQuery('meta[name=\"_csrf\"]').attr('content');\n          xhr.setRequestHeader('X_CSRF_TOKEN', token);\n        }\n      });\n    }(jQuery));\n\n  Default value: X_CSRF_TOKEN\n\n  Note that Rack will append \"HTTP_\" to this value.\n\n[\u003ctt\u003e:check_also\u003c/tt\u003e]\n  By passing an array of uppercase strings to this option you can add them to\n  the list of HTTP methods which \"mark\" requests that must be searched for the\n  anti-forging token.\n\n    use Rack::Csrf, :check_also =\u003e %w(WHATEVER YOU WANT EVEN GET)\n\n  Default value: empty\n\nThe \u003ctt\u003e:browser_only\u003c/tt\u003e option has been removed; you do not need to edit\nany rackup file because Rack::Csrf simply ignores unknown options. Changes\nintroduced in Rack version 1.1.0 tightened the parsing of POST params, so\nrequests need to have the right Content-Type (or none at all); these\nContent-Types are exactly those used also by browsers and so there is no use\nfor \u003ctt\u003e:browser_only\u003c/tt\u003e anymore.\n\nThe ill devised \u003ctt\u003e:browser_only\u003c/tt\u003e option could have been used to\n\"protect\" an API, but I think it might be better to use a combination of\n\u003ctt\u003e:skip\u003c/tt\u003e and formatted URLs.\n\n== Helpers\n\nThe following class methods try to ease the insertion of the anti-forging\ntoken.\n\n[\u003ctt\u003eRack::Csrf.key\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_key\u003c/tt\u003e)]\n  Returns the name of the key used to store/retrieve the token from the Rack\n  session.\n\n  Despite this class method, you should never try to retrieve the token with\n  code like \u003ctt\u003eenv['rack.session'][Rack::Csrf.key]\u003c/tt\u003e. See the `token`\n  method below.\n\n[\u003ctt\u003eRack::Csrf.field\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_field\u003c/tt\u003e)]\n  Returns the name of the field that must be present in the request.\n\n[\u003ctt\u003eRack::Csrf.header\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_header\u003c/tt\u003e)]\n  Returns the name of the header that must be present in the request.\n\n[\u003ctt\u003eRack::Csrf.token(env)\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_token(env)\u003c/tt\u003e)]\n  Given the request's environment, it generates a random token, stuffs it in\n  the session and returns it to the caller or simply retrieves the already\n  stored one.\n\n[\u003ctt\u003eRack::Csrf.tag(env)\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_tag(env)\u003c/tt\u003e)]\n  Given the request's environment, it generates a small HTML fragment to\n  insert the token in a standard form like an hidden input field with the\n  right value already entered for you.\n\n[\u003ctt\u003eRack::Csrf.metatag(env, options = {})\u003c/tt\u003e (also \u003ctt\u003eRack::Csrf.csrf_metatag(env, options = {})\u003c/tt\u003e)]\n  Given the request's environment, it generates a small HTML fragment to\n  insert the token in a standard metatag within your layout's head with the\n  right value already entered for you.\n\n  \u003ctt\u003eoptions\u003c/tt\u003e is an optional hash that can currently take a +name+\n  setting, which will alter the metatag's name attribute.\n\n  Default name: _csrf\n\n== Working examples\n\nIn the +examples+ directory there are some small, working web applications\nwritten with different Rack-based frameworks. They are named after the used\nframework; see the various README files for other details.\n\n== Supported Rubies and Racks\n\nThe gemspec shows the minimum Ruby and Rack versions, but Rack::Csrf is\ntested only with the Rubies and Racks you can see in\n\u003ctt\u003e.circleci/config.yml\u003c/tt\u003e and/or \u003ctt\u003e.github/workflows/ci.yml\u003c/tt\u003e. It\ncould work also with older versions, but I decided not to test it against\nunsupported Rubies and Racks.\n\n== Contributing\n\nIf you want to help:\n\n* fork the project[https://github.com/baldowl/rack_csrf] on GitHub;\n* work in a topic branch;\n* add features/specs for your additions or bug fixes;\n* write your additions/bug fixes;\n* commit;\n* send me a pull request for the topic branch.\n\nIf you have any issue, please post them on the {project's issue\nlist}[https://github.com/baldowl/rack_csrf] on GitHub.\n\n== Warning! Warning! Warning!\n\nI cannot stress enough that this middleware is not a bulletproof vest or a\npanacea for the CSRF plague; it is just an *aid* and by using it you cannot\nforgo responsibilities for keeping your application as safe as possible.\n\n== Copyright\n\nCopyright (c) 2009, 2010, 2011, 2012, 2014, 2016, 2022 Emanuele Vicentini. \nSee LICENSE.rdoc for details.\n","funding_links":[],"categories":["Middleware","Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaldowl%2Frack_csrf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaldowl%2Frack_csrf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaldowl%2Frack_csrf/lists"}