{"id":13562132,"url":"https://github.com/assetnote/kiterunner","last_synced_at":"2025-05-15T14:04:08.365Z","repository":{"id":37778283,"uuid":"355407223","full_name":"assetnote/kiterunner","owner":"assetnote","description":"Contextual Content Discovery Tool","archived":false,"fork":false,"pushed_at":"2024-04-29T02:49:24.000Z","size":251,"stargazers_count":2815,"open_issues_count":49,"forks_count":307,"subscribers_count":38,"default_branch":"main","last_synced_at":"2025-04-15T03:53:24.515Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/assetnote.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-04-07T04:03:00.000Z","updated_at":"2025-04-15T02:43:26.000Z","dependencies_parsed_at":"2024-06-18T18:23:29.309Z","dependency_job_id":"cec6841e-4980-48fd-a19d-e9102e9ccac3","html_url":"https://github.com/assetnote/kiterunner","commit_stats":{"total_commits":12,"total_committers":4,"mean_commits":3.0,"dds":"0.33333333333333337","last_synced_commit":"7d5824cda9a2eef86d8d18b05b713d7e260f34d2"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fkiterunner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fkiterunner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fkiterunner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/assetnote%2Fkiterunner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/assetnote","download_url":"https://codeload.github.com/assetnote/kiterunner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355333,"owners_count":22057354,"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-01T13:01:04.953Z","updated_at":"2025-05-15T14:04:08.260Z","avatar_url":"https://github.com/assetnote.png","language":"Go","readme":"# Kiterunner\n\n![](/hack/kiterunner.png)\n\n[![GoDoc](https://godoc.org/github.com/assetnote/kiterunner?status.svg)](https://godoc.org/github.com/assetnote/kiterunner)\n[![GitHub release](https://img.shields.io/github/release/assetnote/kiterunner.svg)](https://github.com/assetnote/kiterunner/releases)\n[![Go Report Card](https://goreportcard.com/badge/github.com/assetnote/kiterunner)](https://goreportcard.com/report/github.com/assetnote/kiterunner)\n\n# Introduction\n\nFor the longest of times, content discovery has been focused on finding files and folders. While this approach is effective for legacy web servers that host static files or respond with 3xx’s upon a partial path, it is no longer effective for modern web applications, specifically APIs.\n\nOver time, we have seen a lot of time invested in making content discovery tools faster so that larger wordlists can be used, however the art of content discovery has not been innovated upon.\n\nKiterunner is a tool that is capable of not only performing traditional content discovery at lightning fast speeds, but also bruteforcing routes/endpoints in modern applications.\n\nModern application frameworks such as Flask, Rails, Express, Django and others follow the paradigm of explicitly defining routes which expect certain HTTP methods, headers, parameters and values. \n\nWhen using traditional content discovery tooling, such routes are often missed and cannot easily be discovered.\n\nBy collating a dataset of Swagger specifications and condensing it into our own schema, Kiterunner can use this dataset to bruteforce API endpoints by sending the correct HTTP method, headers, path, parameters and values for each request it sends.\n\nSwagger files were collected from a number of datasources, including an internet wide scan for the 40+ most common swagger paths. Other datasources included [GitHub via BigQuery](https://cloud.google.com/bigquery/public-data/github), and [APIs.guru](https://apis.guru/).\n\n# Contents\n\n* [Kiterunner](#kiterunner)\n* [Introduction](#introduction)\n* [Installation](#installation)\n  * [Downloading a release](#downloading-a-release)\n  * [Building from source](#building-from-source)\n  * [Installing via AUR](#aur)\n* [Usage](#usage)\n  * [Quick Start](#quick-start)\n  * [CLI Help](#cli-help)\n  * [Input/Host Formatting](#inputhost-formatting)\n  * [API Scanning](#api-scanning)\n  * [Vanilla Bruteforcing](#vanilla-bruteforcing)\n  * [Dirsearch Bruteforcing](#dirsearch-bruteforcing)\n* [Technical Features](#technical-features)\n  * [Depth Scanning](#depth-scanning)\n  * [Using Assetnote Wordlists](#using-assetnote-wordlists)\n    * [Head Syntax](#head-syntax)\n  * [Concurrency Settings/Going Fast](#concurrency-settingsgoing-fast)\n  * [Converting between file formats](#converting-between-file-formats)\n  * [Replaying requests](#replaying-requests)\n* [Technical Implementation](#technical-implementation)\n  * [Intermediate Data Type (PRoutes)](#intermediate-data-type-proutes)\n  * [Kite File Format](#kite-file-format)\n\n# Installation\n\n## Downloading a release\n\nYou can download a pre-built copy from https://github.com/assetnote/kiterunner/releases.\n\n## Building from source\n```bash\n# build the binary\nmake build\n\n# symlink your binary\nln -s $(pwd)/dist/kr /usr/local/bin/kr\n\n# compile the wordlist\n# kr kb compile \u003cinput.json\u003e \u003coutput.kite\u003e\nkr kb compile routes.json routes.kite\n\n# scan away\nkr scan hosts.txt -w routes.kite -x 20 -j 100 --ignore-length=1053\n```\n\nThe JSON datasets can be found below:\n\n- [routes-large.json](https://wordlists-cdn.assetnote.io/rawdata/kiterunner/routes-large.json.tar.gz) (118MB compressed, 2.6GB decompressed)\n- [routes-small.json](https://wordlists-cdn.assetnote.io/rawdata/kiterunner/routes-small.json.tar.gz) (14MB compressed, 228MB decompressed)\n\nAlternatively, it is possible to download the compile `.kite` files from the links below:\n\n- [routes-large.kite](https://wordlists-cdn.assetnote.io/data/kiterunner/routes-large.kite.tar.gz) (40MB compressed, 183M decompressed)\n- [routes-small.kite](https://wordlists-cdn.assetnote.io/data/kiterunner/routes-small.kite.tar.gz) (2MB compressed, 35MB decompressed)\n\n## AUR\nUsers using a Arch based distro can download the pre-built binary from [AUR](https://aur.archlinux.org/packages/kiterunner-bin/)\nYou can use a \"Aur Helper\" like `yay` to install kiterunner\n```\nyay -S kiterunner-bin\n```\n# Usage\n\n## Quick Start\n\n```\nkr [scan|brute] \u003cinput\u003e [flags]\n```\n\n- `\u003cinput\u003e` can be a file, a domain, or URI. we'll figure it out for you. See  [Input/Host Formatting](#inputhost-formatting) for more details\n\n```\n# Just have a list of hosts and no wordlist\nkr scan hosts.txt -A=apiroutes-210328:20000 -x 5 -j 100 --fail-status-codes 400,401,404,403,501,502,426,411\n\n# You have your own wordlist but you want assetnote wordlists too\nkr scan target.com -w routes.kite -A=apiroutes-210328:20000 -x 20 -j 1 --fail-status-codes 400,401,404,403,501,502,426,411\n\n# Bruteforce like normal but with the first 20000 words\nkr brute https://target.com/subapp/ -A=aspx-210328:20000 -x 20 -j 1\n\n# Use a dirsearch style wordlist with %EXT%\nkr brute https://target.com/subapp/ -w dirsearch.txt -x 20 -j 1 -exml,asp,aspx,ashx -D\n```\n\n\n\n## CLI Help\n\n```\nUsage:\n  kite scan [flags]\n\nFlags:\n  -A, --assetnote-wordlist strings    use the wordlists from wordlist.assetnote.io. specify the type/name to use, e.g. apiroutes-210228. You can specify an additional maxlength to use only the first N values in the wordlist, e.g. apiroutes-210228;20000 will only use the first 20000 lines in that wordlist\n      --blacklist-domain strings      domains that are blacklisted for redirects. We will not follow redirects to these domains\n      --delay duration                delay to place inbetween requests to a single host\n      --disable-precheck              whether to skip host discovery\n      --fail-status-codes ints        which status codes blacklist as fail. if this is set, this will override success-status-codes\n      --filter-api strings            only scan apis matching this ksuid\n      --force-method string           whether to ignore the methods specified in the ogl file and force this method\n  -H, --header strings                headers to add to requests (default [x-forwarded-for: 127.0.0.1])\n  -h, --help                          help for scan\n      --ignore-length strings         a range of content length bytes to ignore. you can have multiple. e.g. 100-105 or 1234 or 123,34-53. This is inclusive on both ends\n      --kitebuilder-full-scan         perform a full scan without first performing a phase scan.\n  -w, --kitebuilder-list strings      ogl wordlist to use for scanning\n  -x, --max-connection-per-host int   max connections to a single host (default 3)\n  -j, --max-parallel-hosts int        max number of concurrent hosts to scan at once (default 50)\n      --max-redirects int             maximum number of redirects to follow (default 3)\n  -d, --preflight-depth int           when performing preflight checks, what directory depth do we attempt to check. 0 means that only the docroot is checked (default 1)\n      --profile-name string           name for profile output file\n      --progress                      a progress bar while scanning. by default enabled only on Stderr (default true)\n      --quarantine-threshold int      if the host return N consecutive hits, we quarantine the host as wildcard. Set to 0 to disable (default 10)\n      --success-status-codes ints     which status codes whitelist as success. this is the default mode\n  -t, --timeout duration              timeout to use on all requests (default 3s)\n      --user-agent string             user agent to use for requests (default \"Chrome. Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36\")\n      --wildcard-detection            can be set to false to disable wildcard redirect detection (default true)\n\nGlobal Flags:\n      --config string    config file (default is $HOME/.kiterunner.yaml)\n  -o, --output string    output format. can be json,text,pretty (default \"pretty\")\n  -q, --quiet            quiet mode. will mute unecessarry pretty text\n  -v, --verbose string   level of logging verbosity. can be error,info,debug,trace (default \"info\")\n```\n\nbruteforce flags (all the flags above +)\n```\n  -D, --dirsearch-compat              this will replace %EXT% with the extensions provided. backwards compat with dirsearch because shubs loves him some dirsearch\n  -e, --extensions strings            extensions to append while scanning\n  -w, --wordlist strings              normal wordlist to use for scanning\n```\n## Input/Host Formatting\n\nWhen supplied with an input, kiterunner will attempt to resolve the input in the following order:\n1. Is the input a file. If so read all the lines in the file as separate domains\n2. The input is treated as a \"domain\"\n\nIf you supply a \"domain\", but it exists as a file, e.g. `google.com` but `google.com` is also a txt file in the current directory,\nwe'll load `google.com` the text file, because we found it first.\n\n**Domain Parsing**\n\nIts preferred that you provide a full URI as the input, however you can provide incomplete URIs and we'll try and guess what you mean.\nAn example list of domains you can supply are:\n\n```\none.com\ntwo.com:80\nthree.com:443\nfour.com:9447\nhttps://five.com:9090\nhttp://six.com:80/api\n```\n\nThe above list of domains will expand into the subsequent list of targets\n\n```\n(two targets are created for one.com, since neither port nor protocol was specified)\nhttp://one.com (port 80 implied)\nhttps://one.com (port 443 implied)\n\nhttp://two.com (port 80 implied)\nhttps://three.com (port 443 implied)\nhttp://four.com:9447 (non-tls port guessed)\nhttps://five.com:9090\nhttp://six.com/api (port 80 implied; basepath API appended)\n```\n\nthe rules we apply are:\n- if you supply a scheme, we use the scheme.\n  - We only support http \u0026 https\n  - if you don't supply a scheme, we'll guess based on the port\n- if you supply a port, we'll use the port\n  - If your port is 443, or 8443, we'll assume its tls\n  - if you don't supply a port, we'll guess both port 80, 443\n- if you supply a path, we'll prepend that path to all requests against that host\n\n## API Scanning\n\nWhen you have a single target\n```bash\n# single target\nkr scan https://target.com:8443/ -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34\n\n# single target, but you want to try http and https\nkr scan target.com -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34\n\n# a list of targets\nkr scan targets.txt -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34\n```\n\n## Vanilla Bruteforcing \n\n```bash\nkr brute https://target.com -A=raft-large-words -A=apiroutes-210228:20000 -x 10 -d=0 --ignore-length=34 -ejson,txt\n```\n\n## Dirsearch Bruteforcing\n\nFor when you have an old-school wordlist that still has %EXT% in the wordlist, you can use `-D`. this will only substitute the extension where %EXT% is present in the path\n\n```bash\nkr brute https://target.com -w dirsearch.txt -x 10 -d=0 --ignore-length=34 -ejson,txt -D\n```\n\n# Technical Features\n\n## Depth Scanning\n\nA key feature of kiterunner is depth based scanning. This attempts to handle detecting wildcards given virtual application path based routing. The depth defines how many directories deep the baseline checks are performed E.g.\n\n```bash\n~/kiterunner $ cat wordlist.txt\n\n/api/v1/user/create\n/api/v1/user/delete\n/api/v2/user/\n/api/v2/admin/\n/secrets/v1/\n/secrets/v2/\n```\n\n- At depth 0, only `/` would have the baseline checks performed for wildcard detection\n- At depth 1, `/api` and `/secrets` would have baseline checks performed; and these checks would be used against `/api` and `/secrets` correspondingly\n- At depth 2, `/api/v1`, `/api/v2`, `/secrets/v1` and `/secrets/v2` would all have baseline checks performed.\n\nBy default, `kr scan` has a depth of 1, since from internal usage, we've often seen this as the most common depth where virtual routing has occured. `kr brute` has a default depth of 0, as you typically don't want this check to be performed with a static wordlist.\n\nNaturally, increasing the depth will increase the accuracy of your scans, however this also increases the number of requests to the target. (`# of baseline checks * # of depth baseline directories`). Hence, we recommend against going above 1, and in rare cases going to depth 2.\n\n\n## Using Assetnote Wordlists\n\nWe provide inbuilt downloading and caching of wordlists from assetnote.io. You can use these with the `-A` flag which receives a comma delimited list of aliases, or fullnames.\n\nYou can get a full list of all the Assetnote wordlists with `kr wordlist list`. \n\nThe wordlists when used, are cached in `~/.cache/kiterunner/wordlists`. When used, these are compiled from `.txt` -\u003e `.kite` \n\n```\n+-----------------------------------+-------------------------------------------------------+----------------+---------+----------+--------+\n|               ALIAS               |                       FILENAME                        |     SOURCE     |  COUNT  | FILESIZE | CACHED |\n+-----------------------------------+-------------------------------------------------------+----------------+---------+----------+--------+\n| 2m-subdomains                     | 2m-subdomains.txt                                     | manual.json    | 2167059 | 28.0mb   | false  |\n| asp_lowercase                     | asp_lowercase.txt                                     | manual.json    |   24074 | 1.1mb    | false  |\n| aspx_lowercase                    | aspx_lowercase.txt                                    | manual.json    |   80293 | 4.4mb    | false  |\n| bak                               | bak.txt                                               | manual.json    |   31725 | 634.8kb  | false  |\n| best-dns-wordlist                 | best-dns-wordlist.txt                                 | manual.json    | 9996122 | 139.0mb  | false  |\n| cfm                               | cfm.txt                                               | manual.json    |   12100 | 260.3kb  | true   |\n| do                                | do.txt                                                | manual.json    |  173152 | 4.8mb    | false  |\n| dot_filenames                     | dot_filenames.txt                                     | manual.json    | 3191712 | 71.3mb   | false  |\n| html                              | html.txt                                              | manual.json    | 4227526 | 107.7mb  | false  |\n| apiroutes-201120                  | httparchive_apiroutes_2020_11_20.txt                  | automated.json |  953011 | 45.3mb   | false  |\n| apiroutes-210128                  | httparchive_apiroutes_2021_01_28.txt                  | automated.json |  225456 | 6.6mb    | false  |\n| apiroutes-210228                  | httparchive_apiroutes_2021_02_28.txt                  | automated.json |  223544 | 6.5mb    | true   |\n| apiroutes-210328                  | httparchive_apiroutes_2021_03_28.txt                  | automated.json |  215114 | 6.3mb    | false  |\n| aspx-201118                       | httparchive_aspx_asp_cfm_svc_ashx_asmx_2020_11_18.txt | automated.json |   63200 | 1.7mb    | false  |\n| aspx-210128                       | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_01_28.txt | automated.json |   46286 | 928.7kb  | false  |\n| aspx-210228                       | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_02_28.txt | automated.json |   43958 | 883.3kb  | false  |\n| aspx-210328                       | httparchive_aspx_asp_cfm_svc_ashx_asmx_2021_03_28.txt | automated.json |   45928 | 926.8kb  | false  |\n| cgi-201118                        | httparchive_cgi_pl_2020_11_18.txt                     | automated.json |    2637 | 44.0kb   | false  |\n\n\u003cSNIP\u003e\n```\n\n**Usage**\n```\nkr scan targets.txt -A=apiroutes-210228 -x 10 --ignore-length=34\nkr brute targets.txt -A=aspx-210228 -x 10 --ignore-length=34 -easp,aspx\n```\n\n### Head Syntax\n\nWhen using assetnote provided wordlists, you may not want to use the entire wordlist, so you can opt to use the first N lines in a given wordlist using the `head syntax`. The format is `\u003cwordlist_name\u003e:\u003cN lines\u003e` when specifying a wordlist.\n\n**Usage**\n```\n# this will use the first 20000 lines in the api routes wordlist\nkr scan targets.txt -A=apiroutes-210228:20000 -x 10 --ignore-length=34\n\n# this will use the first 10 lines in the aspx wordlist\nkr brute targets.txt -A=aspx-210228:10 -x 10 --ignore-length=34 -easp,aspx\n```\n\n## Concurrency Settings/Going Fast\n\nKiterunner is made to go fast on a lot of hosts. But, just because you can run kiterunner at 20000 goroutines, doesn't mean its a good idea. Bottlenecks and performance degredation will occur at high thread counts due to more time spent scheduling goroutines that are waiting on network IO and kernel context switching.\n\nThere are two main concurrency settings for kiterunner:\n- `-x, --max-connection-per-host` - maximum number of open connections we can have on a host. Governed by 1 goroutine each. To avoid DOS'ing a host, we recommend keeping this in a low realm of 5-10. Depending on latency to the target, this will yield on average between 1-5 requests per second per connection (200ms - 1000ms/req) to a host.\n- `-j, --max-parallel-hosts` - maximum number of hosts to scan at any given time. Governed by 1 goroutine supervisor for each\n\nDepending on the hardware you are scanning from, the \"maximum\" number of goroutines you can run optimally will vary. On an AWS t3.medium, we saw performance degradation going over 2500 goroutines. Meaning, 500 hosts x 5 conn per host (2500) would yield peak performance.\n\nWe recommend **against** running kiterunner from your **macbook**. Due to poor kernel optimisations for high IO counts and Epoll syscalls on macOS, we noticed substantially poorer (0.3-0.5x) performance when compared to running kiterunner on a similarly configured linux instance.\n\nTo maximise performance when scanning an individual target, or a large attack surface we recommend the following tips:\n- Spin up an EC2 instance in a similar geographic region/datacenter to the target(s) you are scanning\n- Perform some initial benchmarks against your target set with varying `-x` and `-j` options. We recommend having a typical starting point of around `-x 5 -j 100` and moving `-j` upwards as your CPU usage/network performance permits\n\n## Converting between file formats\n\nKiterunner will also let you convert between the schema JSON, a kite file and a standard txt wordlist. \n\n**Usage**\n\nThe format is decided by the filetype extension supplied by the `\u003cinput\u003e` and `\u003coutput\u003e` fields. We support `txt`, `json` and `kite`\n```bash\nkr kb convert wordlist.txt wordlist.kite\nkr kb convert wordlist.kite wordlist.json\nkr kb convert wordlist.kite wordlist.txt\n```\n```\n❯ go run ./cmd/kiterunner kb convert -qh\nconvert an input file format into the specified output file format\n\nthis will determine the conversion based on the extensions of the input and the output\nwe support the following filetypes: txt, json, kite\nYou can convert any of the following into the corresponding types\n\n-d Debug mode will attempt to convert the schema with error handling\n-v=debug Debug verbosity will print out the errors for the schema\n\nUsage:\nkite kb convert \u003cinput\u003e \u003coutput\u003e [flags]\n\nFlags:\n-d, --debug   debug the parsing\n-h, --help    help for convert\n\nGlobal Flags:\n--config string    config file (default is $HOME/.kiterunner.yaml)\n-o, --output string    output format. can be json,text,pretty (default \"pretty\")\n-q, --quiet            quiet mode. will mute unecessarry pretty text\n-v, --verbose string   level of logging verbosity. can be error,info,debug,trace (default \"info\")``bigquery\n```\n\n## Replaying requests\n\nWhen you receive a bunch of output from kiterunner, it may be difficult to immediately understand why a request is causing a specific response code/length. Kiterunner offers a method of rebuilding the request from the wordlists used including all the header and body parameters.\n\n- You can replay a request by copy pasting the full response output into the `kb replay` command. \n- You can specify a `--proxy` to forward your requests through, so you can modify/repeat/intercept the request using 3rd party tools if you wish\n- The golang net/http client will perform a few additional changes to your request due to how the default golang spec implementation (unfortunately).\n\n```bash\n❯ go run ./cmd/kiterunner kb replay -q --proxy=http://localhost:8080 -w routes.kite \"POST    403 [    287,   10,   1] https://target.com/dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents 0cc39f76702ea287ec3e93f4b4710db9c8a86251\"\n11:25AM INF Raw reconstructed request\nPOST /dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents?ar_fields=48637466\u0026code=66132381\u0026db_name=08791392\u0026lang=lg-eng\u0026recursive=false\u0026term_id=72336471 HTTP/1.1\nContent-Type: any\n\n\n11:25AM INF Outbound request\nPOST /dedalo/lib/dedalo/publication/server_api/v1/json/thesaurus_parents?ar_fields=48637466\u0026code=66132381\u0026db_name=08791392\u0026lang=lg-eng\u0026recursive=false\u0026term_id=72336471 HTTP/1.1\nHost: target.com\nUser-Agent: Go-http-client/1.1\nContent-Length: 0\nContent-Type: any\nAccept-Encoding: gzip\n\n\n11:25AM INF Response After Redirects\nHTTP/1.1 403 Forbidden\nConnection: close\nContent-Length: 45\nContent-Type: application/json\nDate: Wed, 07 Apr 2021 01:25:28 GMT\nX-Amzn-Requestid: 7e6b2ea1-c662-4671-9eaa-e8cd31b463f2\n\nUser is not authorized to perform this action\n```\n\n# Technical Implementation\n\n## Intermediate Data Type (PRoutes)\n\nWe use an intermediate representation of wordlists and kitebuilder json schemas in kiterunner. This is to allow us to dynamically generate the fields in the wordlist and reconstruct request bodies/headers and query parameters from a given spec.\n\nThe PRoute type is composed of Headers, Body, Query and Cookie parameters that are encoded in `pkg/proute.Crumb`. The Crumb type is an interface that is implemented on types such as UUIDs, Floats, Ints, Random Strings, etc.\n\nWhen performing conversions to and from txt, json and kite files, all the conversions are first done to the `proute.API` intermediate type. Then the corresponding encoding is written out\n\n## Kite File Format\n\nWe use a super secret kite file format for storing the json schemas from kitebuilder. These are simply protobuf encoded `pkg/proute.APIS` written to a file. The compilation is used to allow us to quickly deserialize the already parsed wordlist. This file format is not stable, and should only be interacted with using the inbuilt conversion tools for kiterunner.\n\nWhen a new version of the kite file format is released, you may need to recompile your kite files\n","funding_links":[],"categories":["Go","Tools","Weapons","Recon","BUG BOUNTY / SECURITY RESEARCH"],"sub_categories":["Tools","Content Discovery","API Security Testing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fassetnote%2Fkiterunner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fassetnote%2Fkiterunner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fassetnote%2Fkiterunner/lists"}