{"id":13454880,"url":"https://github.com/everywall/ladder","last_synced_at":"2025-05-14T13:03:49.717Z","repository":{"id":205384564,"uuid":"713106159","full_name":"everywall/ladder","owner":"everywall","description":"Selfhosted alternative to 12ft.io. and 1ft.io bypass paywalls with a proxy ladder and remove CORS headers from any URL","archived":false,"fork":false,"pushed_at":"2024-10-02T07:19:49.000Z","size":13651,"stargazers_count":4751,"open_issues_count":18,"forks_count":188,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-04-10T00:15:32.991Z","etag":null,"topics":["bypass","cors","cors-proxy","paywall","paywall-blocker","paywall-bypasser"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/everywall.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":"2023-11-01T21:09:49.000Z","updated_at":"2025-04-09T17:49:13.000Z","dependencies_parsed_at":"2024-05-28T07:25:41.160Z","dependency_job_id":"e4891302-d87c-404d-8276-c27ca4274350","html_url":"https://github.com/everywall/ladder","commit_stats":null,"previous_names":["kubero-dev/ladder","everywall/ladder"],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/everywall%2Fladder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/everywall%2Fladder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/everywall%2Fladder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/everywall%2Fladder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/everywall","download_url":"https://codeload.github.com/everywall/ladder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254149838,"owners_count":22022850,"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":["bypass","cors","cors-proxy","paywall","paywall-blocker","paywall-bypasser"],"created_at":"2024-07-31T08:00:58.883Z","updated_at":"2025-05-14T13:03:49.606Z","avatar_url":"https://github.com/everywall.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"assets/pigeon.svg\" width=\"100px\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eLadder\u003c/h1\u003e\n\u003cdiv\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/everywall/ladder\"\u003e \u003cimg alt=\"go.mod Go version \" src=\"https://img.shields.io/github/go-mod/go-version/everywall/ladder\"\u003e \u003cimg alt=\"GitHub tag (with filter)\" src=\"https://img.shields.io/github/v/tag/everywall/ladder\"\u003e \u003cimg alt=\"GitHub (Pre-)Release Date\" src=\"https://img.shields.io/github/release-date-pre/everywall/ladder\"\u003e \u003cimg alt=\"GitHub Downloads all releases\" src=\"https://img.shields.io/github/downloads/everywall/ladder/total\"\u003e \u003cimg alt=\"GitHub Build Status (with event)\" src=\"https://img.shields.io/github/actions/workflow/status/everywall/ladder/release-binaries.yaml\"\u003e\u003c/div\u003e\n\n\n*Ladder is a http web proxy.* This is a selfhosted version of [1ft.io](https://1ft.io) and [12ft.io](https://12ft.io). It is inspired by [13ft](https://github.com/wasi-master/13ft).\n\n### Why\n\nFreedom of information is an essential pillar of democracy and informed decision-making. While media organizations have legitimate financial interests, it is crucial to strike a balance between profitability and the public's right to access information. The proliferation of paywalls raises concerns about the erosion of this fundamental freedom, and it is imperative for society to find innovative ways to preserve access to vital information without compromising the sustainability of journalism. In a world where knowledge should be shared and not commodified, paywalls should be critically examined to ensure that they do not undermine the principles of an open and informed society.\n\n\u003e **Disclaimer:** This project is intended for educational purposes only. The author does not endorse or encourage any unethical or illegal activity. Use this tool at your own risk.\n\n### How it works\n\n```mermaid\nsequenceDiagram\n    client-\u003e\u003e+ladder: GET\n    ladder--\u003e\u003eladder: apply RequestModifications\n    ladder-\u003e\u003e+website: GET\n    website-\u003e\u003e-ladder: 200 OK\n    ladder--\u003e\u003eladder: apply ResultModifications\n    ladder-\u003e\u003e-client: 200 OK\n```\n\n### Features\n- [x] Bypass Paywalls\n- [x] Remove CORS headers from responses, assets, and images ...\n- [x] Apply domain based ruleset/code to modify response / requested URL\n- [x] Keep site browsable\n- [x] API\n- [x] Fetch RAW HTML\n- [x] Custom User Agent\n- [x] Custom X-Forwarded-For IP\n- [x] [Docker container](https://github.com/everywall/ladder/pkgs/container/ladder) (amd64, arm64)\n- [x] Linux binary\n- [x] Mac OS binary\n- [x] Windows binary (untested)\n- [x] Removes most of the ads (unexpected side effect ¯\\\\\\_(ツ)_/¯ )\n- [x] Basic Auth\n- [x] Disable logs\n- [x] No Tracking\n- [x] Limit the proxy to a list of domains\n- [x] Expose Ruleset to other ladders\n- [x] Fetch from Google Cache\n- [ ] Optional TOR proxy\n- [ ] A key to share only one URL\n\n### Limitations\nSome sites do not expose their content to search engines, which means that the proxy cannot access the content. A future version will try to fetch the content from Google Cache.\n\nCertain sites may display missing images or encounter formatting issues. This can be attributed to the site's reliance on JavaScript or CSS for image and resource loading, which presents a limitation when accessed through this proxy. If you prefer a full experience, please consider buying a subscription for the site.\n\n## Installation\n\n\u003e **Warning:** If your instance will be publicly accessible, make sure to enable Basic Auth. This will prevent unauthorized users from using your proxy. If you do not enable Basic Auth, anyone can use your proxy to browse nasty/illegal stuff. And you will be responsible for it.\n\n### Binary\n1) Download binary [here](https://github.com/everywall/ladder/releases/latest)\n2) Unpack and run the binary `./ladder -r https://t.ly/14PSf`\n3) Open Browser (Default: http://localhost:8080)\n\n### Docker\n```bash\ndocker run -p 8080:8080 -d --env RULESET=https://t.ly/14PSf --name ladder ghcr.io/everywall/ladder:latest\n```\n\n### Docker Compose\n```bash\ncurl https://raw.githubusercontent.com/everywall/ladder/main/docker-compose.yaml --output docker-compose.yaml\ndocker-compose up -d\n```\n\n### Helm\nSee [README.md](/helm-chart/README.md) in helm-chart sub-directory for more information.\n\n## Usage\n\n### Browser\n1) Open Browser (Default: http://localhost:8080)\n2) Enter URL\n3) Press Enter\n\nOr direct by appending the URL to the end of the proxy URL:\nhttp://localhost:8080/https://www.example.com\n\nOr create a bookmark with the following URL:\n```javascript\njavascript:window.location.href=\"http://localhost:8080/\"+location.href\n```\n\n### API\n```bash\ncurl -X GET \"http://localhost:8080/api/https://www.example.com\"\n```\n\n### RAW\nhttp://localhost:8080/raw/https://www.example.com\n\n\n### Running Ruleset\nhttp://localhost:8080/ruleset\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description | Value |\n| --- | --- | --- |\n| `PORT` | Port to listen on | `8080` |\n| `PREFORK` | Spawn multiple server instances | `false` |\n| `USER_AGENT` | User agent to emulate | `Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)` |\n| `X_FORWARDED_FOR` | IP forwarder address | `66.249.66.1` |\n| `USERPASS` | Enables Basic Auth, format `admin:123456` | `` |\n| `LOG_URLS` | Log fetched URL's | `true` |\n| `DISABLE_FORM` | Disables URL Form Frontpage | `false` |\n| `FORM_PATH` | Path to custom Form HTML | `` |\n| `RULESET` | Path or URL to a ruleset file, accepts local directories | `https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml` or `/path/to/my/rules.yaml` or `/path/to/my/rules/` |\n| `EXPOSE_RULESET` | Make your Ruleset available to other ladders | `true` |\n| `ALLOWED_DOMAINS` | Comma separated list of allowed domains. Empty = no limitations | `` |\n| `ALLOWED_DOMAINS_RULESET` | Allow Domains from Ruleset. false = no limitations | `false` |\n\n`ALLOWED_DOMAINS` and `ALLOWED_DOMAINS_RULESET` are joined together. If both are empty, no limitations are applied.\n\n### Ruleset\n\nIt is possible to apply custom rules to modify the response or the requested URL. This can be used to remove unwanted or modify elements from the page. The ruleset is a YAML file, a directory with YAML Files, or an URL to a YAML file that contains a list of rules for each domain. These rules are loaded on startup.\n\nThere is a basic ruleset available in a separate repository [ruleset.yaml](https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml). Feel free to add your own rules and create a pull request.\n\n\n```yaml\n- domain: example.com          # Includes all subdomains\n  domains:                     # Additional domains to apply the rule\n    - www.example.de\n    - www.beispiel.de\n  headers:\n    x-forwarded-for: none      # override X-Forwarded-For header or delete with none\n    referer: none              # override Referer header or delete with none\n    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36\n    content-security-policy: script-src 'self'; # override response header\n    cookie: privacy=1\n  regexRules:\n    - match: \u003cscript\\s+([^\u003e]*\\s+)?src=\"(/)([^\"]*)\"\n      replace: \u003cscript $1 script=\"/https://www.example.com/$3\"\n  injections:\n    - position: head # Position where to inject the code\n      append: |      # possible keys: append, prepend, replace\n        \u003cscript\u003e\n          window.localStorage.clear();\n          console.log(\"test\");\n          alert(\"Hello!\");\n        \u003c/script\u003e\n- domain: www.anotherdomain.com # Domain where the rule applies\n  paths:                        # Paths where the rule applies\n    - /article\n  googleCache: false            # Use Google Cache to fetch the content\n  regexRules:                   # Regex rules to apply\n    - match: \u003cscript\\s+([^\u003e]*\\s+)?src=\"(/)([^\"]*)\"\n      replace: \u003cscript $1 script=\"/https://www.example.com/$3\"\n  injections:\n    - position: .left-content article .post-title # Position where to inject the code into DOM\n      replace: | \n        \u003ch1\u003eMy Custom Title\u003c/h1\u003e\n    - position: .left-content article # Position where to inject the code into DOM\n      prepend: | \n        \u003ch2\u003eSubtitle\u003c/h2\u003e\n- domain: demo.com\n  headers:\n    content-security-policy: script-src 'self';\n    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36\n  urlMods:              # Modify the URL\n    query:              \n      - key: amp        # (this will append ?amp=1 to the URL)\n        value: 1 \n    domain:             \n      - match: www      # regex to match part of domain\n        replace: amp    # (this would modify the domain from www.demo.de to amp.demo.de)\n    path:               \n      - match: ^        # regex to match part of path\n        replace: /amp/  # (modify the url from https://www.demo.com/article/ to https://www.demo.de/amp/article/)\n```\n\n## Development\n\nTo run a development server at http://localhost:8080:\n\n```bash\necho \"dev\" \u003e handlers/VERSION\nRULESET=\"./ruleset.yaml\" go run cmd/main.go\n```\n\n### Optional: Live reloading development server with [cosmtrek/air](https://github.com/cosmtrek/air)\n\nInstall air according to the [installation instructions](https://github.com/cosmtrek/air#installation). \n\nRun a development server at http://localhost:8080:\n\n```bash\nair # or the path to air if you haven't added a path alias to your .bashrc or .zshrc\n```\n\nThis project uses [pnpm](https://pnpm.io/) to build a stylesheet with the [Tailwind CSS](https://tailwindcss.com/) classes. For local development, if you modify styles in `form.html`, run `pnpm build` to generate a new stylesheet.\n","funding_links":[],"categories":["Go","others","[](#table-of-contents) Table of contents"],"sub_categories":["[](#warc)Tools for working with WARC (WebARChive) files"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feverywall%2Fladder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feverywall%2Fladder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feverywall%2Fladder/lists"}