{"id":20261345,"url":"https://github.com/parsiya/personal-semgrep-server","last_synced_at":"2025-04-11T01:45:16.751Z","repository":{"id":118394256,"uuid":"544145379","full_name":"parsiya/personal-semgrep-server","owner":"parsiya","description":"Personal Semgrep Server for learning Rust.","archived":false,"fork":false,"pushed_at":"2023-05-03T22:33:18.000Z","size":103,"stargazers_count":8,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T22:51:24.247Z","etag":null,"topics":["rust","semgrep"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/parsiya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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":"2022-10-01T19:07:48.000Z","updated_at":"2025-02-24T21:08:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"87565d33-f0e0-475b-afd3-38aedf382c27","html_url":"https://github.com/parsiya/personal-semgrep-server","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiya%2Fpersonal-semgrep-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiya%2Fpersonal-semgrep-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiya%2Fpersonal-semgrep-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiya%2Fpersonal-semgrep-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parsiya","download_url":"https://codeload.github.com/parsiya/personal-semgrep-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248327863,"owners_count":21085258,"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":["rust","semgrep"],"created_at":"2024-11-14T11:25:20.457Z","updated_at":"2025-04-11T01:45:16.744Z","avatar_url":"https://github.com/parsiya.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Personal Semgrep Server\nI created this personal [Semgrep][sem-url] server to learn Rust. It is suitable\nfor local deployment for folks who cannot use the [Semgrep SaaS App][sem-app]\nbecause of custom Semgrep rules and proprietary code.\n\n1. Unlimited local policies: A policy is a collection of rules.\n2. Serve rules and policies to the Semgrep CLI app over HTTP.\n\n[sem-url]: https://semgrep.dev/\n\nIt was inspired by [wahyuhadi/semgrep-server-rules][go-server].\n\n[go-server]: https://github.com/wahyuhadi/semgrep-server-rules\n\nI will try to keep the `main` branch usable. The `dev` branch is used for\ndevelopment.\n\n## Quickstart\n\n```bash\n$ git clone https://github.com/parsiya/personal-semgrep-server\n$ git submodule update --init --recursive\n$ cargo build\n$ ./target/debug/personal-semgrep-server -r tests/rules/ -p tests/policies/\n# run all rules against your code\n$ semgrep --config http://localhost:9090/c/p/all path/to/code\n```\n\n**Note: Passing a policy path with \"-p\" is optional.** The only mandatory option\nis `-r` that points to the location of the rules. In this case, it will only\nserve individual rules or the `all` policy/rule.\n\n## How to Use\nRun the server like this:\n\n`./personal-semgrep-server -r path/to/rules/ -p path/to/policies/`\n\nThen navigate to http://localhost:9090. The landing page has a link to every\nrule and policy indexed by the server. Clicking on each link will show you the\ncomplete YAML file. This server uses the same path structure as the Semgrep App.\n\n* Policy URL: `/c/p/{policyid}`\n* Rule URL: `/c/r/{ruleid}`\n\nPass these URLs directly to the Semgrep CLI app.\n\n![index](.github/index.png)\n\n## Policies\nPolicies are collections of rules. A local policy is a YAML file like this:\n\n```yaml\nname: policy-name # this should be unique\nrules:\n- ruleID-1\n- ruleID-2\n- arrays-out-of-bounds-access\n- potentially-uninitialized-pointer\n- snprintf-insecure-use\n```\n\nCreate as many as you want. After passing the path to the server, it will search\nfor all `.yaml` and `.yml` files in that path recursively. This allows you to\nstore your policies in subdirectories for better organization:\n\n```\ntests\n└── policies\n     ├── cpp\n     |   ├── cpp-policy1.yaml\n     |   └── cpp-policy2.yaml\n     └── rust\n         ├── rust-policy1.yaml\n         └── rust-policy2.yaml\n```\n\n**Note: Policy names must be unique.** If you have duplicate policy names, one\nwill be overwritten by another.\n\n### The 'all' Policy and Rule\nThe [semgrep-rs][semgrep-rs] library creates a built-in policy and rule named\n`all`, even if you do not pass a policy path. The `all` rule/policy contains\nevery rule indexed by the server. It's useful when you want to run all rules\nagainst a code base.\n**If you have a custom rule or policy named `all`, it will be overwritten.**\n\n[semgrep-rs]: https://github.com/parsiya/semgrep-rs\n\nThe Semgrep CLI app only runs specific rules against a file based on its\nextension so don't shy away from throwing the kitchen sink at your code with\n`all`. See [Language extensions and tags][sem-ext] in the Semgrep documentation.\n\n[sem-ext]: https://semgrep.dev/docs/writing-rules/rule-syntax/#language-extensions-and-tags\n\n## Complete Rule IDs\n**Similar to policy names, rule IDs must also be unique.** The\n[Semgrep SaaS App][sem-app] uses complete rule IDs that are based on the path\nto avoid collisions. To create a complete rule ID, replace the path separator\n(`/` or `\\`) with `.`, then append the rule's internal ID (the value of the `id`\nkey in the rule file).\n\nFor example, the complete rule ID for a rule with `id: double-free` in the\n`rules/c/lang/security/double-free.c` file is:\n`rules.c.lang.security.double-free.double-free`.\n\nMy underlying library [semgrep-rs][complete-id] supports creating complete rule\nIDs, but I have not added it to the current iteration of server because:\n\n1. You have to include the complete rule ID in the policy file.\n2. The rule ID will be dependent on the path passed to the server.\n\nI can change this if we can come up with a solution to get consistent rule IDs\nand a way to write policies automatically.\n\n[complete-id]: https://github.com/parsiya/semgrep-rs#complete-rule-ids\n\n## Security\nlol wut?! Only run it on `localhost` and don't expose this to the internet.\n\n## Why not Use the Semgrep App?\nThe [Semgrep SaaS App][sem-app] is awesome and you should use (and buy it) if\nyou can. But my custom rules and code had to stay local so I had to create a\ndirectory structure for rules to simulate policies.\n\n[sem-app]: https://semgrep.dev/products/semgrep-app\n\nAnother issue was lack of local policies. For example, to run all C++ rules\nagainst a target, your only realistic option is to store all rules in a\ndirectory named `cpp` and pass it to Semgrep CLI with `--config path/to/cpp/`.\n\nIf you want to run a specific set of C++ rules, you can either copy/paste the\nrule files somewhere else or use the `--exclude-rule` command line switch a\nbajillion times. Now if you modify a rule (good idea to keep them in a git\nrepository), you have to manually update all copies\n\nAnother issue is the directory structure of the\n[Semgrep Rules on GitHub][sem-rules-gh]. It doesn't work for me. \n[Audit Shouldn't be Under Security in the Semgrep Rules Repository][sem-audit]\n\nThis server and local policies solve all of these problems for me. I can keep a\nsingle copy of my custom rules in a git repository with the Semgrep Rules\nrepository as a git submodule and have custom policies to mix and match rules.\nThe policies are also in the same repository.\n\n[sem-rules-gh]: https://github.com/returntocorp/semgrep-rules\n[sem-audit]: https://parsiya.net/blog/2022-04-07-code-review-hot-spots-with-semgrep/#audit-shouldnt-be-under-security-in-the-semgrep-rules-repository\n\n## Features\nI like to keep this server as simple as possible. I don't want to create a\nSemgrep App competitor. The only thing I would add is a simple UI similar to the\n[Semgrep Playground][sem-play] to allow people to run it locally for proprietary\nrules/code and maybe some simple commands for filtering rules and creating\npolicies (e.g., create a policy from specific keys in the rules' metadata).\n\n[sem-play]: https://semgrep.dev/playground/\n\n## License\nRust likes dual-licensing so here we go.\n\nLicensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or\n[MIT license](LICENSE-MIT).\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this repository by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsiya%2Fpersonal-semgrep-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparsiya%2Fpersonal-semgrep-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsiya%2Fpersonal-semgrep-server/lists"}