├── site ├── .gitignore ├── content │ ├── _index.md │ ├── blog │ │ └── _index.md │ └── docs │ │ ├── contributing │ │ ├── developer-docs │ │ │ ├── plugin-query-system │ │ │ │ ├── developer_docs_plugin_grpc.png │ │ │ │ └── developer_docs_plugin_sender_receiver.png │ │ │ └── _index.md │ │ ├── intellectual-property.md │ │ ├── describing-changes.md │ │ ├── testing.md │ │ ├── coordinating-changes.md │ │ └── _index.md │ │ ├── guide │ │ ├── plugins │ │ │ ├── mitre-github.md │ │ │ ├── mitre-npm.md │ │ │ ├── mitre-linguist.md │ │ │ ├── mitre-git.md │ │ │ ├── mitre-fuzz.md │ │ │ ├── mitre-activity.md │ │ │ └── mitre-identity.md │ │ ├── cli │ │ │ ├── hc-schema.md │ │ │ ├── hc-setup.md │ │ │ ├── hc-update.md │ │ │ ├── hc-scoring.md │ │ │ ├── hc-explain.md │ │ │ └── hc-ready.md │ │ ├── config │ │ │ └── _index.md │ │ ├── debugging │ │ │ ├── _index.md │ │ │ ├── debugger.md │ │ │ └── starting.md │ │ ├── concepts │ │ │ ├── _index.md │ │ │ ├── data │ │ │ │ └── index.md │ │ │ └── concerns.md │ │ ├── making-plugins │ │ │ └── _index.md │ │ └── _index.md │ │ ├── rfds │ │ ├── _index.md │ │ └── 0010-submit-chunking.md │ │ ├── _index.md │ │ └── getting-started │ │ └── _index.md ├── static │ ├── .well-known │ │ └── atproto-did │ ├── 192.png │ ├── 512.png │ ├── favicon.ico │ ├── apple-touch-icon.png │ ├── assets │ │ └── explainer.pdf │ ├── images │ │ ├── homepage-bg.png │ │ └── authors │ │ │ ├── andrew.jpg │ │ │ └── julian.png │ ├── fonts │ │ └── plex │ │ │ ├── IBMPlexMono-Bold.woff2 │ │ │ └── IBMPlexMono-Text.woff2 │ ├── manifest.webmanifest │ ├── dl │ │ ├── install.ps1 │ │ └── install.sh │ ├── icon.svg │ └── js │ │ └── header.mjs ├── templates │ ├── partials │ │ ├── end.tera.html │ │ ├── prose-config.tera.html │ │ └── head.tera.html │ ├── macros │ │ ├── icon.tera.html │ │ └── breadcrumbs.tera.html │ ├── page.html │ ├── docs_page.html │ ├── docs.html │ ├── section.html │ ├── shortcodes │ │ ├── info.html │ │ ├── warn.html │ │ ├── button.html │ │ ├── waypoint.html │ │ └── install.html │ └── blog_post.html ├── scripts │ ├── src │ │ ├── header │ │ │ ├── theme.ts │ │ │ └── main.ts │ │ ├── util │ │ │ ├── event.ts │ │ │ ├── icon.ts │ │ │ └── web.ts │ │ └── footer │ │ │ ├── theme.ts │ │ │ ├── main.ts │ │ │ ├── scroll.ts │ │ │ └── docs.ts │ ├── deno.json │ └── tasks │ │ └── bundle.ts ├── styles │ └── main.css └── tailwind.config.js ├── .dockerignore ├── sdk ├── python │ ├── .python-version │ ├── src │ │ └── hipcheck_sdk │ │ │ ├── py.typed │ │ │ ├── gen │ │ │ ├── __init__.py │ │ │ └── types.py │ │ │ ├── __init__.py │ │ │ ├── cli.py │ │ │ └── options.py │ ├── docs │ │ ├── source │ │ │ ├── modules.rst │ │ │ ├── index.rst │ │ │ ├── conf.py │ │ │ └── hipcheck_sdk.rst │ │ ├── Makefile │ │ └── make.bat │ ├── tests │ │ ├── context.py │ │ ├── example-plugin │ │ │ └── local-plugin.kdl │ │ └── test_mock_responses.py │ └── pyproject.toml └── rust │ ├── src │ └── types.rs │ ├── Cargo.toml │ └── README.md ├── xtask ├── src │ ├── task │ │ ├── manifest │ │ │ ├── release.rs │ │ │ ├── util │ │ │ │ ├── mod.rs │ │ │ │ ├── redacted.rs │ │ │ │ ├── agent.rs │ │ │ │ └── authenticated_agent.rs │ │ │ └── mod.rs │ │ ├── site.rs │ │ ├── mod.rs │ │ ├── buf.rs │ │ ├── build.rs │ │ ├── check.rs │ │ ├── benchmark │ │ │ └── mod.rs │ │ └── changelog.rs │ ├── string.rs │ └── workspace.rs └── Cargo.toml ├── plugins ├── typo │ ├── src │ │ └── util │ │ │ ├── mod.rs │ │ │ └── fs.rs │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── binary │ ├── src │ │ └── util │ │ │ ├── mod.rs │ │ │ └── fs.rs │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── linguist │ ├── src │ │ └── util │ │ │ ├── mod.rs │ │ │ └── fs.rs │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── affiliation │ ├── src │ │ └── util │ │ │ ├── mod.rs │ │ │ └── fs.rs │ ├── test │ │ └── test_orgs.kdl │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── dist.toml │ └── Cargo.toml ├── npm │ ├── src │ │ └── util │ │ │ ├── mod.rs │ │ │ └── fs.rs │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── github │ ├── src │ │ ├── github │ │ │ ├── rest │ │ │ │ ├── mod.rs │ │ │ │ └── code_search.rs │ │ │ ├── graphql │ │ │ │ ├── custom_scalars.rs │ │ │ │ ├── mod.rs │ │ │ │ └── schemas │ │ │ │ │ └── user_orgs.graphql │ │ │ └── mod.rs │ │ ├── tls │ │ │ ├── mod.rs │ │ │ └── agent.rs │ │ └── cli.rs │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── dist.toml │ └── Cargo.toml ├── git │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── fuzz │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── review │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── activity │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── identity │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── churn │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ ├── dist.toml │ └── src │ │ ├── metric.rs │ │ └── types.rs └── entropy │ ├── plugin.kdl │ ├── local-plugin.kdl │ ├── local-release-plugin.kdl │ ├── Cargo.toml │ └── dist.toml ├── hipcheck ├── src │ ├── explain │ │ └── mod.rs │ ├── cache │ │ └── mod.rs │ ├── util │ │ ├── http │ │ │ ├── mod.rs │ │ │ └── agent.rs │ │ ├── mod.rs │ │ └── test.rs │ ├── shell │ │ ├── macros.rs │ │ ├── color_choice.rs │ │ └── verbosity.rs │ ├── target │ │ └── tests │ │ │ └── package-lock.json │ ├── init │ │ ├── indicatif_log_bridge.rs │ │ ├── git2_log_shim.rs │ │ └── mod.rs │ ├── setup.rs │ └── benchmarking.rs ├── dist.toml └── build.rs ├── tests └── test-plugins │ ├── dummy_sha256 │ ├── schema │ │ └── query_schema_sha256.json │ ├── Cargo.toml │ └── src │ │ └── main.rs │ ├── activity-container │ ├── Containerfile │ ├── local-plugin.kdl │ ├── Cargo.toml │ └── activity-container-deploy.sh │ └── dummy_rand_data │ └── Cargo.toml ├── .buf.yaml ├── .config ├── nextest.toml └── hakari.toml ├── library ├── hipcheck-workspace-hack │ ├── src │ │ └── lib.rs │ ├── build.rs │ └── .gitattributes ├── hipcheck-macros │ ├── README.md │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── hipcheck-kdl │ └── Cargo.toml ├── hipcheck-sdk-macros │ └── Cargo.toml └── hipcheck-common │ ├── build.rs │ ├── Cargo.toml │ └── src │ ├── lib.rs │ └── error.rs ├── config ├── Exec.kdl └── benchmark-targets.kdl ├── .cargo └── config.toml ├── .rustfmt.toml ├── .devcontainer └── devcontainer.json ├── dist ├── dockerhub │ ├── check-description-size.sh │ └── README.md └── Containerfile ├── .github ├── dependabot.yml ├── workflows │ ├── commits.yml │ └── docker.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .gitignore ├── SECURITY.md └── dist-workspace.toml /site/.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .target/ 3 | -------------------------------------------------------------------------------- /sdk/python/.python-version: -------------------------------------------------------------------------------- 1 | 3.10 2 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /site/content/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hipcheck 3 | --- 4 | -------------------------------------------------------------------------------- /site/static/.well-known/atproto-did: -------------------------------------------------------------------------------- 1 | did:plc:3bw6glwbegbtqdgucuvnhapn 2 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/release.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | -------------------------------------------------------------------------------- /site/static/192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/192.png -------------------------------------------------------------------------------- /site/static/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/512.png -------------------------------------------------------------------------------- /plugins/typo/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod fs; 4 | -------------------------------------------------------------------------------- /xtask/src/task/site.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod serve; 4 | -------------------------------------------------------------------------------- /plugins/binary/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod fs; 4 | -------------------------------------------------------------------------------- /plugins/linguist/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod fs; 4 | -------------------------------------------------------------------------------- /site/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/favicon.ico -------------------------------------------------------------------------------- /hipcheck/src/explain/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub(crate) mod semver; 4 | -------------------------------------------------------------------------------- /plugins/affiliation/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod fs; 4 | -------------------------------------------------------------------------------- /tests/test-plugins/dummy_sha256/schema/query_schema_sha256.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "integer" 3 | } 4 | -------------------------------------------------------------------------------- /.buf.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | lint: 3 | use: 4 | - STANDARD 5 | rpc_allow_same_request_response: true 6 | -------------------------------------------------------------------------------- /hipcheck/src/cache/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod plugin; 4 | pub mod repo; 5 | -------------------------------------------------------------------------------- /plugins/npm/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod command; 4 | pub mod fs; 5 | -------------------------------------------------------------------------------- /.config/nextest.toml: -------------------------------------------------------------------------------- 1 | [profile.ci] 2 | # Do not cancel the test run on the first failure. 3 | fail-fast = false 4 | -------------------------------------------------------------------------------- /site/static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/apple-touch-icon.png -------------------------------------------------------------------------------- /site/static/assets/explainer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/assets/explainer.pdf -------------------------------------------------------------------------------- /site/static/images/homepage-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/images/homepage-bg.png -------------------------------------------------------------------------------- /library/hipcheck-workspace-hack/src/lib.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // This is a stub lib.rs. 4 | -------------------------------------------------------------------------------- /site/static/images/authors/andrew.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/images/authors/andrew.jpg -------------------------------------------------------------------------------- /site/static/images/authors/julian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/images/authors/julian.png -------------------------------------------------------------------------------- /sdk/python/docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | hipcheck_sdk 2 | ============ 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | hipcheck_sdk 8 | -------------------------------------------------------------------------------- /site/content/blog/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Blog 3 | sort_by: date 4 | template: blog.html 5 | page_template: blog_post.html 6 | --- 7 | -------------------------------------------------------------------------------- /site/static/fonts/plex/IBMPlexMono-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/fonts/plex/IBMPlexMono-Bold.woff2 -------------------------------------------------------------------------------- /site/static/fonts/plex/IBMPlexMono-Text.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/static/fonts/plex/IBMPlexMono-Text.woff2 -------------------------------------------------------------------------------- /hipcheck/src/util/http/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Methods and types for making HTTP requests 4 | 5 | pub mod agent; 6 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod agent; 4 | pub mod authenticated_agent; 5 | pub mod redacted; 6 | -------------------------------------------------------------------------------- /plugins/github/src/github/rest/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Logic for interacting with the GitHub REST API. 4 | 5 | pub mod code_search; 6 | -------------------------------------------------------------------------------- /config/Exec.kdl: -------------------------------------------------------------------------------- 1 | plugin { 2 | backoff-interval 100000 3 | max-spawn-attempts 3 4 | max-conn-attempts 5 5 | jitter-percent 10 6 | grpc-msg-buffer-size 10 7 | } 8 | -------------------------------------------------------------------------------- /library/hipcheck-workspace-hack/build.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // A build script is required for cargo to consider build dependencies. 4 | fn main() {} 5 | -------------------------------------------------------------------------------- /plugins/github/src/tls/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Agents for establishing TLS connections to GitHub. 4 | 5 | pub mod agent; 6 | pub mod authenticated_agent; 7 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [alias] 2 | xtask = "run --package xtask --bin xtask --" 3 | 4 | [build] 5 | incremental = true 6 | 7 | [target.x86_64-unknown-linux-gnu] 8 | rustflags = ["-C", "link-arg=-fuse-ld=mold"] 9 | -------------------------------------------------------------------------------- /site/static/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "icons": [ 3 | { "src": "/192.png", "type": "image/png", "sizes": "192x192" }, 4 | { "src": "/512.png", "type": "image/png", "sizes": "512x512" } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /site/templates/partials/end.tera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/content/docs/contributing/developer-docs/plugin-query-system/developer_docs_plugin_grpc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/content/docs/contributing/developer-docs/plugin-query-system/developer_docs_plugin_grpc.png -------------------------------------------------------------------------------- /site/scripts/src/header/theme.ts: -------------------------------------------------------------------------------- 1 | import { getConfiguredTheme, setPageTheme } from "../util/theme.ts"; 2 | 3 | /** 4 | * Sets up the logic for updating theme pre-load. 5 | */ 6 | export function setupTheme() { 7 | setPageTheme(getConfiguredTheme()); 8 | } 9 | -------------------------------------------------------------------------------- /site/content/docs/contributing/developer-docs/plugin-query-system/developer_docs_plugin_sender_receiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitre/hipcheck/HEAD/site/content/docs/contributing/developer-docs/plugin-query-system/developer_docs_plugin_sender_receiver.png -------------------------------------------------------------------------------- /hipcheck/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Utility methods and types used throughout Hipcheck. 4 | 5 | pub mod command; 6 | pub mod fs; 7 | pub mod git; 8 | pub mod http; 9 | pub mod npm; 10 | #[cfg(test)] 11 | pub mod test; 12 | -------------------------------------------------------------------------------- /site/templates/macros/icon.tera.html: -------------------------------------------------------------------------------- 1 | {% macro icon(name, classes="") %} 2 | 3 | 4 | 5 | {% endmacro icon %} 6 | -------------------------------------------------------------------------------- /library/hipcheck-workspace-hack/.gitattributes: -------------------------------------------------------------------------------- 1 | # Avoid putting conflict markers in the generated Cargo.toml file, since their presence breaks 2 | # Cargo. 3 | # Also do not check out the file as CRLF on Windows, as that's what hakari needs. 4 | Cargo.toml merge=binary -crlf 5 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/gen/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | import os 4 | import sys 5 | dir_path = os.path.dirname(os.path.realpath(__file__)) 6 | sys.path.append(dir_path) 7 | 8 | from hipcheck_pb2 import * 9 | from hipcheck_pb2_grpc import * 10 | -------------------------------------------------------------------------------- /plugins/github/src/github/graphql/custom_scalars.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Helper types used for GraphQL derives. 4 | //! 5 | //! These map scalar types from `types.graphql` to Rust types. 6 | 7 | #[allow(clippy::upper_case_acronyms)] 8 | pub type URI = url::Url; 9 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-github.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/github" 3 | extra: 4 | nav_title: "mitre/github" 5 | --- 6 | 7 | # `mitre/github` 8 | 9 | Provides access to GitHub data. Does not define a default query and can't be 10 | used as a top-level plugin in a policy file. 11 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-npm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/npm" 3 | extra: 4 | nav_title: "mitre/npm" 5 | --- 6 | 7 | # `mitre/npm` 8 | 9 | Provides access to NPM data for a package. Does not provide a default query 10 | and can't be used as a top-level plugin in a policy file. 11 | -------------------------------------------------------------------------------- /site/static/dl/install.ps1: -------------------------------------------------------------------------------- 1 | 2 | # This installer delegates to the "real" installer included with each new 3 | # release of Hipcheck. 4 | 5 | $hc_version = "3.14.0" 6 | $installer = "https://github.com/mitre/hipcheck/releases/download/hipcheck-v${hc_version}/hipcheck-installer.ps1" 7 | 8 | irm "$installer" | iex 9 | -------------------------------------------------------------------------------- /xtask/src/task/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Commands supported by 'xtask' 4 | 5 | pub mod benchmark; 6 | pub mod buf; 7 | pub mod build; 8 | pub mod changelog; 9 | pub mod check; 10 | pub mod ci; 11 | pub mod manifest; 12 | pub mod rfd; 13 | pub mod site; 14 | pub mod validate; 15 | -------------------------------------------------------------------------------- /plugins/git/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "git" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "git" 8 | on arch="x86_64-apple-darwin" "git" 9 | on arch="x86_64-unknown-linux-gnu" "git" 10 | on arch="x86_64-pc-windows-msvc" "git.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/npm/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "npm" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "npm" 8 | on arch="x86_64-apple-darwin" "npm" 9 | on arch="x86_64-unknown-linux-gnu" "npm" 10 | on arch="x86_64-pc-windows-msvc" "npm.exe" 11 | } 12 | -------------------------------------------------------------------------------- /site/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "bases/base.tera.html" %} 2 | 3 | {% block title %} 4 | {% if page.title %} 5 | {{ page.title }} 6 | {% else %} 7 | Hipcheck 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content %} 12 | {{ page.content | safe }} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /xtask/src/string.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use itertools::Itertools as _; 4 | 5 | /// List a bunch of strings together separated by commas. 6 | pub fn list_with_commas(list: impl IntoIterator) -> String { 7 | list.into_iter().map(|elem| elem.to_string()).join(", ") 8 | } 9 | -------------------------------------------------------------------------------- /tests/test-plugins/activity-container/Containerfile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | FROM debian:bookworm-slim 4 | 5 | WORKDIR /app 6 | 7 | COPY ../../target/debug/activity /app/activity 8 | 9 | RUN chmod +x /app/activity 10 | 11 | EXPOSE 50051 12 | 13 | ENTRYPOINT ["/app/activity", "--port", "50051"] 14 | -------------------------------------------------------------------------------- /plugins/binary/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "binary" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "binary" 8 | on arch="x86_64-apple-darwin" "binary" 9 | on arch="x86_64-unknown-linux-gnu" "binary" 10 | on arch="x86_64-pc-windows-msvc" "binary.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/github/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "github" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "github" 8 | on arch="x86_64-apple-darwin" "github" 9 | on arch="x86_64-unknown-linux-gnu" "github" 10 | on arch="x86_64-pc-windows-msvc" "github.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/github/src/github/graphql/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Logic for interacting with the GitHub GraphQL API. 4 | 5 | mod custom_scalars; 6 | pub mod reviews; 7 | pub mod user_orgs; 8 | 9 | /// The URL of the GitHub GraphQL API. 10 | pub const GH_API_V4: &str = "https://api.github.com/graphql"; 11 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-linguist.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/linguist" 3 | extra: 4 | nav_title: "mitre/linguist" 5 | --- 6 | 7 | # `mitre/linguist` 8 | 9 | Analyzes text files to identify their likely language. Does not provide a 10 | default query and can't be used as a top-level plugin in a policy file. 11 | -------------------------------------------------------------------------------- /plugins/linguist/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "linguist" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "linguist" 8 | on arch="x86_64-apple-darwin" "linguist" 9 | on arch="x86_64-unknown-linux-gnu" "linguist" 10 | on arch="x86_64-pc-windows-msvc" "linguist.exe" 11 | } 12 | -------------------------------------------------------------------------------- /library/hipcheck-macros/README.md: -------------------------------------------------------------------------------- 1 | 2 | # `hipcheck-macros` 3 | 4 | `hipcheck-macros` is a helper crate for [Hipcheck] which provides procedural 5 | macros. It's not intended for use by anyone else, and generally involves 6 | private APIs. 7 | 8 | ## License 9 | 10 | `hipcheck-macros` is Apache-2.0 licensed. 11 | 12 | [Hipcheck]: https://github.com/mitre/hipcheck 13 | -------------------------------------------------------------------------------- /plugins/git/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "git" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/git" 8 | on arch="x86_64-apple-darwin" "./target/debug/git" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/git" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/git.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/npm/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "npm" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/npm" 8 | on arch="x86_64-apple-darwin" "./target/debug/npm" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/npm" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/npm.exe" 11 | } 12 | -------------------------------------------------------------------------------- /site/scripts/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "tasks": { 3 | "bundle": "deno run -A tasks/bundle.ts", 4 | "dev": "deno run -A --watch tasks/bundle.ts" 5 | }, 6 | "imports": { 7 | "@luca/esbuild-deno-loader": "jsr:@luca/esbuild-deno-loader@^0.11.0", 8 | "esbuild": "npm:esbuild@^0.24.0" 9 | }, 10 | "compilerOptions": { 11 | "lib": ["deno.window", "dom"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugins/git/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "git" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/git" 8 | on arch="x86_64-apple-darwin" "./target/release/git" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/git" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/git.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/npm/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "npm" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/npm" 8 | on arch="x86_64-apple-darwin" "./target/release/npm" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/npm" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/npm.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/binary/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "binary" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/binary" 8 | on arch="x86_64-apple-darwin" "./target/debug/binary" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/binary" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/binary.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/github/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "github" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/github" 8 | on arch="x86_64-apple-darwin" "./target/debug/github" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/github" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/github.exe" 11 | } 12 | -------------------------------------------------------------------------------- /library/hipcheck-kdl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hipcheck-kdl" 3 | description = "Common KDL functionality used throughout the Hipcheck project" 4 | repository = "https://github.com/mitre/hipcheck" 5 | version = "0.1.0" 6 | license = "Apache-2.0" 7 | edition = "2024" 8 | publish = false 9 | 10 | [dependencies] 11 | kdl = { workspace = true } 12 | hipcheck-workspace-hack = { workspace = true } 13 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | from hipcheck_sdk.options import * 4 | 5 | from hipcheck_sdk.engine import PluginEngine, MockResponses 6 | from hipcheck_sdk.server import Plugin, PluginServer 7 | from hipcheck_sdk.query import query, Endpoint 8 | from hipcheck_sdk.cli import get_parser_for, run_server_for 9 | from hipcheck_sdk.gen.types import * 10 | -------------------------------------------------------------------------------- /xtask/src/workspace.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::{Result, anyhow}; 4 | use std::path::{Path, PathBuf}; 5 | 6 | /// Get the root directory of the workspace. 7 | pub fn root() -> Result { 8 | Path::new(&env!("CARGO_MANIFEST_DIR")) 9 | .ancestors() 10 | .nth(1) 11 | .ok_or_else(|| anyhow!("can't find cargo root")) 12 | .map(Path::to_path_buf) 13 | } 14 | -------------------------------------------------------------------------------- /plugins/linguist/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "linguist" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/linguist" 8 | on arch="x86_64-apple-darwin" "./target/debug/linguist" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/linguist" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/linguist.exe" 11 | } 12 | -------------------------------------------------------------------------------- /site/scripts/src/header/main.ts: -------------------------------------------------------------------------------- 1 | import { setupTheme } from "./theme.ts"; 2 | 3 | /** 4 | * Run all page setup operations, initializing all interactive widgets. 5 | */ 6 | function setup() { 7 | setupTheme(); 8 | } 9 | 10 | /** 11 | * Do setup, logging errors to the console. 12 | */ 13 | (function () { 14 | try { 15 | setup(); 16 | } catch (e) { 17 | console.error(e); 18 | } 19 | })(); 20 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Hard tabs are better than spaces for code accessibility. For example. 2 | # someone who needs to use a large font size may prefer to set tab width 3 | # to a smaller number to avoid too much rightward drift in the display 4 | # of the code. Using tabs for indenting and spaces for alignment will 5 | # make it easier for people to access and contribute to the Hipcheck 6 | # source code. 7 | hard_tabs = true 8 | -------------------------------------------------------------------------------- /plugins/binary/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "binary" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/binary" 8 | on arch="x86_64-apple-darwin" "./target/release/binary" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/binary" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/binary.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/github/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "github" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/github" 8 | on arch="x86_64-apple-darwin" "./target/release/github" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/github" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/github.exe" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/affiliation/test/test_orgs.kdl: -------------------------------------------------------------------------------- 1 | strategy "independent" { 2 | country "United States" 3 | org "MITRE" 4 | } 5 | orgs { 6 | org "HP" country="United States" { 7 | host "hp.com" 8 | host "hpe.com" 9 | } 10 | org "MITRE" country="United States" { 11 | host "mitre.org" 12 | } 13 | org "RBC Royal Bank" country="Canada" { 14 | host "rbcon.com" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugins/linguist/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "linguist" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/linguist" 8 | on arch="x86_64-apple-darwin" "./target/release/linguist" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/linguist" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/linguist.exe" 11 | } 12 | -------------------------------------------------------------------------------- /site/templates/docs_page.html: -------------------------------------------------------------------------------- 1 | {% extends "bases/docs.tera.html" %} 2 | 3 | {% block title %} 4 | {% if page.title %} 5 | {{ page.title }} 6 | {% else %} 7 | Hipcheck 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content %} 12 | {{ page.content | safe }} 13 | {% endblock %} 14 | 15 | {% block sidebar %} 16 | {{ toc::toc(content=page.toc, is_doc=true) }} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /site/templates/docs.html: -------------------------------------------------------------------------------- 1 | {% extends "bases/docs.tera.html" %} 2 | 3 | {% block title %} 4 | {% if section.title %} 5 | {{ section.title }} 6 | {% else %} 7 | Hipcheck 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block content %} 12 | {{ section.content | safe }} 13 | {% endblock %} 14 | 15 | {% block sidebar %} 16 | {{ toc::toc(content=section.toc, is_doc=true) }} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hipcheck-dev-container", 3 | "image": "mcr.microsoft.com/devcontainers/universal:2-linux", 4 | "features": { 5 | "ghcr.io/devcontainers/features/rust:1": { 6 | "profile": "default" 7 | }, 8 | "ghcr.io/devcontainers/features/node:1": {} 9 | }, 10 | "postCreateCommand": { 11 | "openssl": "sudo apt-get install libssl-dev protobuf-compiler mold" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-plugins/dummy_sha256/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dummy_sha256" 3 | version = "0.1.0" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | clap = { workspace = true, features = ["derive"] } 10 | hipcheck-sdk = { workspace = true, features = ["macros"] } 11 | sha2 = { workspace = true } 12 | tokio = { workspace = true, features = ["rt"] } 13 | hipcheck-workspace-hack = { workspace = true } 14 | -------------------------------------------------------------------------------- /plugins/typo/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "typo" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "typo" 8 | on arch="x86_64-apple-darwin" "typo" 9 | on arch="x86_64-unknown-linux-gnu" "typo" 10 | on arch="x86_64-pc-windows-msvc" "typo.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/npm" version="^0.4" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/npm.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/fuzz/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "fuzz" 3 | version "0.3.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "fuzz" 8 | on arch="x86_64-apple-darwin" "fuzz" 9 | on arch="x86_64-unknown-linux-gnu" "fuzz" 10 | on arch="x86_64-pc-windows-msvc" "fuzz.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="^0.4" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/github.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /site/templates/section.html: -------------------------------------------------------------------------------- 1 | {% extends "bases/base.tera.html" %} 2 | 3 | {% block title %} 4 | {% if section.title %} 5 | {{ section.title }} 6 | {% else %} 7 | Hipcheck 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block sidebar %} 12 | {% set content = section.toc %} 13 | {{ toc::toc(content=content) }} 14 | {% endblock %} 15 | 16 | {% block content %} 17 | {{ section.content | safe }} 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /site/templates/shortcodes/info.html: -------------------------------------------------------------------------------- 1 | 2 | {% import "macros/icon.tera.html" as ic %} 3 | 4 |
5 | {% if title %}{{ title }}{% else %}Info{% endif %} 6 |
7 | {{ body | markdown | safe }} 8 |
9 |
10 | -------------------------------------------------------------------------------- /plugins/review/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "review" 3 | version "0.4.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "review" 8 | on arch="x86_64-apple-darwin" "review" 9 | on arch="x86_64-unknown-linux-gnu" "review" 10 | on arch="x86_64-pc-windows-msvc" "review.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="^0.4" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/github.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /library/hipcheck-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hipcheck-macros" 3 | description = "Helper macros for the `hipcheck` crate." 4 | repository = "https://github.com/mitre/hipcheck" 5 | version = "0.3.5" 6 | edition = "2024" 7 | license = "Apache-2.0" 8 | 9 | [lib] 10 | proc-macro = true 11 | 12 | [dependencies] 13 | proc-macro2 = { workspace = true } 14 | quote = { workspace = true } 15 | syn = { workspace = true } 16 | hipcheck-workspace-hack = { workspace = true } 17 | -------------------------------------------------------------------------------- /plugins/activity/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "activity" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "activity" 8 | on arch="x86_64-apple-darwin" "activity" 9 | on arch="x86_64-unknown-linux-gnu" "activity" 10 | on arch="x86_64-pc-windows-msvc" "activity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="^0.5" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /sdk/rust/src/types.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | typify_macro::import_types!( 4 | schema = "../schema/hipcheck_target_schema.json", 5 | derives = [schemars::JsonSchema], 6 | convert = { 7 | { 8 | type = "string", 9 | format = "uri", 10 | } = url::Url, 11 | { 12 | type = "string", 13 | format = "date-time" 14 | } = jiff::Zoned, 15 | { 16 | type = "string", 17 | format = "duration" 18 | } = jiff::Span, 19 | } 20 | ); 21 | -------------------------------------------------------------------------------- /site/templates/shortcodes/warn.html: -------------------------------------------------------------------------------- 1 | 2 | {% import "macros/icon.tera.html" as ic %} 3 | 4 |
5 | {% if title %}{{ title }}{% else %}Info{% endif %} 6 |
7 | {{ body | markdown | safe }} 8 |
9 |
10 | -------------------------------------------------------------------------------- /plugins/identity/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "identity" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "identity" 8 | on arch="x86_64-apple-darwin" "identity" 9 | on arch="x86_64-unknown-linux-gnu" "identity" 10 | on arch="x86_64-pc-windows-msvc" "identity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="^0.5" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/affiliation/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "affiliation" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "affiliation" 8 | on arch="x86_64-apple-darwin" "affiliation" 9 | on arch="x86_64-unknown-linux-gnu" "affiliation" 10 | on arch="x86_64-pc-windows-msvc" "affiliation.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="^0.5" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/typo/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "typo" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/typo" 8 | on arch="x86_64-apple-darwin" "./target/debug/typo" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/typo" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/typo.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/npm" version="0.0.0" manifest="./plugins/npm/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /tests/test-plugins/activity-container/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "activity-container" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "activity-container-deploy.sh" 8 | on arch="x86_64-apple-darwin" "activity-container-deploy.sh" 9 | on arch="x86_64-unknown-linux-gnu" "activity-container-deploy.sh" 10 | } 11 | 12 | dependencies { 13 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 14 | } 15 | -------------------------------------------------------------------------------- /plugins/fuzz/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "fuzz" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/fuzz" 8 | on arch="x86_64-apple-darwin" "./target/debug/fuzz" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/fuzz" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/fuzz.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="0.0.0" manifest="./plugins/github/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/review/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "review" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/review" 8 | on arch="x86_64-apple-darwin" "./target/debug/review" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/review" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/review.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="0.0.0" manifest="./plugins/github/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /sdk/python/tests/context.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | from pytest import fixture 4 | 5 | from hipcheck_sdk import * 6 | 7 | 8 | @fixture 9 | def options_disable_rfd9_compat(): 10 | opts_before = get_options() 11 | set_option("rfd9_compat", False) 12 | yield 13 | set_options(opts_before) 14 | 15 | 16 | @fixture 17 | def options_enable_rfd9_compat(): 18 | opts_before = get_options() 19 | set_option("rfd9_compat", True) 20 | yield 21 | set_options(opts_before) 22 | -------------------------------------------------------------------------------- /config/benchmark-targets.kdl: -------------------------------------------------------------------------------- 1 | targets { 2 | // NOTE: the parser of this file expects the following order repo url=<> ref=<> type=<> 3 | // git repository with about 700 commits 4 | repo url="https://github.com/mitre/hipcheck" ref="hipcheck-v3.11.0" type="repo" 5 | // popular Python repo with approximately 3000 commits 6 | repo url="jinja2" ref="3.1.6" type="pypi" 7 | // popular NPM package with approximately 6000 commits as of v5.0.0 8 | repo url="express" ref="v5.0.0" type="npm" 9 | } 10 | 11 | -------------------------------------------------------------------------------- /plugins/activity/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "activity" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/activity" 8 | on arch="x86_64-apple-darwin" "./target/debug/activity" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/activity" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/activity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/typo/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "typo" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/typo" 8 | on arch="x86_64-apple-darwin" "./target/release/typo" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/typo" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/typo.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/npm" version="0.0.0" manifest="./plugins/npm/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /sdk/python/docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. hipcheck-sdk documentation master file, created by 2 | sphinx-quickstart on Fri Mar 21 16:01:33 2025. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | hipcheck-sdk documentation 7 | ========================== 8 | 9 | API documentation for the `Hipcheck `_ plugin SDK. 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Contents: 14 | 15 | hipcheck_sdk 16 | -------------------------------------------------------------------------------- /site/scripts/src/util/event.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Debounce an event handler by waiting `waitFor` number of milliseconds before 3 | * permitting the event to be triggered again. 4 | */ 5 | export function debounce) => ReturnType>( 6 | waitFor: number, 7 | func: F, 8 | ): (...args: Parameters) => void { 9 | let timeout: number; 10 | return (...args: Parameters): void => { 11 | clearTimeout(timeout); 12 | timeout = setTimeout(() => func(...args), waitFor); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /site/templates/shortcodes/button.html: -------------------------------------------------------------------------------- 1 | {% if link is starting_with("http") %} 2 | {% set link = link %} 3 | {% else %} 4 | {% set link = get_url(path=link) %} 5 | {% endif %} 6 | 7 | 20 | {{ text }} → 21 | 22 | -------------------------------------------------------------------------------- /plugins/fuzz/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "fuzz" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/fuzz" 8 | on arch="x86_64-apple-darwin" "./target/release/fuzz" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/fuzz" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/fuzz.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="0.0.0" manifest="./plugins/github/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/identity/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "identity" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/identity" 8 | on arch="x86_64-apple-darwin" "./target/debug/identity" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/identity" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/identity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /tests/test-plugins/dummy_rand_data/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dummy_rand_data" 3 | version = "0.1.0" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | clap = { workspace = true, features = ["derive"] } 10 | hipcheck-sdk = { workspace = true, features = ["macros"] } 11 | tokio = { workspace = true, features = ["rt"] } 12 | hipcheck-workspace-hack = { workspace = true } 13 | 14 | [dev-dependencies] 15 | hipcheck-sdk = { workspace = true, features = ["macros", "mock_engine"] } 16 | -------------------------------------------------------------------------------- /dist/dockerhub/check-description-size.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | FILE_PATH="./dist/dockerhub/README.md" 6 | MAX_SIZE=25000 7 | 8 | if [ ! -f "$FILE_PATH" ]; then 9 | echo "File does not exist: $FILE_PATH" 10 | exit 1 11 | fi 12 | 13 | FILE_SIZE=$(wc -c < $FILE_PATH) 14 | 15 | if [ "$FILE_SIZE" -ge $MAX_SIZE ]; then 16 | echo "File is too large: $FILE_SIZE bytes (MAX allowed is $MAX_SIZE)" 17 | exit 1 18 | fi 19 | 20 | echo "File is small enough to push: $FILE_SIZE (MAX allowed is $MAX_SIZE)" 21 | -------------------------------------------------------------------------------- /plugins/affiliation/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "affiliation" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/affiliation" 8 | on arch="x86_64-apple-darwin" "./target/debug/affiliation" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/affiliation" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/affiliation.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/review/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "review" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/review" 8 | on arch="x86_64-apple-darwin" "./target/release/review" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/review" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/review.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/github" version="0.0.0" manifest="./plugins/github/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/activity/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "activity" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/activity" 8 | on arch="x86_64-apple-darwin" "./target/release/activity" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/activity" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/activity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/identity/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "identity" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/identity" 8 | on arch="x86_64-apple-darwin" "./target/release/identity" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/identity" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/identity.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-git.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/git" 3 | extra: 4 | nav_title: "mitre/git" 5 | --- 6 | 7 | # `mitre/git` 8 | 9 | Provides access to Git commit history data. Does not define a default query 10 | and can't be used as a top-level plugin in a policy file. 11 | 12 | ## Configuration 13 | 14 | | Parameter | Type | Explanation | 15 | |:--------------------|:--------|:--------------| 16 | | `commit-cache-size` | `Integer` | Optional number of repositories to retain in cache. Defaults to one. | 17 | -------------------------------------------------------------------------------- /site/static/dl/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # This installer delegates to the "real" installer included with each new 4 | # release of Hipcheck. 5 | 6 | HC_VERSION="3.14.0" 7 | REPO="https://github.com/mitre/hipcheck" 8 | INSTALLER="$REPO/releases/download/hipcheck-v$HC_VERSION/hipcheck-installer.sh" 9 | 10 | # Check that curl is installed and error out if it isn't. 11 | if ! command -v curl >/dev/null; then 12 | echo "error: 'curl' is required to run the installer" 1>&2 13 | exit 1 14 | fi 15 | 16 | curl -LsSf "$INSTALLER" | sh "$@" 17 | -------------------------------------------------------------------------------- /plugins/affiliation/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "affiliation" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/affiliation" 8 | on arch="x86_64-apple-darwin" "./target/release/affiliation" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/affiliation" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/affiliation.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-release-plugin.kdl" 15 | } 16 | -------------------------------------------------------------------------------- /plugins/github/src/cli.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::Result; 4 | use clap::Parser; 5 | use hipcheck_sdk::LogLevel; 6 | 7 | #[derive(Parser, Debug)] 8 | pub struct Cli { 9 | #[arg(long)] 10 | pub port: u16, 11 | 12 | #[arg(long, default_value_t=LogLevel::Error)] 13 | pub log_level: LogLevel, 14 | 15 | #[arg(trailing_var_arg(true), allow_hyphen_values(true), hide = true)] 16 | pub unknown_args: Vec, 17 | } 18 | 19 | impl Cli { 20 | pub fn parse_args() -> Result { 21 | Ok(Self::try_parse()?) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugins/churn/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "churn" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "churn" 8 | on arch="x86_64-apple-darwin" "churn" 9 | on arch="x86_64-unknown-linux-gnu" "churn" 10 | on arch="x86_64-pc-windows-msvc" "churn.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="^0.5" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl" 15 | plugin "mitre/linguist" version="^0.4" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/linguist.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /site/content/docs/contributing/intellectual-property.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Intellectual Property 3 | weight: 3 4 | --- 5 | 6 | # Intellectual Property 7 | 8 | When you make contributions to Hipcheck, they're done under the terms 9 | of the Apache 2.0 license. 10 | 11 | Apache 2.0 is approved by the Open Source Initiative (OSI) as an 12 | open source license, meeting the Open Source Definition. 13 | 14 | ChooseALicense.com, a project by GitHub, has a layperson's [breakdown of the 15 | terms of the Apache 2.0 license](https://choosealicense.com/licenses/apache-2.0/). 16 | -------------------------------------------------------------------------------- /plugins/entropy/plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "entropy" 3 | version "0.5.2" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "entropy" 8 | on arch="x86_64-apple-darwin" "entropy" 9 | on arch="x86_64-unknown-linux-gnu" "entropy" 10 | on arch="x86_64-pc-windows-msvc" "entropy.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="^0.5" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/git.kdl" 15 | plugin "mitre/linguist" version="^0.4" manifest="https://hipcheck.mitre.org/dl/plugin/mitre/linguist.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /library/hipcheck-sdk-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hipcheck-sdk-macros" 3 | description = "Helper macros for the `hipcheck-sdk` crate." 4 | repository = "https://github.com/mitre/hipcheck" 5 | version = "0.2.1" 6 | edition = "2024" 7 | license = "Apache-2.0" 8 | 9 | [lib] 10 | proc-macro = true 11 | 12 | [dependencies] 13 | convert_case = { workspace = true } 14 | tracing = { workspace = true } 15 | proc-macro2 = { workspace = true } 16 | quote = { workspace = true } 17 | syn = { workspace = true, features = ["full", "printing"] } 18 | hipcheck-workspace-hack = { workspace = true } 19 | -------------------------------------------------------------------------------- /plugins/churn/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "churn" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/churn" 8 | on arch="x86_64-apple-darwin" "./target/debug/churn" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/churn" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/churn.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 15 | plugin "mitre/linguist" version="0.0.0" manifest="./plugins/linguist/local-plugin.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /site/content/docs/rfds/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Requests for Discussion 3 | sort_by: weight 4 | template: rfds.html 5 | page_template: docs_page.html 6 | weight: 5 7 | aliases: 8 | - "/rfds/_index.md" 9 | --- 10 | 11 | # RFDs 12 | 13 | RFDs are Hipcheck's mechanism for managing major changes to the tool. 14 | The motivation and details of the process are described in [RFD #0, 15 | "The RFD Process."](@/docs/rfds/0000-rfds.md) 16 | 17 | Anyone can submit an RFD! If you're interested in contributing to Hipcheck's 18 | design, take a look at the [Contribution Guide](@/docs/contributing/_index.md). 19 | -------------------------------------------------------------------------------- /plugins/entropy/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "entropy" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/debug/entropy" 8 | on arch="x86_64-apple-darwin" "./target/debug/entropy" 9 | on arch="x86_64-unknown-linux-gnu" "./target/debug/entropy" 10 | on arch="x86_64-pc-windows-msvc" "./target/debug/entropy.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-plugin.kdl" 15 | plugin "mitre/linguist" version="0.0.0" manifest="./plugins/linguist/local-plugin.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /sdk/python/tests/example-plugin/local-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "example" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "uv run --project sdk/python sdk/python/tests/example-plugin/test_main.py" 8 | on arch="x86_64-apple-darwin" "uv run --project sdk/python sdk/python/tests/example-plugin/test_main.py" 9 | on arch="x86_64-unknown-linux-gnu" "uv run --project sdk/python sdk/python/tests/example-plugin/test_main.py" 10 | on arch="x86_64-pc-windows-msvc" "uv run --project sdk/python sdk/python/tests/example-plugin/test_main.py" 11 | } 12 | -------------------------------------------------------------------------------- /plugins/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fuzz" 3 | version = "0.3.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | hipcheck-sdk = { workspace = true, features = ["macros"] } 12 | serde_json = { workspace = true } 13 | tracing = { workspace = true } 14 | tokio = { workspace = true, features = ["rt"] } 15 | hipcheck-workspace-hack = { workspace = true } 16 | 17 | [dev-dependencies] 18 | hipcheck-sdk = { workspace = true, features = ["macros", "mock_engine"] } 19 | -------------------------------------------------------------------------------- /hipcheck/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # The installers to generate for each app 9 | installers = ["shell", "powershell"] 10 | 11 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 12 | # compiler present on their platform. 13 | 14 | [dist.dependencies.apt] 15 | protobuf-compiler = "*" 16 | mold = "*" 17 | 18 | [dist.dependencies.homebrew] 19 | protobuf = "*" 20 | 21 | [dist.dependencies.chocolatey] 22 | protoc = "*" 23 | -------------------------------------------------------------------------------- /plugins/churn/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "churn" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/churn" 8 | on arch="x86_64-apple-darwin" "./target/release/churn" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/churn" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/churn.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-release-plugin.kdl" 15 | plugin "mitre/linguist" version="0.0.0" manifest="./plugins/linguist/local-release-plugin.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "cargo" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | cooldown: 13 | default-days: 7 14 | exclude-paths: 15 | - "library/hipcheck-workspace-hack/" 16 | -------------------------------------------------------------------------------- /plugins/entropy/local-release-plugin.kdl: -------------------------------------------------------------------------------- 1 | publisher "mitre" 2 | name "entropy" 3 | version "0.0.0" 4 | license "Apache-2.0" 5 | 6 | entrypoint { 7 | on arch="aarch64-apple-darwin" "./target/release/entropy" 8 | on arch="x86_64-apple-darwin" "./target/release/entropy" 9 | on arch="x86_64-unknown-linux-gnu" "./target/release/entropy" 10 | on arch="x86_64-pc-windows-msvc" "./target/release/entropy.exe" 11 | } 12 | 13 | dependencies { 14 | plugin "mitre/git" version="0.0.0" manifest="./plugins/git/local-release-plugin.kdl" 15 | plugin "mitre/linguist" version="0.0.0" manifest="./plugins/linguist/local-release-plugin.kdl" 16 | } 17 | -------------------------------------------------------------------------------- /site/styles/main.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @font-face { 6 | font-family: "IBM Plex Mono"; 7 | src: url("/fonts/plex/IBMPlexMono-Text.woff2") format("woff2"); 8 | font-weight: 400; 9 | font-style: normal; 10 | } 11 | 12 | @font-face { 13 | font-family: "IBM Plex Mono"; 14 | src: url("/fonts/plex/IBMPlexMono-Bold.woff2") format("woff2"); 15 | font-weight: 700; 16 | font-style: normal; 17 | } 18 | 19 | .icon { 20 | @apply inline-block; 21 | @apply w-4; 22 | @apply h-4; 23 | @apply stroke-0; 24 | @apply stroke-current; 25 | @apply fill-current; 26 | } 27 | -------------------------------------------------------------------------------- /library/hipcheck-macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Use the `README.md` as the crate docs. 4 | #![doc = include_str!("../README.md")] 5 | 6 | mod update; 7 | 8 | use proc_macro::TokenStream; 9 | use syn::{DeriveInput, Error, parse_macro_input}; 10 | 11 | /// Derive an implementation of the `Update` trait for the type. 12 | #[proc_macro_derive(Update)] 13 | pub fn derive_update(input: TokenStream) -> TokenStream { 14 | // Parse the input. 15 | let input = parse_macro_input!(input as DeriveInput); 16 | 17 | // Generate the token stream. 18 | update::derive_update(input) 19 | .unwrap_or_else(Error::into_compile_error) 20 | .into() 21 | } 22 | -------------------------------------------------------------------------------- /plugins/churn/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "churn" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | hipcheck-sdk = { workspace = true, features = ["macros"] } 12 | tracing = { workspace = true } 13 | schemars = { workspace = true } 14 | serde = { workspace = true } 15 | serde_json = { workspace = true } 16 | tokio = { workspace = true, features = ["rt"] } 17 | hipcheck-workspace-hack = { workspace = true } 18 | 19 | [dev-dependencies] 20 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 21 | -------------------------------------------------------------------------------- /plugins/identity/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "identity" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | hipcheck-sdk = { workspace = true, features = ["macros"] } 12 | tracing = { workspace = true } 13 | schemars = { workspace = true } 14 | serde = { workspace = true } 15 | serde_json = { workspace = true } 16 | tokio = { workspace = true, features = ["rt"] } 17 | hipcheck-workspace-hack = { workspace = true } 18 | 19 | [dev-dependencies] 20 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 21 | -------------------------------------------------------------------------------- /site/scripts/src/footer/theme.ts: -------------------------------------------------------------------------------- 1 | import { querySelectorAll } from "../util/web.ts"; 2 | import { setPageTheme } from "../util/theme.ts"; 3 | 4 | /** 5 | * Sets up the logic for updating theme post-load. 6 | * 7 | * Note that this does _not_ handle setting the theme initially on page load. 8 | * That's done in a separate file since it needs to happen in the head, whereas 9 | * this code runs at the end of the body. 10 | */ 11 | export function setupThemeController() { 12 | querySelectorAll(".theme-option").forEach(($option) => { 13 | $option.addEventListener("click", (e) => { 14 | e.preventDefault(); 15 | setPageTheme($option.dataset.theme); 16 | }); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/commits.yml: -------------------------------------------------------------------------------- 1 | name: Commits 2 | 3 | on: 4 | pull_request: 5 | branches: [main] 6 | merge_group: 7 | types: [checks_requested] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | conventional-commits: 14 | name: Conventional Commits 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 5 17 | steps: 18 | - name: Check out the repo 19 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 20 | with: 21 | persist-credentials: false 22 | 23 | - name: Check conventional commits compliance 24 | uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 # v1.3.0 25 | -------------------------------------------------------------------------------- /site/content/docs/contributing/describing-changes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Describing Changes 3 | weight: 4 4 | --- 5 | 6 | # Describing Changes 7 | 8 | All commits to Hipcheck are required to follow the Conventional Commits 9 | specfication. We use this requirement to help us auto-generate material 10 | for our `CHANGELOG.md` and GitHub Release notes with each new version, 11 | though we do still double-check and write them by hand. 12 | 13 | We also generally try to make sure commits serve a reasonably clear 14 | purpose, and include comments whenever appropriate to explain the 15 | reasoning behind what is being changed, or at least link to a GitHub 16 | Issue or Discussion for further explanation. 17 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-schema.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc schema 3 | extra: 4 | nav_title: "hc schema" 5 | --- 6 | 7 | # `hc schema` 8 | 9 | The `hc schema` command is intended to help users of Hipcheck who are trying 10 | to integrate Hipcheck into other tools and systems. Hipcheck supports a JSON 11 | output format for analyses, and `hc schema` produces a JSON schema description 12 | of that output. 13 | 14 | `hc schema` takes the name of the target type for which to print the schema. 15 | For the list of target types, see [the documentation for the `hc check` command](@/docs/guide/cli/hc-check.md). 16 | 17 | `hc schema` also takes the usual [General Flags](@/docs/guide/cli/general-flags.md). 18 | -------------------------------------------------------------------------------- /hipcheck/src/shell/macros.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Macros that mirror/replace those from the standard library using the global [`Shell`][crate::shell::Shell]. 4 | 5 | macro_rules! println { 6 | ($($arg:tt)+) => { 7 | $crate::shell::Shell::println(format!($($arg)*)); 8 | }; 9 | 10 | () => { 11 | $crate::shell::Shell::println(""); 12 | } 13 | } 14 | 15 | // public re-export 16 | pub(crate) use println; 17 | 18 | macro_rules! eprintln { 19 | ($($arg:tt)+) => { 20 | $crate::shell::Shell::eprintln(format!($($arg)*)); 21 | }; 22 | 23 | () => { 24 | $crate::shell::Shell::eprintln(""); 25 | } 26 | } 27 | 28 | pub(crate) use eprintln; 29 | -------------------------------------------------------------------------------- /site/content/docs/contributing/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Testing Changes 3 | weight: 2 4 | --- 5 | 6 | # Testing Changes 7 | 8 | All changes to Hipcheck must pass continuous integration (CI) tests prior 9 | to being merged. You can simulate this test suite, at least on your own 10 | operating system and architecture, using the following command: 11 | 12 | ```sh 13 | $ cargo xtask ci 14 | ``` 15 | 16 | Passing this command is not a _guarantee_ of passing the official CI suite 17 | on GitHub, but is a good way to approximate things locally. 18 | 19 | If you want faster tests locally, we also recommend installing `cargo-nextest`. 20 | The `cargo xtask ci` command will use it instead of `cargo test` if it's 21 | installed. 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'type: enhancement' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /plugins/activity/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "activity" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | hipcheck-sdk = { workspace = true, features = ["macros"] } 12 | jiff = { workspace = true, features = ["serde"] } 13 | tracing = { workspace = true } 14 | serde = { workspace = true, features = ["derive", "rc"] } 15 | serde_json = { workspace = true } 16 | tokio = { workspace = true, features = ["rt"] } 17 | hipcheck-workspace-hack = { workspace = true } 18 | 19 | [dev-dependencies] 20 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 21 | -------------------------------------------------------------------------------- /sdk/python/docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /site/content/docs/guide/config/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Configuration 3 | template: docs.html 4 | page_template: docs_page.html 5 | weight: 2 6 | sort_by: weight 7 | --- 8 | 9 | # Configuration 10 | 11 | This section covers how to configure Hipcheck through policy files. 12 | 13 |
14 | 15 | {% waypoint(title="Policy Files", path="@/docs/guide/config/policy-file.md", icon="file") %} 16 | How to configure what plugins to use and how to score their results. 17 | {% end %} 18 | 19 | {% waypoint(title="Policy Expressions", path="@/docs/guide/config/policy-expr.md", icon="message-square") %} 20 | How to convert individual analysis results into a pass/fail determination. 21 | {% end %} 22 | 23 |
24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'type: bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Desktop (please complete the following information):** 23 | - Operating System: [e.g. macOS] 24 | - Hipcheck Version [e.g. 3.6.0] 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /tests/test-plugins/activity-container/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "activity-container" 3 | version = "0.4.0" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | publish = false 7 | 8 | [dependencies] 9 | clap = { workspace = true, features = ["derive"] } 10 | hipcheck-sdk = { workspace = true, features = ["macros"] } 11 | jiff = { workspace = true, features = ["serde"] } 12 | log = { workspace = true } 13 | schemars = { workspace = true, features = ["url2"] } 14 | serde = { workspace = true, features = ["derive", "rc"] } 15 | serde_json = { workspace = true } 16 | tokio = { workspace = true, features = ["rt"] } 17 | hipcheck-workspace-hack = { workspace = true } 18 | 19 | [dev-dependencies] 20 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 21 | -------------------------------------------------------------------------------- /plugins/linguist/src/util/fs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::error::*; 4 | use crate::linguist::LanguageFile; 5 | use std::{fs, path::Path, str::FromStr}; 6 | 7 | /// Read a file to a string. 8 | pub fn read_string>(path: P) -> Result { 9 | fn inner(path: &Path) -> Result { 10 | fs::read_to_string(path) 11 | .with_context(|| format!("failed to read as UTF-8 string '{}'", path.display())) 12 | } 13 | 14 | inner(path.as_ref()) 15 | } 16 | 17 | /// Read file to a struct that can be deserialized from kdl format. 18 | pub fn read_kdl>(path: P) -> Result { 19 | let path = path.as_ref(); 20 | let contents = read_string(path)?; 21 | LanguageFile::from_str(&contents) 22 | } 23 | -------------------------------------------------------------------------------- /plugins/github/src/github/graphql/schemas/user_orgs.graphql: -------------------------------------------------------------------------------- 1 | query UserOrgs($login: String!) { 2 | user(login: $login) { 3 | # Company set in user's profile, if any. 4 | company 5 | # GitHub Organizations the user is a member of, if any, capped at 100. 6 | organizations(first: 100, orderBy: LOGIN) { 7 | nodes { 8 | name 9 | login 10 | # Domains associated with an org, if any, capped at 100. 11 | domains(first: 100) { 12 | nodes { 13 | domain 14 | isApproved 15 | isVerified 16 | } 17 | } 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dist/Containerfile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | FROM node:bookworm-slim 4 | 5 | ARG HC_VERSION="3.14.0" 6 | 7 | WORKDIR /app 8 | 9 | RUN set -eux \ 10 | && apt-get update \ 11 | && apt-get install --no-install-recommends -y ca-certificates git curl xz-utils mold \ 12 | && rm -rf /var/lib/apt/lists/* \ 13 | && adduser --disabled-password hc_user \ 14 | && chown -R hc_user /app 15 | 16 | USER hc_user 17 | 18 | RUN set -eux \ 19 | && curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mitre/hipcheck/releases/download/hipcheck-v${HC_VERSION}/hipcheck-installer.sh | sh \ 20 | && $HOME/.local/bin/hc setup 21 | 22 | ENV HC_CONFIG="/home/hc_user/.config/hipcheck" 23 | ENTRYPOINT ["/home/hc_user/.local/bin/hc"] 24 | CMD ["help"] 25 | -------------------------------------------------------------------------------- /plugins/binary/src/util/fs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::binary_detector::ExtensionsFile; 4 | use crate::error::*; 5 | use std::{fs, path::Path, str::FromStr}; 6 | 7 | /// Read a file to a string. 8 | pub fn read_string>(path: P) -> Result { 9 | fn inner(path: &Path) -> Result { 10 | fs::read_to_string(path) 11 | .with_context(|| format!("failed to read as UTF-8 string '{}'", path.display())) 12 | } 13 | 14 | inner(path.as_ref()) 15 | } 16 | 17 | /// Read file to a struct that can be deserialized from kdl format. 18 | pub fn read_kdl>(path: P) -> Result { 19 | let path = path.as_ref(); 20 | let contents = read_string(path)?; 21 | ExtensionsFile::from_str(&contents) 22 | } 23 | -------------------------------------------------------------------------------- /xtask/src/task/buf.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::workspace; 4 | use anyhow::{Context, Result}; 5 | use pathbuf::pathbuf; 6 | use which::which; 7 | use xshell::{Shell, cmd}; 8 | 9 | /// Run the `buf lint` command 10 | pub fn run() -> Result<()> { 11 | let sh = Shell::new().context("could not init shell")?; 12 | run_buf_lint(&sh) 13 | } 14 | 15 | /// Use existing `xshell::Shell` to run `buf lint` 16 | pub fn run_buf_lint(sh: &Shell) -> Result<()> { 17 | which("buf").context("could not find 'buf'")?; 18 | 19 | let root = workspace::root()?; 20 | let config = pathbuf![&root, ".buf.yaml"]; 21 | let target = pathbuf![&root, "hipcheck-common", "proto"]; 22 | 23 | cmd!(sh, "buf lint --config {config} {target}").run()?; 24 | 25 | Ok(()) 26 | } 27 | -------------------------------------------------------------------------------- /library/hipcheck-common/build.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::Result; 4 | use pathbuf::pathbuf; 5 | use tonic_prost_build::configure; 6 | 7 | fn main() -> Result<()> { 8 | // Compile the Hipcheck gRPC protocol spec to an .rs file 9 | let root = env!("CARGO_MANIFEST_DIR"); 10 | 11 | let protos = vec![pathbuf![root, "proto", "hipcheck", "v1", "hipcheck.proto"]]; 12 | let includes = vec![pathbuf![root, "proto"]]; 13 | 14 | configure().compile_protos(&protos, &includes)?; 15 | 16 | // Make the target available as a compile-time env var for plugin arch 17 | // resolution 18 | println!( 19 | "cargo:rustc-env=TARGET={}", 20 | std::env::var("TARGET").unwrap() 21 | ); 22 | println!("cargo:rerun-if-changed-env=TARGET"); 23 | 24 | Ok(()) 25 | } 26 | -------------------------------------------------------------------------------- /site/static/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /plugins/review/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "review" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | hipcheck-sdk = { workspace = true, features = ["macros"] } 13 | tracing = { workspace = true } 14 | schemars = { workspace = true, features = ["url2"] } 15 | serde = { workspace = true, features = ["derive", "rc"] } 16 | serde_json = { workspace = true } 17 | tokio = { workspace = true, features = ["rt"] } 18 | url = { workspace = true } 19 | hipcheck-workspace-hack = { workspace = true } 20 | 21 | [dev-dependencies] 22 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 23 | -------------------------------------------------------------------------------- /plugins/npm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "npm" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | hipcheck-sdk = { workspace = true, features = ["macros"] } 13 | tracing = { workspace = true } 14 | pathbuf = { workspace = true } 15 | regex = { workspace = true } 16 | schemars = { workspace = true, features = ["url2"] } 17 | semver = { workspace = true } 18 | serde = { workspace = true, features = ["derive", "rc"] } 19 | serde_json = { workspace = true } 20 | tokio = { workspace = true, features = ["rt"] } 21 | which = { workspace = true } 22 | hipcheck-workspace-hack = { workspace = true } 23 | -------------------------------------------------------------------------------- /plugins/linguist/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linguist" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | hipcheck-kdl = { workspace = true } 12 | hipcheck-sdk = { workspace = true, features = ["macros"] } 13 | tracing = { workspace = true } 14 | miette = { workspace = true, features = ["fancy"] } 15 | pathbuf = { workspace = true } 16 | serde = { workspace = true, features = ["derive"] } 17 | serde_json = { workspace = true } 18 | tokio = { workspace = true, features = ["rt"] } 19 | hipcheck-workspace-hack = { workspace = true } 20 | 21 | [dev-dependencies] 22 | hipcheck-sdk = { workspace = true, features = ["macros", "mock_engine"] } 23 | -------------------------------------------------------------------------------- /plugins/npm/src/util/fs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::{Context as _, Result}; 4 | use serde::de::DeserializeOwned; 5 | use std::{fs, path::Path}; 6 | 7 | /// Read file to a byte buffer. 8 | pub fn read_bytes>(path: P) -> Result> { 9 | fn inner(path: &Path) -> Result> { 10 | fs::read(path).with_context(|| format!("failed to read as bytes '{}'", path.display())) 11 | } 12 | 13 | inner(path.as_ref()) 14 | } 15 | 16 | /// Read file to a struct that can be deserialize from JSON format. 17 | pub fn read_json, T: DeserializeOwned>(path: P) -> Result { 18 | let path = path.as_ref(); 19 | let contents = read_bytes(path)?; 20 | serde_json::from_slice(&contents) 21 | .with_context(|| format!("failed to read as JSON '{}'", path.display())) 22 | } 23 | -------------------------------------------------------------------------------- /plugins/git/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "git" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | hipcheck-sdk = { workspace = true, features = ["macros"] } 13 | lru = { workspace = true } 14 | gix = { workspace = true, features = ["basic", "max-control", "zlib-stock"] } 15 | jiff = { workspace = true, features = ["serde"] } 16 | tracing = { workspace = true } 17 | schemars = { workspace = true, features = ["url2"] } 18 | serde_json = { workspace = true } 19 | serde = { workspace = true, features = ["derive", "rc"] } 20 | tokio = { workspace = true, features = ["rt"] } 21 | hipcheck-workspace-hack = { workspace = true } 22 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/util/redacted.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Utility type for hiding data from the user when printed in a debug message. 4 | 5 | use std::fmt::{Debug, Formatter, Result as FmtResult}; 6 | 7 | /// Helper container to ensure a value isn't printed. 8 | pub struct Redacted(T); 9 | 10 | impl Redacted { 11 | /// Construct a new redacted value. 12 | pub fn new(val: T) -> Redacted { 13 | Redacted(val) 14 | } 15 | } 16 | 17 | impl AsRef for Redacted { 18 | fn as_ref(&self) -> &T { 19 | &self.0 20 | } 21 | } 22 | 23 | impl AsMut for Redacted { 24 | fn as_mut(&mut self) -> &mut T { 25 | &mut self.0 26 | } 27 | } 28 | 29 | impl Debug for Redacted { 30 | fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { 31 | write!(f, "") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugins/binary/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "binary" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | content_inspector = { workspace = true } 12 | hipcheck-kdl = { workspace = true } 13 | hipcheck-sdk = { workspace = true, features = ["macros"] } 14 | tracing = { workspace = true } 15 | miette = { workspace = true, features = ["fancy"] } 16 | pathbuf = { workspace = true } 17 | serde = { workspace = true } 18 | serde_json = { workspace = true } 19 | tokio = { workspace = true, features = ["rt"] } 20 | walkdir = { workspace = true } 21 | hipcheck-workspace-hack = { workspace = true } 22 | 23 | [dev-dependencies] 24 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 25 | -------------------------------------------------------------------------------- /site/content/docs/contributing/developer-docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Developer Docs 3 | template: docs.html 4 | sort_by: weight 5 | page_template: docs_page.html 6 | weight: 5 7 | --- 8 | 9 | # Hipcheck Developer Docs 10 | 11 |
12 | 13 | {% waypoint(title="Repo Structure", path="@/docs/contributing/developer-docs/repo-structure.md") %} 14 | List of key directories in the Hipcheck repository. 15 | {% end %} 16 | 17 | {% waypoint(title="Architecture", path="@/docs/contributing/developer-docs/architecture.md") %} 18 | Hipcheck's distributed architecture and how plugins get started. 19 | {% end %} 20 | 21 | {% waypoint(title="Query System", path="@/docs/contributing/developer-docs/plugin-query-system/index.md") %} 22 | The life of a plugin query from inception, through gRPC, to SDK, and back. 23 | {% end %} 24 | 25 |
26 | -------------------------------------------------------------------------------- /hipcheck/src/util/http/agent.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Globally defined agent containing system TLS Certs. 4 | 5 | use crate::Result; 6 | use rustls::ClientConfig; 7 | use rustls_platform_verifier::ConfigVerifierExt; 8 | use std::sync::{Arc, OnceLock}; 9 | use ureq::{Agent, AgentBuilder}; 10 | 11 | /// Global static holding the agent with the appropriate TLS certs. 12 | static AGENT: OnceLock = OnceLock::new(); 13 | 14 | /// Get or initialize the global static agent used in making http(s) requests for hipcheck. 15 | pub fn agent() -> Result<&'static Agent> { 16 | // Create connection configuration with system certs retrieved by rustls platform verifier 17 | let tls_config = ClientConfig::with_platform_verifier()?; 18 | let agent = AGENT.get_or_init(|| AgentBuilder::new().tls_config(Arc::new(tls_config)).build()); 19 | Ok(agent) 20 | } 21 | -------------------------------------------------------------------------------- /plugins/typo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "typo" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | hipcheck-kdl = { workspace = true } 13 | hipcheck-sdk = { workspace = true, features = ["macros"] } 14 | tracing = { workspace = true } 15 | maplit = { workspace = true } 16 | miette = { workspace = true, features = ["fancy"] } 17 | pathbuf = { workspace = true } 18 | serde = { workspace = true, features = ["derive", "rc"] } 19 | serde_json = { workspace = true } 20 | tokio = { workspace = true, features = ["rt"] } 21 | url = { workspace = true } 22 | hipcheck-workspace-hack = { workspace = true } 23 | 24 | [dev-dependencies] 25 | hipcheck-sdk = { workspace = true, features = ["mock_engine"] } 26 | -------------------------------------------------------------------------------- /site/content/docs/guide/debugging/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Debugging 3 | template: docs.html 4 | page_template: docs_page.html 5 | sort_by: weight 6 | weight: 4 7 | --- 8 | 9 | # Debugging 10 | 11 | The following is a guide for debugging Hipcheck's execution. 12 | 13 | 14 |
15 | 16 | {% waypoint(title="Starting Debugging", path="@/docs/guide/debugging/starting.md", icon="thumbs-up") %} 17 | The basics for how to check Hipcheck's execution setup before anything else. 18 | {% end %} 19 | 20 | {% waypoint(title="Logging", path="@/docs/guide/debugging/logging.md", icon="list") %} 21 | How to configure Hipcheck's logging, including a variety of filtering options. 22 | {% end %} 23 | 24 | {% waypoint(title="Using a Debugger", path="@/docs/guide/debugging/debugger.md", icon="paperclip") %} 25 | How to debug Hipcheck using a separate debugger. 26 | {% end %} 27 | 28 |
29 | -------------------------------------------------------------------------------- /plugins/entropy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "entropy" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | clap = { workspace = true, features = ["derive"] } 11 | dashmap = { workspace = true, features = ["inline", "rayon"] } 12 | finl_unicode = { workspace = true, features = ["grapheme_clusters"] } 13 | hipcheck-sdk = { workspace = true, features = ["macros"] } 14 | rayon = { workspace = true } 15 | schemars = { workspace = true } 16 | serde = { workspace = true } 17 | serde_json = { workspace = true } 18 | tracing = { workspace = true } 19 | tokio = { workspace = true, features = ["rt"] } 20 | unicode-normalization = { workspace = true } 21 | hipcheck-workspace-hack = { workspace = true } 22 | 23 | [dev-dependencies] 24 | hipcheck-sdk = { workspace = true, features = ["macros", "mock_engine"] } 25 | -------------------------------------------------------------------------------- /hipcheck/src/shell/color_choice.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Utilities for handling whether or not to use color while printing output. 4 | 5 | use crate::error::{Error, Result}; 6 | use std::str::FromStr; 7 | 8 | /// Selection of whether the CLI output should use color. 9 | #[derive(Debug, Default, Copy, Clone, PartialEq, clap::ValueEnum)] 10 | pub enum ColorChoice { 11 | /// Always use color output 12 | Always, 13 | /// Never use color output 14 | Never, 15 | /// Guess whether to use color output 16 | #[default] 17 | Auto, 18 | } 19 | 20 | impl FromStr for ColorChoice { 21 | type Err = Error; 22 | 23 | fn from_str(s: &str) -> Result { 24 | match s.to_lowercase().as_ref() { 25 | "always" => Ok(ColorChoice::Always), 26 | "never" => Ok(ColorChoice::Never), 27 | "auto" => Ok(ColorChoice::Auto), 28 | _ => Err(Error::msg("unknown color option")), 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugins/affiliation/src/util/fs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! General shared functions for interacting with the file system 4 | 5 | use anyhow::{Context as _, Result, anyhow}; 6 | use std::{fs, ops::Not, path::Path}; 7 | 8 | /// Read a file to a string. 9 | pub fn read_string>(path: P) -> Result { 10 | fn inner(path: &Path) -> Result { 11 | fs::read_to_string(path) 12 | .with_context(|| format!("failed to read as UTF-8 string '{}'", path.display())) 13 | } 14 | 15 | inner(path.as_ref()) 16 | } 17 | 18 | /// Check that a given path exists. 19 | pub fn exists>(path: P) -> Result<()> { 20 | fn inner(path: &Path) -> Result<()> { 21 | if path.exists().not() { 22 | Err(anyhow!( 23 | "'{}' not found at current directory", 24 | path.display() 25 | )) 26 | } else { 27 | Ok(()) 28 | } 29 | } 30 | 31 | inner(path.as_ref()) 32 | } 33 | -------------------------------------------------------------------------------- /plugins/git/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/npm/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/binary/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/churn/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/entropy/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/fuzz/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/github/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/identity/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/linguist/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/review/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /plugins/typo/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /xtask/src/task/build.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::{ 4 | BuildArgs, 5 | build::{resolve_builder_args, resolve_packages}, 6 | string::list_with_commas, 7 | }; 8 | use anyhow::Result; 9 | use itertools::Itertools; 10 | use log::debug; 11 | use std::collections::BTreeSet; 12 | use xshell::{Shell, cmd}; 13 | 14 | /// Run the build command. 15 | pub fn run(args: BuildArgs) -> Result<()> { 16 | debug!("rebuild targeting: {}", list_with_commas(&args.pkg)); 17 | 18 | let pkgs = args 19 | .pkg 20 | .into_iter() 21 | .flat_map(resolve_packages) 22 | .unique() 23 | .collect::>(); 24 | 25 | let builder_args = resolve_builder_args(&pkgs, &args.profile, args.timings); 26 | 27 | debug!("rebuilding packages: {}", list_with_commas(&pkgs)); 28 | debug!("using profile: {}", args.profile); 29 | 30 | let sh = Shell::new()?; 31 | cmd!(sh, "cargo build {builder_args...}").run()?; 32 | 33 | Ok(()) 34 | } 35 | -------------------------------------------------------------------------------- /xtask/src/task/check.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::{ 4 | BuildArgs, 5 | build::{resolve_builder_args, resolve_packages}, 6 | string::list_with_commas, 7 | }; 8 | use anyhow::Result; 9 | use itertools::Itertools; 10 | use log::debug; 11 | use std::collections::BTreeSet; 12 | use xshell::{Shell, cmd}; 13 | 14 | /// Run the build command. 15 | pub fn run(args: BuildArgs) -> Result<()> { 16 | debug!("check targeting: {}", list_with_commas(&args.pkg)); 17 | 18 | let pkgs = args 19 | .pkg 20 | .into_iter() 21 | .flat_map(resolve_packages) 22 | .unique() 23 | .collect::>(); 24 | 25 | let builder_args = resolve_builder_args(&pkgs, &args.profile, args.timings); 26 | 27 | debug!("checking packages: {}", list_with_commas(&pkgs)); 28 | debug!("using profile: {}", args.profile); 29 | 30 | let sh = Shell::new()?; 31 | cmd!(sh, "cargo check {builder_args...}").run()?; 32 | 33 | Ok(()) 34 | } 35 | -------------------------------------------------------------------------------- /plugins/affiliation/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 19 | # compiler present on their platform. 20 | 21 | [dist.dependencies.apt] 22 | protobuf-compiler = "*" 23 | mold = "*" 24 | 25 | [dist.dependencies.homebrew] 26 | protobuf = "*" 27 | 28 | [dist.dependencies.chocolatey] 29 | protoc = "*" 30 | -------------------------------------------------------------------------------- /dist/dockerhub/README.md: -------------------------------------------------------------------------------- 1 | # What is Hipcheck? 2 | 3 | Hipcheck is a plugin-based command line interface (CLI) tool for analyzing open 4 | source software packages and source repositories to understand their software 5 | supply chain risk. 6 | 7 | ## How to Use 8 | 9 | ``` 10 | docker run mitre/hipcheck:latest 11 | ``` 12 | 13 | NOTE: `latest` __always__ refers to the most-recently published image. 14 | 15 | Hipcheck currently provides images for `linux/amd64` (64-bit Linux). 16 | 17 | ## Helpful Links 18 | 19 | * [Website](https://hipcheck.mitre.org) 20 | * [Quickstart Guide](https://hipcheck.mitre.org/docs/quickstart/) 21 | * [Complete Guide](https://hipcheck.mitre.org/docs/guide/) 22 | * [Github](https://github.com/mitre/hipcheck) 23 | * [Report an Issue](https://github.com/mitre/hipcheck/issues/new) 24 | 25 | ## License 26 | 27 | Hipcheck's software is licensed under the 28 | [Apache 2.0 license](https://github.com/mitre/hipcheck/blob/main/LICENSE) 29 | -------------------------------------------------------------------------------- /plugins/activity/dist.toml: -------------------------------------------------------------------------------- 1 | 2 | [dist] 3 | 4 | # Make sure that 'dist' will handle releases for this. Otherwise, since 5 | # the crate is set to 'publish = false', 'dist' would ignore it by default. 6 | dist = true 7 | 8 | # We explicitly *don't* want 'dist' to produce installers; just to prebuild 9 | # the binaries for us and bundle everything together. Hipcheck itself will 10 | # handle people getting the prebuilt binaries based on the download manifest. 11 | installers = [] 12 | 13 | # Do not install an updater. 14 | install-updater = false 15 | 16 | # Make sure to include the plugin manifest. 17 | include = ["plugin.kdl"] 18 | 19 | # Make sure that both Hipcheck and all the plugins are built with the protobuf 20 | # compiler present on their platform. 21 | 22 | [dist.dependencies.apt] 23 | protobuf-compiler = "*" 24 | mold = "*" 25 | 26 | [dist.dependencies.homebrew] 27 | protobuf = "*" 28 | 29 | [dist.dependencies.chocolatey] 30 | protoc = "*" 31 | -------------------------------------------------------------------------------- /plugins/affiliation/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "affiliation" 3 | version = "0.5.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | hipcheck-kdl = { workspace = true } 13 | hipcheck-sdk = { workspace = true, features = ["macros"] } 14 | tracing = { workspace = true } 15 | miette = { workspace = true, features = ["fancy"] } 16 | pathbuf = { workspace = true } 17 | schemars = { workspace = true, features = ["url2"] } 18 | serde = { workspace = true, features = ["derive", "rc"] } 19 | serde_json = { workspace = true } 20 | strum = { workspace = true, features = ["derive"] } 21 | tokio = { workspace = true, features = ["rt"] } 22 | hipcheck-workspace-hack = { workspace = true } 23 | 24 | [dev-dependencies] 25 | hipcheck-sdk = { workspace = true, features = ["macros", "mock_engine"] } 26 | -------------------------------------------------------------------------------- /site/content/docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Documentation 3 | template: docs.html 4 | page_template: docs_page.html 5 | sort_by: weight 6 | --- 7 | 8 | # Documentation 9 | 10 | Welcome to the official Hipcheck documentation! 11 | 12 |
13 | 14 | {% waypoint(title="Getting Started", path="@/docs/getting-started/_index.md", icon="map-pin") %} 15 | A guide to installing and running Hipcheck for the first time. 16 | {% end %} 17 | 18 | {% waypoint(title="Complete Guide", path="@/docs/guide/_index.md", icon="map") %} 19 | A complete guide to all of Hipcheck's functionality. 20 | {% end %} 21 | 22 | {% waypoint(title="Contribute", path="@/docs/contributing/_index.md", icon="award") %} 23 | Learn how to make contributions to Hipcheck itself. 24 | {% end %} 25 | 26 | {% waypoint(title="RFDs", path="@/docs/rfds/_index.md", icon="pen-tool") %} 27 | Design documents proposing important changes to Hipcheck. 28 | {% end %} 29 | 30 |
31 | -------------------------------------------------------------------------------- /sdk/python/docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /site/scripts/src/footer/main.ts: -------------------------------------------------------------------------------- 1 | import { setupDocsNav } from "./docs.ts"; 2 | import { setupInstallerPicker } from "./installer.ts"; 3 | import { setupSmoothScrolling } from "./scroll.ts"; 4 | import { setupSearch, setupSearchModal } from "./search.ts"; 5 | import { setupThemeController } from "./theme.ts"; 6 | 7 | /** 8 | * Run all page setup operations, initializing all interactive widgets. 9 | * 10 | * There are currently three widgets: 11 | * 12 | * - Theme Controller in the navigation bar. 13 | * - Installer Picker on the homepage. 14 | * - Search button in the navigation bar. 15 | */ 16 | function setup() { 17 | setupThemeController(); 18 | setupInstallerPicker(); 19 | setupSearchModal(); 20 | setupSearch(); 21 | setupSmoothScrolling(); 22 | setupDocsNav(); 23 | } 24 | 25 | /** 26 | * Do setup, logging errors to the console. 27 | */ 28 | (function () { 29 | try { 30 | setup(); 31 | } catch (e) { 32 | console.error(e); 33 | } 34 | })(); 35 | -------------------------------------------------------------------------------- /hipcheck/build.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | include!("src/target/types.rs"); 4 | 5 | use anyhow::Result; 6 | use pathbuf::pathbuf; 7 | use schemars::schema_for; 8 | use std::{fs, path::Path}; 9 | 10 | fn generate_schemars_for_target_types(out_dir: &Path) -> Result<()> { 11 | let out_schemars = vec![("target", schema_for!(Target))]; 12 | for (key, schema) in out_schemars { 13 | let out_path = pathbuf![out_dir, format!("hipcheck_{}_schema.json", key).as_str()]; 14 | fs::write(out_path, serde_json::to_string_pretty(&schema).unwrap()).unwrap(); 15 | } 16 | Ok(()) 17 | } 18 | 19 | fn main() -> Result<()> { 20 | generate_schemars_for_target_types(Path::new("../sdk/schema"))?; 21 | 22 | // Make the target available as a compile-time env var for plugin arch 23 | // resolution 24 | println!( 25 | "cargo:rustc-env=TARGET={}", 26 | std::env::var("TARGET").unwrap() 27 | ); 28 | println!("cargo:rerun-if-changed-env=TARGET"); 29 | 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | # Run once a week on Monday at midnight. 4 | # Plus be able to run it on command. 5 | on: 6 | schedule: 7 | - cron: "0 0 * * 1" 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | name: "Build Containerfile" 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check out the repo 16 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 17 | with: 18 | persist-credentials: false 19 | 20 | - name: Setup Qemu 21 | uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 22 | 23 | - name: Setup Docker buildx 24 | uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 25 | 26 | - name: Run Docker build 27 | uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 28 | with: 29 | file: dist/Containerfile 30 | push: false 31 | -------------------------------------------------------------------------------- /library/hipcheck-common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hipcheck-common" 3 | description = "Common functionality for the Hipcheck gRPC protocol" 4 | repository = "https://github.com/mitre/hipcheck" 5 | version = "0.4.2" 6 | license = "Apache-2.0" 7 | edition = "2024" 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["cargo", "derive", "string"] } 12 | prost = { workspace = true } 13 | serde = { workspace = true, features = ["derive", "rc"] } 14 | serde_json = { workspace = true } 15 | thiserror = { workspace = true } 16 | tonic = { workspace = true } 17 | tonic-prost = { workspace = true } 18 | hipcheck-workspace-hack = { workspace = true } 19 | 20 | [build-dependencies] 21 | anyhow = { workspace = true } 22 | pathbuf = { workspace = true } 23 | tonic-prost-build = { workspace = true } 24 | 25 | [features] 26 | default = ["rfd9-compat"] 27 | rfd9-compat = [] 28 | 29 | [package.metadata.cargo-machete] 30 | ignored = ["prost", "tonic"] 31 | -------------------------------------------------------------------------------- /site/content/docs/guide/debugging/debugger.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Using a Debugger 3 | weight: 3 4 | --- 5 | 6 | # Debugger 7 | 8 | Hipcheck can be run under a debugger like `gdb` or `lldb`. Because Hipcheck is 9 | written in Rust, we recommend using the Rust-patched versions of `gdb` or `lldb` 10 | which ship with the Rust standard tooling. These versions of the tools include 11 | specific logic to demangle Rust symbols to improve the experience of debugging 12 | Rust code. 13 | 14 | You can install these tools by following the standard [Rust installation 15 | instructions](https://www.rust-lang.org/tools/install). 16 | 17 | With one of these debuggers installed, you can then use them to set breakpoints 18 | during Hipcheck's execution, and do all the normal program debugging processes 19 | you're familiar with if you've used a debugger before. Explaining the use of 20 | these tools is outside of the scope of the Hipcheck documentation, so we defer 21 | to their respective documentation sources. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The target directory, where all the build artifacts go. 2 | /target/ 3 | /target 4 | .target/ 5 | ./target/ 6 | .target 7 | ./target 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | # macOS file 13 | .DS_Store 14 | 15 | # Visual Studio Code directory 16 | .vscode 17 | 18 | # IntelliJ IDEA Directory 19 | .idea 20 | 21 | # dotenv env configuration file 22 | .env 23 | 24 | # Vim swap files 25 | .*.swp 26 | 27 | # We generate a file with this name when prepping each release, and don't 28 | # want it to be checked in. 29 | CHANGELOG-NEXT.md 30 | 31 | # File generated by cargo-flamegraph 32 | flamegraph.svg 33 | 34 | # Generated file based on the protobuf definition. 35 | /hipcheck/src/hipcheck.rs 36 | 37 | # Editor-specific directory for Zed 38 | .zed 39 | 40 | # Python environment dir 41 | venv 42 | 43 | # Python pycache and SDK build dirs 44 | __pycache__ 45 | sdk/python/build/ 46 | sdk/python/dist/ 47 | sdk/python/hipcheck_sdk.egg-info/ 48 | sdk/python/docs/build/ 49 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/util/agent.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Globally defined agent containing system TLS Certs. 4 | 5 | use anyhow::Result; 6 | use rustls::ClientConfig; 7 | use rustls_platform_verifier::ConfigVerifierExt; 8 | use std::sync::{Arc, OnceLock}; 9 | use ureq::{Agent, AgentBuilder}; 10 | 11 | /// Global static holding the agent with the appropriate TLS certs. 12 | static AGENT: OnceLock = OnceLock::new(); 13 | 14 | /// Get or initialize the global static agent used in making http(s) requests for hipcheck. 15 | /// 16 | /// # Panics 17 | /// - If native certs cannot be loaded the first time this function is called. 18 | pub fn agent() -> Result<&'static Agent> { 19 | // Create connection configuration with system certs retrieved by rustls platform verifier 20 | let tls_config = ClientConfig::with_platform_verifier()?; 21 | 22 | Ok(AGENT.get_or_init(|| { 23 | // Construct agent 24 | AgentBuilder::new().tls_config(Arc::new(tls_config)).build() 25 | })) 26 | } 27 | -------------------------------------------------------------------------------- /site/scripts/src/footer/scroll.ts: -------------------------------------------------------------------------------- 1 | import { querySelector, querySelectorAll } from "../util/web.ts"; 2 | 3 | export function setupSmoothScrolling() { 4 | /* 5 | * This code from: https://stackoverflow.com/a/7717572 6 | * Used under the CC BY-SA 3.0 license with modifications. 7 | */ 8 | querySelectorAll('a[href^="#"]').forEach((anchor) => { 9 | anchor.addEventListener("click", (e) => { 10 | e.preventDefault(); 11 | if (e.currentTarget === null) return; 12 | 13 | const targetHeader = (e.currentTarget as HTMLElement).getAttribute("href"); 14 | if (targetHeader === null) return; 15 | 16 | const $header = querySelector(targetHeader); 17 | const headerPosition = $header.getBoundingClientRect().top; 18 | const scrollAmount = globalThis.window.scrollY; 19 | const offsetPosition = headerPosition + scrollAmount; 20 | 21 | globalThis.window.scrollTo({ 22 | top: offsetPosition, 23 | behavior: "smooth", 24 | }); 25 | }); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /site/content/docs/contributing/coordinating-changes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Coordinating Changes 3 | weight: 1 4 | --- 5 | 6 | # Coordinating Changes 7 | 8 | For small changes, including improvements to documentation, correction of 9 | bugs, fixing typos, and general code quality improvements, submitting 10 | without coordinating with the Hipcheck team is generally fine and 11 | appreciated! 12 | 13 | For larger changes, including the addition of new data sources, new analyses, 14 | refactoring modules, changing the CLI or configuration, or similar, we 15 | highly suggest discussing your proposed changes before submission. Often 16 | this will begin with opening up a GitHub Issue or a Discussion, and for 17 | larger changes may also involve writing a Request for Discussion (RFD) 18 | document. 19 | 20 | RFD's are how the Hipcheck project manages large scale changes to the tool, 21 | and are documented more on the RFD's page. 22 | 23 | The Hipcheck product roadmap is public, and we always recommend checking 24 | there to see how your proposed changes may fit into the currently-planned 25 | work. 26 | -------------------------------------------------------------------------------- /site/scripts/src/util/icon.ts: -------------------------------------------------------------------------------- 1 | export function updateIcon( 2 | $node: HTMLElement, 3 | oldName: string, 4 | newName: string, 5 | ) { 6 | const iconUrl = getIconUrl($node); 7 | const newIconUrl = iconUrl.replace(`#icon-${oldName}`, `#icon-${newName}`); 8 | setIconUrl($node, newIconUrl); 9 | } 10 | 11 | /** 12 | * Get the URL out of an icon `use` element. 13 | */ 14 | function getIconUrl($node: HTMLElement): string { 15 | const iconUrl = $node.getAttributeNS(XLINK_NS, "href"); 16 | if (iconUrl === null) throw new IconError(); 17 | return iconUrl; 18 | } 19 | 20 | /** 21 | * Get the URL on an icon `use` element. 22 | */ 23 | function setIconUrl($node: HTMLElement, url: string) { 24 | $node.setAttributeNS(XLINK_NS, "href", url); 25 | } 26 | 27 | /** 28 | * The namespace URL for the Xlink namespace 29 | */ 30 | const XLINK_NS: string = "http://www.w3.org/1999/xlink"; 31 | 32 | /** 33 | * Error arising when trying to update the copy-to-clipboard icon. 34 | */ 35 | class IconError extends Error { 36 | constructor() { 37 | super(`could not find copy icon`); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/cli.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | import argparse 4 | 5 | from hipcheck_sdk.server import Plugin, PluginServer 6 | 7 | 8 | def get_parser_for(plugin_name: str) -> argparse.ArgumentParser: 9 | """ 10 | Get the default argument parser for a Hipcheck plugin 11 | 12 | :return: An ArgumentParser configured to capture Hipcheck plugin CLI 13 | arguments 14 | """ 15 | parser = argparse.ArgumentParser(prog=plugin_name) 16 | parser.add_argument("-p", "--port", type=int) 17 | parser.add_argument("-l", "--log-level", type=str, default="error") 18 | return parser 19 | 20 | 21 | def run_server_for(plugin: Plugin): 22 | """ 23 | Parse CLI arguments and start the server for the plugin. Does not return 24 | until the gRPC connection closes. 25 | 26 | :param Plugin plugin: An instance of a subclass of `Plugin` 27 | """ 28 | plugin_name = type(plugin).__name__ 29 | parser = get_parser_for(plugin_name) 30 | args = parser.parse_args() 31 | PluginServer.register(plugin, args.log_level).listen(args.port) 32 | -------------------------------------------------------------------------------- /site/scripts/tasks/bundle.ts: -------------------------------------------------------------------------------- 1 | import * as esbuild from "npm:esbuild"; 2 | import { denoPlugins } from "jsr:@luca/esbuild-deno-loader"; 3 | 4 | const footerResult = await esbuild.build({ 5 | plugins: [...denoPlugins()], 6 | entryPoints: ["src/footer/main.ts"], 7 | outfile: "../static/js/footer.mjs", 8 | bundle: true, 9 | minify: true, 10 | sourcemap: true, 11 | format: "esm", 12 | }); 13 | 14 | for (const warning in footerResult.warnings) { 15 | console.warn(`footer: ${warning}`); 16 | } 17 | 18 | for (const error in footerResult.errors) { 19 | console.error(`footer: ${error}`); 20 | } 21 | 22 | const headerResult = await esbuild.build({ 23 | plugins: [...denoPlugins()], 24 | entryPoints: ["src/header/main.ts"], 25 | outfile: "../static/js/header.mjs", 26 | bundle: true, 27 | minify: true, 28 | sourcemap: true, 29 | format: "esm", 30 | }); 31 | 32 | for (const warning in headerResult.warnings) { 33 | console.warn(`header: ${warning}`); 34 | } 35 | 36 | for (const error in headerResult.errors) { 37 | console.error(`header: ${error}`); 38 | } 39 | 40 | await esbuild.stop(); 41 | -------------------------------------------------------------------------------- /plugins/github/src/tls/agent.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Globally defined agent containing system TLS Certs. 4 | 5 | use crate::Result; 6 | use hipcheck_sdk::error::Error; 7 | use rustls::ClientConfig; 8 | use rustls_platform_verifier::ConfigVerifierExt; 9 | use std::sync::{Arc, OnceLock}; 10 | use ureq::{Agent, AgentBuilder}; 11 | 12 | /// Global static holding the agent with the appropriate TLS certs. 13 | static AGENT: OnceLock = OnceLock::new(); 14 | 15 | /// Get or initialize the global static agent used in making http(s) requests for hipcheck. 16 | /// 17 | /// # Panics 18 | /// - If native certs cannot be loaded the first time this function is called. 19 | pub fn agent() -> Result<&'static Agent> { 20 | // Create connection configuration with system certs retrieved by rustls platform verifier 21 | let tls_config = ClientConfig::with_platform_verifier().map_err(|e| Error::Unspecified { 22 | source: Box::new(e), 23 | })?; 24 | 25 | Ok(AGENT.get_or_init(|| { 26 | // Construct agent 27 | AgentBuilder::new().tls_config(Arc::new(tls_config)).build() 28 | })) 29 | } 30 | -------------------------------------------------------------------------------- /plugins/github/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "github" 3 | version = "0.4.2" 4 | license = "Apache-2.0" 5 | edition = "2024" 6 | repository = "https://github.com/mitre/hipcheck" 7 | publish = false 8 | 9 | [dependencies] 10 | anyhow = { workspace = true } 11 | clap = { workspace = true, features = ["derive"] } 12 | graphql_client = { workspace = true } 13 | hipcheck-sdk = { workspace = true, features = ["macros"] } 14 | tracing = { workspace = true } 15 | # Exactly matching the version of rustls used by ureq 16 | # Get rid of default features since we don't use the AWS backed crypto 17 | # provider (we use ring) and it breaks stuff on windows. 18 | rustls = { workspace = true, features = ["logging", "std", "tls12", "ring"] } 19 | rustls-platform-verifier = { workspace = true } 20 | schemars = { workspace = true, features = ["url2"] } 21 | serde = { workspace = true } 22 | serde_json = { workspace = true } 23 | tokio = { workspace = true, features = ["rt"] } 24 | ureq = { workspace = true, features = ["json", "tls"] } 25 | url = { workspace = true, features = ["serde"] } 26 | hipcheck-workspace-hack = { workspace = true } 27 | -------------------------------------------------------------------------------- /site/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | 3 | const defaultTheme = require("tailwindcss/defaultTheme"); 4 | 5 | module.exports = { 6 | // Track the template files for the purpose of selecting 7 | // what CSS is actually used. 8 | content: ["./templates/**/*.html", "./public/**/*.html", "./content/**/*.md"], 9 | theme: { 10 | extend: { 11 | fontFamily: { 12 | // Use Inter as the default font, but otherwise use 13 | // the default sans-serif font. 14 | sans: [ 15 | "'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'", 16 | { 17 | fontFeatureSettings: 18 | '"calt", "dlig", "case", "ss03", "cv01", "cv10"', 19 | }, 20 | ], 21 | mono: ["IBM Plex Mono", ...defaultTheme.fontFamily.mono], 22 | }, 23 | }, 24 | }, 25 | plugins: [ 26 | // Use the standard typography plugin 27 | require("@tailwindcss/typography"), 28 | ], 29 | // Use a selector to set dark mode. 30 | darkMode: "selector", 31 | }; 32 | -------------------------------------------------------------------------------- /hipcheck/src/target/tests/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-app", 3 | "version": "0.2.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | }, 8 | "dependencies": { 9 | "@bugsounet/node-lpcm16": { 10 | "version": "1.0.2", 11 | "resolved": "https://registry.npmjs.org/@bugsounet/node-lpcm16/-/node-lpcm16-1.0.2.tgz", 12 | "integrity": "sha512-PZ3EUZ7C2V1hYNSsHQLW+vy/xKbKeeBwbL4mVYNdaxRjf3ByYF/Udu8qQX9zpRTBD2D3VYq5dtEMS0aD2g6IEQ==", 13 | "requires": { 14 | "child_process": "^1.0.2" 15 | } 16 | }, 17 | "child_process": { 18 | "version": "1.0.2", 19 | "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", 20 | "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==" 21 | }, 22 | "chownr": { 23 | "version": "2.0.0", 24 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 25 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /xtask/src/task/benchmark/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use std::{num::NonZeroUsize, path::PathBuf}; 4 | 5 | #[cfg(not(target_os = "linux"))] 6 | mod non_linux { 7 | use super::BenchmarkArgs; 8 | use anyhow::Result; 9 | 10 | pub fn run(_args: BenchmarkArgs) -> Result<()> { 11 | panic!("benchmark is currently only available on Linux") 12 | } 13 | } 14 | 15 | #[cfg(not(target_os = "linux"))] 16 | pub use non_linux::run; 17 | 18 | #[cfg(target_os = "linux")] 19 | mod linux; 20 | #[cfg(target_os = "linux")] 21 | pub use linux::run; 22 | 23 | #[derive(Debug, clap::Args)] 24 | pub struct BenchmarkArgs { 25 | /// number of runs to perform for each benchmark target 26 | #[arg(long = "runs", short = 'r', default_value_t = NonZeroUsize::new(3).unwrap())] 27 | runs: NonZeroUsize, 28 | /// path to file contain configuration for running benchmarks 29 | #[arg(long = "config", short = 'c')] 30 | config: PathBuf, 31 | /// path to directory to write results should be written, results will be appended to a CSV 32 | /// file per metric 33 | #[arg(long = "output", short = 'o')] 34 | output_dir: PathBuf, 35 | } 36 | -------------------------------------------------------------------------------- /site/templates/partials/prose-config.tera.html: -------------------------------------------------------------------------------- 1 | prose dark:prose-invert 2 | 3 | prose-code:before:content-none 4 | prose-code:after:content-none 5 | prose-code:font-normal 6 | prose-code:py-1 prose-code:px-2 7 | prose-code:rounded-md 8 | prose-code:bg-neutral-100 9 | dark:prose-code:bg-neutral-700 10 | [&_pre_code]:bg-inherit 11 | [&_pre_code]:p-0 12 | [&_pre_code]:rounded-none 13 | [&_.info_code]:bg-neutral-200 14 | dark:[&_.info_code]:bg-neutral-700 15 | 16 | prose-a:font-normal 17 | hover:prose-a:text-blue-500 18 | 19 | prose-h3:font-medium 20 | prose-h3:pt-4 21 | prose-h3:border-t 22 | prose-h3:border-neutral-300 23 | dark:prose-h3:border-neutral-600 24 | prose-h3:mt-16 25 | prose-h3:mb-8 26 | prose-h3:text-2xl 27 | 28 | prose-h2:font-medium 29 | prose-h2:text-3xl 30 | prose-h2:mt-12 31 | prose-h2:pt-8 32 | prose-h2:mb-8 33 | prose-h2:text-black 34 | dark:prose-h2:text-neutral-100 35 | 36 | prose-h1:font-medium 37 | prose-h1:text-4xl 38 | 39 | prose-table:border 40 | prose-table:border-neutral-300 41 | prose-table:dark:border-neutral-700 42 | 43 | prose-td:p-3 44 | prose-th:p-3 45 | prose-th:bg-neutral-100 46 | prose-th:dark:bg-neutral-600 47 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc setup 3 | extra: 4 | nav_title: "hc setup" 5 | --- 6 | 7 | # `hc setup` 8 | 9 | The `hc setup` command is intended to be run after first installing Hipcheck, 10 | and again after updating Hipcheck, to ensure you have the required configuration 11 | and data files needed for Hipcheck to run. 12 | 13 | When installing Hipcheck, regardless of method, you are only installing the 14 | `hc` binary, not these additional configuration files. `hc setup` identifies 15 | the correct location in your system for configuration files and writes the 16 | files to that directory. 17 | 18 | It also produces an export command that should be used to set the `HC_CONFIG` 19 | environmental variable to the relevant directory, as necessary to run `hc check`. 20 | 21 | Please note that in some cases, `hc setup` may default to a directory that 22 | requires escalated privileges. You can resolve this by running `sudo hc setup` or 23 | passing in the your desired directory with `hc setup --config [directory path]`. 24 | 25 | `hc setup` supports Hipcheck's [General Flags](@/docs/guide/cli/general-flags.md). 26 | -------------------------------------------------------------------------------- /tests/test-plugins/activity-container/activity-container-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Default values 4 | IMAGE_TAR="./tests/test-plugins/activity-container/activity-image.tar" 5 | IMAGE_NAME="activity-image" 6 | PORT=8888 7 | 8 | while [[ $# -gt 0 ]]; do 9 | if [[ "$1" == "--port" && -n "$2" && "$2" =~ ^[0-9]+$ ]]; then 10 | PORT="$2" 11 | shift 2 12 | else 13 | # Collect any other arguments to pass to docker run 14 | EXTRA_ARGS="$EXTRA_ARGS $1" 15 | shift 16 | fi 17 | done 18 | 19 | if [[ ! -f "$IMAGE_TAR" ]]; then 20 | echo "Error: Image tar file '$IMAGE_TAR' not found!" 21 | exit 1 22 | fi 23 | 24 | 25 | # Check if the image is already loaded 26 | if ! docker images | grep -q "$IMAGE_NAME"; then 27 | echo "Image '$IMAGE_NAME' not found. Loading the image..." 28 | if ! docker load -i "$IMAGE_TAR" > /dev/null 2>&1; then 29 | echo "Error: Failed to load image '$IMAGE_TAR'." 30 | exit 1 31 | fi 32 | fi 33 | # Otherwise, the image is already loaded 34 | 35 | # Format the run statement for container port mapping 36 | docker run --init -p "$PORT":50051 activity-image 37 | -------------------------------------------------------------------------------- /sdk/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "hipcheck-sdk" 3 | version = "0.2.1" 4 | description = "An SDK for developing Hipcheck plugins" 5 | readme = "README.md" 6 | authors = [ 7 | { name = "j-lanson", email = "jlanson@mitre.org" } 8 | ] 9 | requires-python = ">=3.10" 10 | classifiers = [ 11 | "Programming Language :: Python :: 3", 12 | "Operating System :: OS Independent" 13 | ] 14 | license = "Apache-2.0" 15 | license-files = ["LICENSE"] 16 | 17 | dependencies = [ 18 | "asyncio>=3.4.3", 19 | "coverage>=7.6.12", 20 | "datamodel-code-generator>=0.28.5", 21 | "grpcio>=1.70.0", 22 | "grpcio-tools>=1.70.0", 23 | "logging>=0.4.9.6", 24 | "pydantic>=2.10.6", 25 | "pytest>=8.3.5", 26 | "pytest-asyncio>=0.26.0", 27 | "sphinx>=8.1.3", 28 | "wheel>=0.45.1", 29 | ] 30 | 31 | [project.urls] 32 | Homepage = "https://hipcheck.mitre.org/" 33 | Documentation = "https://hipcheck.mitre.org/sdk/python/hipcheck_sdk.html" 34 | Repository = "https://github.com/mitre/hipcheck.git" 35 | Issues = "https://github.com/mitre/hipcheck/issues" 36 | 37 | [build-system] 38 | requires = ["hatchling"] 39 | build-backend = "hatchling.build" 40 | -------------------------------------------------------------------------------- /hipcheck/src/init/indicatif_log_bridge.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! The `indicatif-log-bridge` crate discards filtering information when using env_logger, so I'm writting my own. 4 | 5 | use crate::shell::Shell; 6 | use env_logger::Logger; 7 | use log::SetLoggerError; 8 | 9 | pub struct LogWrapper(pub Logger); 10 | 11 | impl log::Log for LogWrapper { 12 | fn enabled(&self, metadata: &log::Metadata) -> bool { 13 | self.0.enabled(metadata) 14 | } 15 | 16 | fn log(&self, record: &log::Record) { 17 | // Don't suspend the shell if we're not gonna log the message. 18 | if log::logger().enabled(record.metadata()) { 19 | Shell::in_suspend(|| self.0.log(record)) 20 | } 21 | } 22 | 23 | fn flush(&self) { 24 | Shell::in_suspend(|| self.0.flush()) 25 | } 26 | } 27 | 28 | impl LogWrapper { 29 | pub fn try_init(self) -> Result<(), SetLoggerError> { 30 | if !Shell::is_init() { 31 | panic!("Initialize the global shell before initializing this logger"); 32 | } 33 | 34 | let max_filter_level = self.0.filter(); 35 | 36 | log::set_boxed_logger(Box::new(self))?; 37 | 38 | log::set_max_level(max_filter_level); 39 | 40 | Ok(()) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /plugins/churn/src/metric.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use std::iter::Iterator; 4 | 5 | /// Calculate the arithmetic mean for a set of floats. Returns an option to account 6 | /// for the possibility of dividing by zero. 7 | pub fn mean(data: &[f64]) -> Option { 8 | // Do not use rayon's parallel iter/sum here due to the non-associativity of floating point numbers/math. 9 | // See: https://en.wikipedia.org/wiki/Associative_property#Nonassociativity_of_floating_point_calculation. 10 | let sum = data.iter().sum::(); 11 | let count = data.len(); 12 | 13 | match count { 14 | positive if positive > 0 => Some(sum / count as f64), 15 | _ => None, 16 | } 17 | } 18 | 19 | /// Calculate the standard deviation for a set of floats. Returns an option to 20 | /// account for the possibility of dividing by zero. 21 | pub fn std_dev(mean: f64, data: &[f64]) -> Option { 22 | match (mean, data.len()) { 23 | (mean, count) if count > 0 => { 24 | let variance = 25 | data.iter() 26 | .map(|value| { 27 | let diff = mean - *value; 28 | diff * diff 29 | }) 30 | .sum::() / count as f64; 31 | 32 | Some(variance.sqrt()) 33 | } 34 | _ => None, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugins/github/src/github/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | pub mod graphql; 4 | pub mod rest; 5 | 6 | use crate::{ 7 | github::{ 8 | graphql::{ 9 | reviews::{GitHubPullRequest, get_reviews}, 10 | user_orgs::{UserOrgData, get_user_orgs}, 11 | }, 12 | rest::code_search::check_fuzzing, 13 | }, 14 | tls::authenticated_agent::AuthenticatedAgent, 15 | }; 16 | use anyhow::{Context, Result}; 17 | 18 | pub struct GitHub<'a> { 19 | agent: AuthenticatedAgent<'a>, 20 | } 21 | 22 | impl<'a> GitHub<'a> { 23 | pub fn new(token: &'a str) -> Result> { 24 | Ok(GitHub { 25 | agent: AuthenticatedAgent::new(token)?, 26 | }) 27 | } 28 | 29 | pub fn check_fuzzing(&self, repo_uri: &str) -> Result { 30 | check_fuzzing(&self.agent, repo_uri).context("unable to search fuzzing information; please ensure the provided system environment variable exists and contains a valid GitHub API token") 31 | } 32 | 33 | pub fn get_reviews(&self, owner: &str, repo: &str) -> Result> { 34 | get_reviews(&self.agent, owner, repo) 35 | } 36 | 37 | pub fn get_user_orgs(&self, user_login: &str) -> Result { 38 | get_user_orgs(&self.agent, user_login) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /hipcheck/src/setup.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::error::Result; 4 | use std::io::Write; 5 | use std::{fs::File, path::Path}; 6 | 7 | static BINARY_KDL: &str = include_str!("../../config/Binary.kdl"); 8 | static EXEC_KDL: &str = include_str!("../../config/Exec.kdl"); 9 | static HIPCHECK_KDL: &str = include_str!("../../config/Hipcheck.kdl"); 10 | static HIPCHECK_TOML: &str = include_str!("../../config/Hipcheck.toml"); 11 | static LANGS_KDL: &str = include_str!("../../config/Langs.kdl"); 12 | static ORGS_KDL: &str = include_str!("../../config/Orgs.kdl"); 13 | static TYPOS_KDL: &str = include_str!("../../config/Typos.kdl"); 14 | 15 | pub fn write_config_binaries(path: &Path) -> Result<()> { 16 | std::fs::create_dir_all(path)?; 17 | 18 | let files = [ 19 | ("Langs.kdl", LANGS_KDL), 20 | ("Typos.kdl", TYPOS_KDL), 21 | ("Binary.kdl", BINARY_KDL), 22 | ("Exec.kdl", EXEC_KDL), 23 | ("Hipcheck.kdl", HIPCHECK_KDL), 24 | ("Hipcheck.toml", HIPCHECK_TOML), 25 | ("Orgs.kdl", ORGS_KDL), 26 | ]; 27 | 28 | for (file_name, content) in &files { 29 | let file_path = path.join(file_name); 30 | let mut file = File::create(file_path)?; 31 | file.write_all(content.as_bytes())?; 32 | } 33 | 34 | Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /site/static/js/header.mjs: -------------------------------------------------------------------------------- 1 | function o(e){let t=document.querySelectorAll(e);if(t===null)throw new n(`could not find all '${e}'`);return Array.from(t)}var n=class extends Error{constructor(t){super(t)}};function s(){let e=localStorage.getItem("theme")??"system";switch(e){case"dark":return e;case"light":return e;case"system":return e;default:throw new r(e)}}function c(e){if(e===void 0)throw new r(e);switch(e){case"system":switch(localStorage.removeItem("theme"),d()){case"dark":document.documentElement.classList.add("dark");break;case"light":document.documentElement.classList.remove("dark");break}break;case"light":localStorage.setItem("theme",e),document.documentElement.classList.remove("dark");break;case"dark":localStorage.setItem("theme",e),document.documentElement.classList.add("dark");break;default:throw new r(e)}l(e)}function l(e){o(".theme-option").forEach(t=>{t.dataset.theme===e?t.dataset.active="true":delete t.dataset.active})}function d(){return globalThis.window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}var r=class extends Error{constructor(t){super(`could not determine theme: '${t||"undefined"}'`)}};function a(){c(s())}function u(){a()}(function(){try{u()}catch(e){console.error(e)}})(); 2 | //# sourceMappingURL=header.mjs.map 3 | -------------------------------------------------------------------------------- /library/hipcheck-common/src/lib.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::anyhow; 4 | 5 | use std::{result::Result as StdResult, str::FromStr}; 6 | 7 | pub mod chunk; 8 | pub mod error; 9 | pub mod types; 10 | 11 | pub mod proto { 12 | include!(concat!(env!("OUT_DIR"), "/hipcheck.v1.rs")); 13 | } 14 | 15 | pub struct QueryTarget { 16 | pub publisher: String, 17 | pub plugin: String, 18 | pub query: Option, 19 | } 20 | 21 | impl FromStr for QueryTarget { 22 | type Err = anyhow::Error; 23 | 24 | fn from_str(s: &str) -> StdResult { 25 | let parts: Vec<&str> = s.split('/').collect(); 26 | match parts.as_slice() { 27 | [publisher, plugin, query] => Ok(Self { 28 | publisher: publisher.to_string(), 29 | plugin: plugin.to_string(), 30 | query: Some(query.to_string()), 31 | }), 32 | [publisher, plugin] => Ok(Self { 33 | publisher: publisher.to_string(), 34 | plugin: plugin.to_string(), 35 | query: None, 36 | }), 37 | _ => Err(anyhow!("Invalid query target string '{}'", s)), 38 | } 39 | } 40 | } 41 | 42 | impl TryInto for &str { 43 | type Error = anyhow::Error; 44 | fn try_into(self) -> StdResult { 45 | QueryTarget::from_str(self) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /site/content/docs/getting-started/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | template: docs.html 4 | page_template: docs_page.html 5 | weight: 1 6 | sort_by: weight 7 | aliases: 8 | - "/quickstart" 9 | --- 10 | 11 | # Getting Started 12 | 13 | Hello, and welcome! This is a "Quickstart" guide to Hipcheck, which means our 14 | goal with this guide is to get you up and running as a user of Hipcheck as 15 | quickly as possible. If you'd like a more thorough guide to Hipcheck which 16 | explains its core concepts, how it works under the hood, and how to configure 17 | it to your heart's content, we recommend the [Complete Guide](@/docs/guide/_index.md). 18 | 19 | 20 |
21 | 22 | {% waypoint(title="Install Hipcheck", path="@/docs/getting-started/install.md", icon="download") %} 23 | A guide to all methods for installing Hipcheck. 24 | {% end %} 25 | 26 | {% waypoint(title="Why Hipcheck?", path="@/docs/getting-started/why.md", icon="book-open") %} 27 | Some history on the creation and purpose of Hipcheck. 28 | {% end %} 29 | 30 | 31 | {% waypoint(title="Quickstart: Your First Analysis", path="@/docs/getting-started/first-run.md", icon="watch") %} 32 | A walkthrough of running Hipcheck for the first time. 33 | {% end %} 34 | 35 |
36 | -------------------------------------------------------------------------------- /sdk/python/docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # For the full list of built-in configuration values, see the documentation: 6 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 7 | 8 | import os 9 | import sys 10 | 11 | sys.path.insert(0, os.path.abspath("../../src/hipcheck_sdk")) 12 | 13 | # -- Project information ----------------------------------------------------- 14 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 15 | 16 | project = "hipcheck-sdk" 17 | copyright = "2025, Julian Lanson" 18 | author = "Julian Lanson" 19 | release = "0.2.1" 20 | 21 | # -- General configuration --------------------------------------------------- 22 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 23 | 24 | extensions = [ 25 | "sphinx.ext.viewcode", 26 | "sphinx.ext.autodoc", 27 | ] 28 | 29 | templates_path = ["_templates"] 30 | exclude_patterns = [] 31 | 32 | 33 | # -- Options for HTML output ------------------------------------------------- 34 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 35 | 36 | html_theme = "alabaster" 37 | html_static_path = ["_static"] 38 | -------------------------------------------------------------------------------- /sdk/python/tests/test_mock_responses.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | import pytest 4 | import asyncio 5 | 6 | from hipcheck_sdk import * 7 | from hipcheck_sdk.error import UnknownPluginQuery 8 | 9 | 10 | def test_mock_responses(): 11 | expected = 2 12 | engine = PluginEngine.mock([(("mitre/example/nondefault", 1), expected)]) 13 | try: 14 | res = asyncio.run(engine.query("mitre/example", 1)) 15 | assert false 16 | except UnknownPluginQuery: 17 | pass 18 | try: 19 | res = asyncio.run(engine.query("mitre/example/nondefault", 2)) 20 | assert false 21 | except UnknownPluginQuery: 22 | pass 23 | 24 | res = asyncio.run(engine.query("mitre/example/nondefault", 1)) 25 | assert res == expected 26 | 27 | engine = PluginEngine.mock( 28 | [ 29 | (("mitre/example", 1), 1), 30 | (("mitre/example", 2), 2), 31 | (("mitre/example", 3), 3), 32 | ] 33 | ) 34 | 35 | async def run(engine): 36 | builder = engine.batch("mitre/example") 37 | builder.query(1) 38 | builder.query(2) 39 | builder.query(3) 40 | 41 | return await builder.send() 42 | 43 | res = asyncio.run(run(engine)) 44 | assert res == [1, 2, 3] 45 | -------------------------------------------------------------------------------- /site/content/docs/guide/concepts/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Key Concepts 3 | template: docs.html 4 | page_template: docs_page.html 5 | sort_by: weight 6 | weight: 1 7 | --- 8 | 9 | # Key Concepts 10 | 11 | To understand Hipcheck, it's useful to understand some of the key concepts 12 | underlying its design, which we'll explore here. 13 | 14 | 15 |
16 | 17 | {% waypoint(title="Targets", path="@/docs/guide/concepts/targets.md", icon="target") %} 18 | How Hipcheck identifies what package or project to analyze. 19 | {% end %} 20 | 21 | {% waypoint(title="Data", path="@/docs/guide/concepts/data/index.md", icon="database") %} 22 | How Hipcheck collects data from external sources. 23 | {% end %} 24 | 25 | {% waypoint(title="Analyses", path="@/docs/guide/concepts/analyses.md", icon="alert-triangle") %} 26 | What kinds of analyses Hipcheck is focused on. 27 | {% end %} 28 | 29 | {% waypoint(title="Scoring", path="@/docs/guide/concepts/scoring/index.md", icon="activity") %} 30 | How Hipcheck converts individual analysis results into a risk score. 31 | {% end %} 32 | 33 | {% waypoint(title="Concerns", path="@/docs/guide/concepts/concerns.md", icon="list") %} 34 | How plugins report extra information to support manual analysis. 35 | {% end %} 36 | 37 |
38 | -------------------------------------------------------------------------------- /.config/hakari.toml: -------------------------------------------------------------------------------- 1 | # This file contains settings for `cargo hakari`. 2 | # See https://docs.rs/cargo-hakari/latest/cargo_hakari/config for a full list of options. 3 | 4 | hakari-package = "hipcheck-workspace-hack" 5 | 6 | # Format version for hakari's output. Version 4 requires cargo-hakari 0.9.22 or above. 7 | dep-format-version = "4" 8 | 9 | # Setting workspace.resolver = "2" or higher in the root Cargo.toml is HIGHLY recommended. 10 | # Hakari works much better with the v2 resolver. (The v2 and v3 resolvers are identical from 11 | # hakari's perspective, so you're welcome to set either.) 12 | # 13 | # For more about the new feature resolver, see: 14 | # https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#cargos-new-feature-resolver 15 | resolver = "2" 16 | 17 | # Add triples corresponding to platforms commonly used by developers here. 18 | # https://doc.rust-lang.org/rustc/platform-support.html 19 | platforms = [ 20 | "x86_64-unknown-linux-gnu", 21 | "x86_64-apple-darwin", 22 | "aarch64-apple-darwin", 23 | "x86_64-pc-windows-msvc", 24 | ] 25 | 26 | # Write out exact versions rather than a semver range. (Defaults to false.) 27 | exact-versions = true 28 | 29 | # Don't include 'xtask' in cargo-hakari's workspace hack calculations. 30 | [traversal-excludes] 31 | workspace-members = ["xtask"] 32 | -------------------------------------------------------------------------------- /hipcheck/src/shell/verbosity.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Utilities for managing and controlling the verbosity of hipcheck. 4 | 5 | use super::Shell; 6 | 7 | /// How verbose CLI output should be. 8 | #[derive(Debug, Default, Copy, Clone, PartialEq, clap::ValueEnum)] 9 | pub enum Verbosity { 10 | /// Output results, not progress indicators. 11 | Quiet, 12 | /// Output results and progress indicators. 13 | #[default] 14 | Normal, 15 | // This one is only used in testing. 16 | /// Do not output anything. 17 | #[value(hide = true)] 18 | Silent, 19 | } 20 | 21 | impl Verbosity { 22 | /// [Verbosity::Quiet] if `quiet` is true, [Verbosity::Normal] otherwise. 23 | pub fn use_quiet(quiet: bool) -> Verbosity { 24 | if quiet { 25 | Verbosity::Quiet 26 | } else { 27 | Verbosity::Normal 28 | } 29 | } 30 | } 31 | 32 | /// A [SilenceGuard] is created by calling [Shell::silence], which returns an opaque 33 | /// value of this type. Once that value is [drop]ped, the global [Shell]'s verbosity is set to 34 | /// whatever it was prior to calling [Shell::silence]. 35 | #[derive(Debug)] 36 | pub struct SilenceGuard { 37 | pub(super) previous_verbosity: Verbosity, 38 | } 39 | 40 | impl Drop for SilenceGuard { 41 | fn drop(&mut self) { 42 | Shell::set_verbosity(self.previous_verbosity); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-fuzz.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/fuzz" 3 | extra: 4 | nav_title: "mitre/fuzz" 5 | --- 6 | 7 | # `mitre/fuzz` 8 | 9 | Checks if a project participates in OSS Fuzz. 10 | 11 | ## Configuration 12 | 13 | None 14 | 15 | ## Default Policy Expression 16 | 17 | ``` 18 | (eq $ #t) 19 | ``` 20 | 21 | ## Default Query: `mitre/fuzz` 22 | 23 | Returns `true` if the project _does_ participate in OSS Fuzz, `false` otherwise. 24 | 25 | ## Explanation 26 | 27 | Repos being checked by Hipcheck may receive regular fuzz testing. This analysis 28 | checks if the repo is participating in the OSS Fuzz program. If it is fuzzed, 29 | this is considered a signal of a repository being lower risk. 30 | 31 | ## Limitations 32 | 33 | * __Not all languagues supported__: Robust fuzzing tools do not exist for every 34 | language. It is possible fuzz testing was not done because no good option for it 35 | existed at the time. Lack of fuzzing in those cases would still indicate a higher 36 | risk, but it would not necessarily indicate bad software development practices. 37 | * __Only OSS Fuzz checked__: At this time, Hipcheck only checks if the repo 38 | participates in Google's OSS Fuzz. Other fuzz testing programs exist, but a repo 39 | will not pass this analysis if it uses one of those instead. 40 | -------------------------------------------------------------------------------- /hipcheck/src/init/git2_log_shim.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Log shim function to redirect [git2] trace messages to [log]. 4 | 5 | use crate::hc_error; 6 | 7 | /// Shim the [git2] crate's tracing infrastructure with calls to the [log] crate which we use. 8 | pub fn git2_set_trace_log_shim() { 9 | git2::trace_set(git2::TraceLevel::Trace, |level, msg| { 10 | use git2::TraceLevel; 11 | use log::{Level, RecordBuilder}; 12 | 13 | // Coerce fatal down to error since there's no trivial equivalent. 14 | let log_level = match level { 15 | TraceLevel::Debug => Level::Debug, 16 | TraceLevel::Fatal | TraceLevel::Error => Level::Error, 17 | TraceLevel::Warn => Level::Warn, 18 | TraceLevel::Info => Level::Info, 19 | TraceLevel::Trace => Level::Trace, 20 | // git2 should not produce trace messages with no level. 21 | other @ TraceLevel::None => panic!("Unsupported git2 log level: {other:?}"), 22 | }; 23 | 24 | let mut record_builder = RecordBuilder::new(); 25 | 26 | record_builder.level(log_level).target("libgit2"); 27 | 28 | let msg_str = std::str::from_utf8(msg).unwrap_or("non-UTF8 string received in callback"); 29 | 30 | log::logger().log(&record_builder.args(format_args!("{}", msg_str)).build()); 31 | }) 32 | .map_err(|e| hc_error!("Failed to set git2 callback: {}", e)) 33 | .unwrap(); 34 | } 35 | -------------------------------------------------------------------------------- /plugins/churn/src/types.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use schemars::JsonSchema; 4 | use serde::{Deserialize, Serialize}; 5 | use std::result::Result; 6 | 7 | #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, JsonSchema)] 8 | pub struct Commit { 9 | pub hash: String, 10 | pub written_on: Result, 11 | pub committed_on: Result, 12 | } 13 | 14 | #[derive(Clone, Debug, Serialize, PartialEq, Eq, JsonSchema, Deserialize)] 15 | pub struct FileDiff { 16 | pub file_name: String, 17 | pub additions: Option, 18 | pub deletions: Option, 19 | pub patch: String, 20 | } 21 | 22 | #[derive(Clone, Debug, Serialize, PartialEq, Eq, JsonSchema, Deserialize)] 23 | pub struct Diff { 24 | pub additions: Option, 25 | pub deletions: Option, 26 | pub file_diffs: Vec, 27 | } 28 | 29 | #[derive(Debug, Serialize, PartialEq, Eq, JsonSchema, Deserialize)] 30 | pub struct CommitDiff { 31 | pub commit: Commit, 32 | pub diff: Diff, 33 | } 34 | 35 | #[derive(Debug, Clone, JsonSchema, Serialize)] 36 | pub struct CommitChurnFreq { 37 | /// The commit 38 | pub commit: Commit, 39 | /// The churn score 40 | pub churn: f64, 41 | } 42 | 43 | #[derive(Debug)] 44 | pub struct CommitChurn { 45 | pub commit: Commit, 46 | pub files_changed: i64, 47 | pub lines_changed: i64, 48 | } 49 | -------------------------------------------------------------------------------- /site/content/docs/rfds/0010-submit-chunking.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Submit Chunking 3 | weight: 10 4 | slug: 0010 5 | extra: 6 | rfd: 10 7 | primary_author: Julian Lanson 8 | primary_author_link: https://github.com/j-lanson 9 | status: Accepted 10 | --- 11 | 12 | # Submit Chunking 13 | 14 | We propose to update Hipcheck's gRPC protocol 15 | to support `Submit` (outbound) query chunking. Currently, there is a query state 16 | `ReplyInProgress` to indicate when a query response is one chunk in a series of 17 | fragmented response messages, and that they should be combined on the receiving 18 | side into a single message. The `ReplyComplete` state indicates that the current 19 | reply message will not be followed by any additional chunks. 20 | 21 | When initially designing the protocol we did not expect that there would be a 22 | need for an analogous system on the outbound side, but after having run Hipcheck 23 | against the Linux kernel we encountered such a need. This RFD proposes to rename 24 | the existing `Submit` query state to `SubmitComplete` and to add another variant 25 | to the `QueryState` enum called `SubmitInProgress`. According to the gRPC 26 | documentation, renaming a field does not break backwards compatibility. 27 | 28 | `Submit` query chunking will use the exact same chunking algorithm as `Reply`, 29 | but will look for different `QueryState` variants. 30 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-activity.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/activity" 3 | extra: 4 | nav_title: "mitre/activity" 5 | --- 6 | 7 | # `mitre/activity` 8 | 9 | Determines if a project is actively maintained. 10 | 11 | ## Configuration 12 | 13 | | Parameter | Type | Explanation | 14 | |:----------|:----------|:--------------| 15 | | `weeks` | `Integer` | The permitted number of weeks before a project is considered inactive. | 16 | 17 | ## Default Policy Expression 18 | 19 | ``` 20 | (lte $ P{config.weeks or 71}w) 21 | ``` 22 | 23 | ## Default Query: `mitre/activity` 24 | 25 | Returns a `Span` representing the time from the most recent commit to now. 26 | 27 | ## Limitations 28 | 29 | * __Cases where lack of updates is warranted__: Sometimes work on a piece of 30 | software stops because it is complete, and there is no longer a need to 31 | update it. In this case, a repository being flagged as failing this analysis 32 | may not be truly risky for lack of activity. However, _most of the time_ 33 | we expect that lack of updates ought to be concern, and so considering this 34 | metric when analyzing software supply chain risk is reasonable. If you 35 | are in a context where lack of updates is desirable or not concerning, you 36 | may consider changing the configuration to a different duration, or disabling 37 | the analysis entirely. 38 | -------------------------------------------------------------------------------- /sdk/python/docs/source/hipcheck_sdk.rst: -------------------------------------------------------------------------------- 1 | hipcheck\_sdk package 2 | ===================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | Submodules 8 | ---------- 9 | 10 | hipcheck\_sdk.cli module 11 | ------------------------ 12 | 13 | .. automodule:: hipcheck_sdk.cli 14 | :members: 15 | :undoc-members: 16 | :show-inheritance: 17 | 18 | hipcheck\_sdk.engine module 19 | --------------------------- 20 | 21 | .. automodule:: hipcheck_sdk.engine 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | 26 | hipcheck\_sdk.error module 27 | -------------------------- 28 | 29 | .. automodule:: hipcheck_sdk.error 30 | :members: 31 | :undoc-members: 32 | :show-inheritance: 33 | 34 | hipcheck\_sdk.options module 35 | ---------------------------- 36 | 37 | .. automodule:: hipcheck_sdk.options 38 | :members: 39 | :undoc-members: 40 | :show-inheritance: 41 | 42 | hipcheck\_sdk.query module 43 | -------------------------- 44 | 45 | .. automodule:: hipcheck_sdk.query 46 | :members: 47 | :undoc-members: 48 | :show-inheritance: 49 | 50 | hipcheck\_sdk.server module 51 | --------------------------- 52 | 53 | .. automodule:: hipcheck_sdk.server 54 | :members: 55 | :undoc-members: 56 | :show-inheritance: 57 | 58 | 59 | Module contents 60 | --------------- 61 | 62 | .. automodule:: hipcheck_sdk 63 | :members: 64 | :undoc-members: 65 | :show-inheritance: 66 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | mod download_manifest; 4 | mod kdl; 5 | mod local; 6 | mod remote; 7 | mod util; 8 | 9 | use download_manifest::DownloadManifestEntry; 10 | 11 | use anyhow::Result; 12 | use std::collections::HashSet; 13 | 14 | #[allow(unused)] 15 | pub use kdl::ParseKdlNode; 16 | 17 | pub fn run() -> Result<()> { 18 | let api_token = std::env::var("HC_GITHUB_TOKEN")?; 19 | let releases = remote::get_hipcheck_plugin_releases(&api_token)?; 20 | 21 | for (name, remote_entries) in releases.0 { 22 | // We know all releases off the hipcheck github repo are mitre-published 23 | let local_manifest_path = local::get_download_manifest_path("mitre", &name)?; 24 | let local_entries = local::try_parse_download_manifest(&local_manifest_path)?; 25 | 26 | let remote_set = HashSet::::from_iter(remote_entries.into_iter()); 27 | let local_set = HashSet::::from_iter(local_entries.into_iter()); 28 | 29 | let diff = remote_set.difference(&local_set); 30 | let diff_vec = diff.collect::>(); 31 | 32 | if diff_vec.is_empty() { 33 | continue; 34 | } 35 | log::info!( 36 | "Updating download manifest for '{}' with {} new entries", 37 | name, 38 | diff_vec.len() 39 | ); 40 | 41 | local::append_entries_to_file(local_manifest_path, diff_vec.into_iter())?; 42 | } 43 | 44 | Ok(()) 45 | } 46 | -------------------------------------------------------------------------------- /site/content/docs/guide/making-plugins/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Making Plugins 3 | weight: 6 4 | template: docs.html 5 | page_template: docs_page.html 6 | sort_by: weight 7 | --- 8 | 9 | # Making Plugins 10 | 11 | The following is a guide for making plugins for Hipcheck. Plugins can add new 12 | data source and new analyses, and can be written using an SDK or by hand. The 13 | rest of this section details the protocols plugins are expected to follow. 14 | 15 |
16 | 17 | {% waypoint(title="Creating a Plugin", path="@/docs/guide/making-plugins/creating-a-plugin.md", icon="box") %} 18 | How to start making a new Hipcheck plugin. 19 | {% end %} 20 | 21 | {% waypoint(title="The Rust Plugin SDK", path="@/docs/guide/making-plugins/rust-sdk.md", icon="tool") %} 22 | How to use the Rust SDK to create a plugin. 23 | {% end %} 24 | 25 | {% waypoint(title="The Python Plugin SDK", path="@/docs/guide/making-plugins/python-sdk.md", icon="tool") %} 26 | How to use the Python SDK to create a plugin. 27 | {% end %} 28 | 29 | {% waypoint(title="The Query Protocol", path="@/docs/guide/making-plugins/query-protocol.md", icon="tool") %} 30 | A description of the query protocol for non-SDK users. 31 | {% end %} 32 | 33 | {% waypoint(title="Packaging and Releasing a Plugin", path="@/docs/guide/making-plugins/release.md", icon="tool") %} 34 | How to prepare a plugin for use and release. 35 | {% end %} 36 | 37 |
38 | -------------------------------------------------------------------------------- /site/scripts/src/util/web.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * document.querySelector with type conversion and error handling. 3 | */ 4 | export function querySelector(selector: string): HTMLElement { 5 | const $elem = document.querySelector(selector); 6 | if ($elem === null) throw new QueryError(`could not find ${selector}`); 7 | return $elem as HTMLElement; 8 | } 9 | 10 | /** 11 | * document.querySelectorAll with type conversions and error handling. 12 | */ 13 | export function querySelectorAll(selector: string): Array { 14 | const $elems = document.querySelectorAll(selector); 15 | if ($elems === null) throw new QueryError(`could not find all '${selector}'`); 16 | return Array.from($elems) as Array; 17 | } 18 | 19 | /** 20 | * navigator.clipboard.writeText with error handling. 21 | */ 22 | export function copyToClipboard(text: string) { 23 | navigator.clipboard.writeText(text).then(null, (reason) => { 24 | throw new ClipboardError(reason); 25 | }); 26 | } 27 | 28 | /** 29 | * Indicates an error while attempting to put data into the clipboard. 30 | */ 31 | class ClipboardError extends Error { 32 | constructor(source: unknown) { 33 | super(`clipboard copy rejected: '${source}'`); 34 | } 35 | } 36 | 37 | /** 38 | * Indicates an error while trying to select one or more elements on the page. 39 | */ 40 | class QueryError extends Error { 41 | constructor(msg: string) { 42 | super(msg); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /plugins/typo/src/util/fs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use anyhow::{Context as _, Result, anyhow}; 4 | use hipcheck_kdl::kdl::KdlDocument; 5 | use hipcheck_kdl::{ParseKdlNode, extract_data}; 6 | use miette::Report; 7 | use std::{fs, path::Path, str::FromStr}; 8 | 9 | /// Read a file to a string. 10 | pub fn read_string>(path: P) -> Result { 11 | fn inner(path: &Path) -> Result { 12 | fs::read_to_string(path) 13 | .with_context(|| format!("failed to read as UTF-8 string '{}'", path.display())) 14 | } 15 | 16 | inner(path.as_ref()) 17 | } 18 | 19 | /// Read file to a struct that can be deserialized from kdl format. 20 | pub fn read_kdl, T: ParseKdlNode>(path: P) -> Result { 21 | let path = path.as_ref(); 22 | let contents = read_string(path)?; 23 | // Print miette::Report with Debug for full help text 24 | let document = KdlDocument::from_str(&contents) 25 | .map_err(|e| anyhow!("File doesn't parse as valid KDL:\n{:?}", Report::from(e)))?; 26 | let nodes = document.nodes(); 27 | extract_data(nodes).ok_or(anyhow!("Could not parse typo KDL 'format'")) 28 | } 29 | 30 | /// Check that a given path exists. 31 | pub fn exists>(path: P) -> Result<()> { 32 | fn inner(path: &Path) -> Result<()> { 33 | if !path.exists() { 34 | Err(anyhow!("'{}' not found", path.display())) 35 | } else { 36 | Ok(()) 37 | } 38 | } 39 | 40 | inner(path.as_ref()) 41 | } 42 | -------------------------------------------------------------------------------- /site/content/docs/contributing/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contribute 3 | template: docs.html 4 | sort_by: weight 5 | page_template: docs_page.html 6 | aliases: 7 | - "/contribute/_index.md" 8 | weight: 3 9 | --- 10 | 11 | # Contribute to Hipcheck 12 | 13 | The Hipcheck project is happy to accept contributions! 14 | 15 |
16 | 17 | {% waypoint(title="Coordinating Changes", path="@/docs/contributing/coordinating-changes.md", icon="user") %} 18 | A guide to all methods for installing Hipcheck. 19 | {% end %} 20 | 21 | {% waypoint(title="Testing Changes", path="@/docs/contributing/testing.md", icon="cloud-lightning") %} 22 | Some history on the creation and purpose of Hipcheck. 23 | {% end %} 24 | 25 | {% waypoint(title="Intellectual Property", path="@/docs/contributing/intellectual-property.md", icon="shield") %} 26 | A walkthrough of running Hipcheck for the first time. 27 | {% end %} 28 | 29 | {% waypoint(title="Describing Changes", path="@/docs/contributing/describing-changes.md", icon="message-circle") %} 30 | A walkthrough of running Hipcheck for the first time. 31 | {% end %} 32 | 33 | {% waypoint(title="PR Review Checklist", path="@/docs/contributing/pr-review.md", icon="message-circle") %} 34 | Things to track when reviewing a PR. 35 | {% end %} 36 | 37 | {% waypoint(title="Developer Docs", path="@/docs/contributing/developer-docs/_index.md") %} 38 | Documentation for Hipcheck developers. 39 | {% end %} 40 | 41 |
42 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | The following is the security policy for the `hipcheck` binary crate found in this workspace. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | You can report a vulnerability using the "Report a Vulnerability" button under 8 | the "Security" tab of the repository. If we find that a vulnerability is legitimate, 9 | we will create a [RustSec](https://rustsec.org/) advisory. 10 | 11 | Please give us 90 days to respond to a vulnerability disclosure. In general, we 12 | will try to produce fixes and respond publicly to disclosures faster than that. 13 | 14 | We ask that you _not_ create advisories yourself; instead please submit 15 | vulnerability reports to us first so we can plan a response. If we accept the 16 | legitimacy of a vulnerability, please wait for us to respond publicly to the 17 | vulnerability before publicly disclosing the vulnerability yourself. 18 | 19 | Our response will include publication of new versions, yanking of old versions, 20 | and public disclosure of the vulnerability and its fixes in the RustSec database. 21 | 22 | We consider soundness violations (violations of safe Rust's memory, thread, or 23 | type safety guarantees) to be at least informational vulnerabilities and 24 | will treat them as such. 25 | 26 | RustSec advisories are automatically imported into the GitHub Security Advisory 27 | system and the OSV database, so you do not need to create duplicate reports for 28 | those systems. -------------------------------------------------------------------------------- /site/templates/macros/breadcrumbs.tera.html: -------------------------------------------------------------------------------- 1 | {% macro breadcrumbs(current) %} 2 | {# TODO: Don't hide this on mobile #} 3 | 44 | {% endmacro breadcrumbs %} 45 | -------------------------------------------------------------------------------- /site/templates/partials/head.tera.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% if page and page.title %} 11 | {% set title = page.title %} 12 | {% elif section and section.title %} 13 | {% set title = section.title %} 14 | {% else %} 15 | {% set title = config.extra.title %} 16 | {% endif %} 17 | 18 | {% if page and page.description %} 19 | {% set description = page.description %} 20 | {% elif section and section.description %} 21 | {% set description = section.description %} 22 | {% else %} 23 | {% set description = config.extra.description %} 24 | {% endif %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /site/content/docs/guide/concepts/data/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Data 3 | weight: 2 4 | template: docs_page.html 5 | --- 6 | 7 | # Data 8 | 9 | To analyze packages, Hipcheck needs to gather data about those packages. 10 | That data can come from a variety of sources, including: 11 | 12 | - Git commit histories 13 | - The GitHub API or, in the future, similar source repository platform 14 | APIs 15 | - Package host APIs like the NPM API 16 | 17 | Each of these sources store information about the history of a project, 18 | which may be relevant for understanding the _practices_ associated with 19 | the code's development, or for detecting possible active supply chain 20 | _attacks_. 21 | 22 | Hipcheck tries to cleanly distinguish between _data_, _analyses_, and 23 | _configuration_. _Data_ is the raw pieces of information pulled from 24 | exterior sources. It is solely factual, recording prior events. 25 | _Analyses_ are computations performed on data which produce _measures_, 26 | and which may also produce _concerns_. Finally, _configuration_ is an 27 | expression of the user's policy, which turns the _measures_ produced 28 | by analyses into a _score_ and a _recommendation_. This is perhaps 29 | easier to see in a diagram. 30 | 31 | ![Concepts diagram](concepts-diagram.svg) 32 | 33 | With this structure, Hipcheck tries to cleanly separate the parts 34 | that are _factual_, from the parts that are _measuring_ facts, and 35 | from the parts that are applying subjective policies on those 36 | measurements. 37 | -------------------------------------------------------------------------------- /plugins/github/src/github/rest/code_search.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::tls::authenticated_agent::AuthenticatedAgent; 4 | use anyhow::{Result, anyhow}; 5 | use serde_json::Value; 6 | 7 | /// Endpoint for GitHub Code Search. 8 | const CODE_SEARCH: &str = "https://api.github.com/search/code"; 9 | 10 | /// Check if the given repo participates in OSS-Fuzz. 11 | pub fn check_fuzzing(agent: &AuthenticatedAgent<'_>, repo: &str) -> Result { 12 | // Example query will look like this: 13 | // https://api.github.com/search/code?q=github.com%20assimp%20assimp+in:file+filename:project.yaml+repo:google/oss-fuzz 14 | // 15 | // Logic based on these docs: 16 | // https://docs.github.com/en/search-github/searching-on-github/searching-code#considerations-for-code-search 17 | // 18 | // Breaking repo out in to more easily searchable string since full 19 | // GitHub repo urls were not working for a few fuzzed urls. 20 | 21 | let repo = repo 22 | .replace("https://", "") 23 | .replace("http://", "") 24 | .replace('/', "%20"); 25 | 26 | let query = format!( 27 | "{}?q={}+in:file+filename:project.yaml+repo:google/oss-fuzz", 28 | CODE_SEARCH, repo 29 | ); 30 | 31 | let json = agent 32 | .get(&query) 33 | .call()? 34 | .into_json::() 35 | .map_err(|_| anyhow!("unable to query fuzzing info"))?; 36 | 37 | let count = json["total_count"] 38 | .to_string() 39 | .parse::() 40 | .map_err(|_| anyhow!("unable to parse count"))?; 41 | 42 | Ok(count > 0) 43 | } 44 | -------------------------------------------------------------------------------- /site/content/docs/guide/debugging/starting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Starting Debugging 3 | weight: 1 4 | --- 5 | 6 | # Starting Debugging 7 | 8 | ## Using `hc ready` 9 | 10 | The `hc ready` command prints a variety of information about how Hipcheck is 11 | currently configured, including Hipcheck's own version, the versions of tools 12 | Hipcheck may need to run its analyses, the configuration of paths Hipcheck will 13 | use during execution, and the presence of API tokens Hipcheck may need. 14 | 15 | It also starts the plugins specified in the 16 | [policy file](@/docs/guide/config/policy-file.md) and confirms that all of them 17 | started and received configuration successfully. This is likely to catch 18 | configuration errors, though it will not expose issues that would only arise 19 | during analysis with [`hc check`](@/docs/guide/cli/hc-check.md). 20 | 21 | This is a very useful starting point when debugging Hipcheck. While Hipcheck 22 | can only automatically check basic information like whether configured paths 23 | are present and accessible, you should also review whether the paths `hc ready` 24 | reports are the ones you intend for Hipcheck to use. 25 | 26 | See the [`hc ready`](@/docs/guide/cli/hc-ready.md) documentation for more 27 | information on its specific CLI. 28 | 29 | ## Checking API Tokens 30 | 31 | Similarly, for any API tokens, it's good to make sure those tokens are valid 32 | to use, and have the appropriate permissions required to access the 33 | repositories or packages you are trying to analyze. 34 | -------------------------------------------------------------------------------- /sdk/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hipcheck-sdk" 3 | description = "SDK for writing Hipcheck plugins in Rust" 4 | homepage = "https://hipcheck.mitre.org" 5 | repository = "https://github.com/mitre/hipcheck" 6 | license = "Apache-2.0" 7 | version = "0.6.1" 8 | edition = "2024" 9 | 10 | [dependencies] 11 | anyhow = { workspace = true } 12 | thiserror = { workspace = true } 13 | futures = { workspace = true } 14 | indexmap = { workspace = true } 15 | lazy_static = { workspace = true } 16 | jiff = { workspace = true, features = ["serde"] } 17 | serde = { workspace = true, features = ["derive"] } 18 | serde_json = { workspace = true } 19 | tokio = { workspace = true, features = ["rt"] } 20 | tokio-stream = { workspace = true } 21 | tonic = { workspace = true } 22 | schemars = { workspace = true, features = ["url2"] } 23 | hipcheck-sdk-macros = { workspace = true, optional = true } 24 | typify-macro = { workspace = true } 25 | url = { workspace = true, features = ["serde"] } 26 | tracing = { workspace = true, optional = true } 27 | tracing-subscriber = { workspace = true, features = [ 28 | "env-filter", 29 | "json", 30 | ], optional = true } 31 | hipcheck-common = { workspace = true } 32 | console = { workspace = true, features = ["windows-console-colors"] } 33 | hipcheck-workspace-hack = { workspace = true } 34 | 35 | [features] 36 | default = ["log_forwarding"] 37 | macros = ["dep:hipcheck-sdk-macros"] 38 | mock_engine = [] 39 | print-timings = [] 40 | log_forwarding = ["tracing", "tracing-subscriber"] 41 | 42 | [package.metadata.docs.rs] 43 | all-features = true 44 | rustdoc-args = ["--cfg", "docsrs"] 45 | -------------------------------------------------------------------------------- /library/hipcheck-common/src/error.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /// An enumeration of errors that can occur in a Hipcheck plugin 4 | #[derive(Debug, thiserror::Error)] 5 | pub enum Error { 6 | /// An unknown error occurred, the query is in an unspecified state 7 | #[error("unknown error; query is in an unspecified state")] 8 | UnspecifiedQueryState, 9 | 10 | /// The `PluginEngine` received a message with the unexpected status `ReplyInProgress` 11 | #[error("unexpected ReplyInProgress state for query")] 12 | UnexpectedReplyInProgress, 13 | 14 | /// The `PluginEngine` received a message with the unexpected status `RequestInProgress` 15 | #[error("unexpected RequestInProgress state for query")] 16 | UnexpectedRequestInProgress, 17 | 18 | /// The `PluginEngine` received a message with a request-type status when it expected a reply 19 | #[error("remote sent QuerySubmit when reply chunk expected")] 20 | ReceivedSubmitWhenExpectingReplyChunk, 21 | 22 | /// The `PluginEngine` received a message with a reply-type status when it expected a submit 23 | #[error("remote sent QueryReply when submit chunk expected")] 24 | ReceivedReplyWhenExpectingSubmitChunk, 25 | 26 | /// The `PluginEngine` received additional messages when it did not expect any 27 | #[error("received additional message for ID '{id}' after query completion")] 28 | MoreAfterQueryComplete { id: usize }, 29 | 30 | #[error("invalid JSON in query key")] 31 | InvalidJsonInQueryKey(#[source] serde_json::Error), 32 | 33 | #[error("invalid JSON in query output")] 34 | InvalidJsonInQueryOutput(#[source] serde_json::Error), 35 | } 36 | -------------------------------------------------------------------------------- /site/templates/blog_post.html: -------------------------------------------------------------------------------- 1 | {% extends "bases/blog.tera.html" %} 2 | 3 | {% block title %} 4 | {% if section.title %} 5 | {{ section.title }} 6 | {% else %} 7 | Hipcheck 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block blog_header %} 12 |
13 |
14 |

{{ page.title }}

15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |

Written by {{ page.authors.0 }}

23 |

Posted on {{ page.date | date(format="%B %-d, %Y") }}

24 |
25 |
26 | 27 |
28 |
29 | {% endblock %} 30 | 31 | {% block content %} 32 |
33 |
34 |
35 | {{ page.content | safe }} 36 |
37 |
38 |
39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /site/templates/shortcodes/waypoint.html: -------------------------------------------------------------------------------- 1 | 2 | {% import "macros/icon.tera.html" as ic %} 3 | 4 | 25 | -------------------------------------------------------------------------------- /xtask/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xtask" 3 | description = "Hipcheck development task runner." 4 | version = "0.1.0" 5 | license = "Apache-2.0" 6 | edition = "2024" 7 | # This ensures we do not publish this to Crates.io, and that 8 | # 'dist' doesn't try to create any releases of this, since it's just 9 | # internal tooling. 10 | publish = false 11 | 12 | [dependencies] 13 | anyhow = { workspace = true } 14 | clap = { workspace = true, features = ["cargo", "derive", "string"] } 15 | clap-verbosity-flag = { workspace = true } 16 | convert_case = { workspace = true } 17 | csv = { workspace = true } 18 | env_logger = { workspace = true } 19 | glob = { workspace = true } 20 | itertools = { workspace = true } 21 | jiff = { workspace = true, features = ["alloc", "serde", "std"] } 22 | kdl = { workspace = true } 23 | log = { workspace = true } 24 | pathbuf = { workspace = true } 25 | pep440_rs = { workspace = true } 26 | pyproject-toml = { workspace = true } 27 | rayon = { workspace = true } 28 | regex = { workspace = true } 29 | # Exactly matching the version of rustls used by ureq 30 | # Get rid of default features since we don't use the AWS backed crypto 31 | # provider (we use ring) and it breaks stuff on windows. 32 | rustls = { workspace = true, features = ["logging", "std", "tls12", "ring"] } 33 | rustls-platform-verifier = { workspace = true } 34 | serde = { workspace = true, features = ["derive"] } 35 | serde_json = { workspace = true } 36 | toml = { workspace = true } 37 | ureq = { workspace = true, features = ["json", "tls"] } 38 | url = { workspace = true, features = ["serde"] } 39 | which = { workspace = true } 40 | xshell = { workspace = true } 41 | -------------------------------------------------------------------------------- /xtask/src/task/changelog.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use crate::ChangelogArgs; 4 | use anyhow::{Context, Result}; 5 | use log::LevelFilter; 6 | use xshell::{Shell, cmd}; 7 | 8 | /// Execute the changelog task. 9 | pub fn run(args: ChangelogArgs) -> Result<()> { 10 | which::which("git-cliff").context( 11 | "changelog requires `git-cliff` to be installed. Please install it with `cargo install git-cliff`.")?; 12 | 13 | let sh = Shell::new()?; 14 | 15 | // Get the root of the workspace, and make sure the shell is in it. 16 | // `git-cliff` expects to be run from the root of the workspace. 17 | let root = crate::workspace::root()?; 18 | sh.change_dir(root); 19 | 20 | // Warn the user about what version we're bumping to. 21 | // 22 | // Avoid running the extra external command if we won't see the result. 23 | if log::max_level() >= LevelFilter::Warn { 24 | let new_version = { 25 | let full = cmd!(sh, "git cliff --bumped-version").read()?; 26 | full.strip_prefix("hipcheck-").unwrap_or(&full).to_owned() 27 | }; 28 | 29 | log::warn!( 30 | "bumping to {}; this may not be the version you want", 31 | new_version 32 | ); 33 | } 34 | 35 | // We don't overwrite the CHANGELOG.md file, and instead by default 36 | // write to a different output file. 37 | let output = "CHANGELOG-NEXT.md"; 38 | 39 | // Only include the bump flag if requested by the user. 40 | let bump = args.bump.then_some("--bump"); 41 | cmd!(sh, "git cliff {bump...} -o {output}") 42 | .quiet() 43 | .ignore_stdout() 44 | .ignore_stderr() 45 | .run()?; 46 | 47 | log::warn!("finished; check {} to proceed", output); 48 | Ok(()) 49 | } 50 | -------------------------------------------------------------------------------- /site/scripts/src/footer/docs.ts: -------------------------------------------------------------------------------- 1 | import { updateIcon } from "../util/icon.ts"; 2 | import { querySelectorAll } from "../util/web.ts"; 3 | 4 | /** 5 | * Sets up the collapse/expand functionality for docs navigation. 6 | */ 7 | export function setupDocsNav() { 8 | let $toggles; 9 | 10 | try { 11 | $toggles = querySelectorAll(".docs-nav-toggle"); 12 | } catch (_e) { 13 | // Swallow these errors. 14 | return; 15 | } 16 | 17 | $toggles.forEach(($toggle) => { 18 | // Get the icon inside the toggle. 19 | const $toggleIcon = $toggle.querySelector( 20 | ".toggle-icon use", 21 | ) as HTMLElement; 22 | if ($toggleIcon === null) { 23 | console.log(`no icon found for toggle: '${$toggle}'`); 24 | return; 25 | } 26 | 27 | $toggle.addEventListener("click", (e) => { 28 | e.preventDefault(); 29 | 30 | // Find the subsection list associated with the current toggle. 31 | const $parent = $toggle.parentElement?.parentElement; 32 | if ($parent === null || $parent === undefined) return; 33 | const $subsection = $parent.querySelector( 34 | ".docs-nav-section", 35 | ) as HTMLElement; 36 | if ($subsection === null) return; 37 | 38 | // Hide or show it. 39 | $subsection.classList.toggle("hidden"); 40 | 41 | if (sectionIsHidden($subsection)) { 42 | updateIcon($toggleIcon, "chevron-right", "chevron-down"); 43 | } else { 44 | updateIcon($toggleIcon, "chevron-down", "chevron-right"); 45 | } 46 | }); 47 | }); 48 | } 49 | 50 | function sectionIsHidden($subsection: HTMLElement): boolean { 51 | return $subsection.classList.contains("hidden"); 52 | } 53 | -------------------------------------------------------------------------------- /tests/test-plugins/dummy_sha256/src/main.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | use clap::Parser; 4 | use hipcheck_sdk::{LogLevel, prelude::*}; 5 | use sha2::{Digest, Sha256}; 6 | 7 | #[query] 8 | async fn query_sha256(_engine: &mut PluginEngine, content: Vec) -> Result> { 9 | let mut hasher = Sha256::new(); 10 | hasher.update(content.as_slice()); 11 | Ok(hasher.finalize().to_vec()) 12 | } 13 | 14 | /// This plugin takes in a Value::Array(Vec) and calculates its sha256 15 | #[derive(Clone, Debug)] 16 | struct Sha256Plugin; 17 | 18 | impl Plugin for Sha256Plugin { 19 | const PUBLISHER: &'static str = "dummy"; 20 | 21 | const NAME: &'static str = "sha256"; 22 | 23 | fn set_config(&self, _config: Value) -> std::result::Result<(), ConfigError> { 24 | Ok(()) 25 | } 26 | 27 | fn default_policy_expr(&self) -> hipcheck_sdk::prelude::Result { 28 | Ok("".to_owned()) 29 | } 30 | 31 | fn explain_default_query(&self) -> hipcheck_sdk::prelude::Result> { 32 | Ok(Some("calculate sha256 of provided array".to_owned())) 33 | } 34 | 35 | queries! { 36 | #[default] query_sha256, 37 | } 38 | } 39 | 40 | #[derive(Parser, Debug)] 41 | struct Args { 42 | #[arg(long)] 43 | port: u16, 44 | 45 | #[arg(long, default_value_t=LogLevel::Error)] 46 | log_level: LogLevel, 47 | 48 | #[arg(trailing_var_arg(true), allow_hyphen_values(true), hide = true)] 49 | unknown_args: Vec, 50 | } 51 | 52 | #[tokio::main(flavor = "current_thread")] 53 | async fn main() -> Result<()> { 54 | let args = Args::try_parse().unwrap(); 55 | PluginServer::register(Sha256Plugin, args.log_level) 56 | .listen_local(args.port) 57 | .await 58 | } 59 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc update 3 | extra: 4 | nav_title: "hc update" 5 | --- 6 | 7 | # `hc update` 8 | 9 | When Hipcheck is installed using the recommend install scripts provided with 10 | each release, the install scripts also provide an "updater" program, built 11 | by `cargo-dist` (which Hipcheck uses to handle creating prebuilt artifacts 12 | with each release, and with announcing each release on GitHub Releases). 13 | This updater program handles checking for a newer version of Hipcheck, 14 | downloading it, and replacing the current version with the newer one. 15 | The updater is provided as a separate binary (named either `hc-update` 16 | or `hipcheck-update`, due to historic bugs). 17 | 18 | The `hc update` command simply delegates to this separate update program, 19 | and provides the same interface that this separate update program does. 20 | In general, you only need to run `hc update` with no arguments, followed 21 | by `hc setup` to ensure your configuration and data files are setup. 22 | 23 | If you want to specifically download a version besides the most recent 24 | version of Hipcheck, you can use the following flags: 25 | 26 | - `--tag `: install the version from this specific Git tag. 27 | - `--version `: install the version from this specific GitHub 28 | release. 29 | - `--prerelease`: permit installing a pre-release version when updating 30 | to `latest`, 31 | 32 | The `--tag` and `--version` flags are mutually exclusive; the updater will 33 | produce an error if both are provided. 34 | 35 | This command also supports Hipcheck's [General Flags](@/docs/guide/cli/general-flags.md), though 36 | they are ignored. 37 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/options.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | import copy 4 | from dataclasses import dataclass 5 | 6 | 7 | @dataclass 8 | class SdkOptions: 9 | """ 10 | Options that can be set before starting a server.PluginServer to 11 | control behavior. Designed to offer roughly similar behavior to the 12 | feature flags available in the Rust Hipcheck SDK. 13 | """ 14 | 15 | rfd9_compat: bool = True 16 | 17 | 18 | _options = SdkOptions() 19 | 20 | 21 | def set_option(option_name: str, val: bool): 22 | """ 23 | Turn an option on or off. 24 | 25 | :param str option_name: The option name to set 26 | :param bool val: The value to which to set the option 27 | """ 28 | global _options 29 | setattr(_options, option_name, val) 30 | 31 | 32 | def enabled(option_name: str) -> bool: 33 | """ 34 | :param str option_name: The option name to check 35 | :return: True if the option is enabled, else False 36 | """ 37 | global _options 38 | return getattr(_options, option_name) 39 | 40 | 41 | def set_options(options: SdkOptions): 42 | """ 43 | Set the entire global `SdkOptions` instance at once instead of toggling 44 | individual options. 45 | 46 | :param SdkOptions options: The options instance to override the current 47 | global value with 48 | """ 49 | global _options 50 | _options = options 51 | 52 | 53 | def get_options() -> SdkOptions: 54 | """ 55 | :return: A copy of the global `SdkOptions` instance. Note that this is a 56 | deep copy so changes to the returned value will not affect the global 57 | state. 58 | """ 59 | global _options 60 | return copy.copy(_options) 61 | -------------------------------------------------------------------------------- /sdk/rust/README.md: -------------------------------------------------------------------------------- 1 | # Hipcheck Rust Plugin SDK ✓ 2 | 3 | A software development kit to help with writing plugins in Rust for the 4 | [Hipcheck][website] dependency analysis tool. 5 | 6 | ## Overview 7 | 8 | Hipcheck is a software dependency analyiss tool that helps identify risky 9 | project management practices and potential supply-chain attacks. It uses a 10 | plugin-based anaylsis architecture, such that Hipcheck users can write and 11 | release their own plugins that integrate seamlessly with the core binary and 12 | other analyses. The Rust plugin SDK provides the boilerplate code for defining a 13 | plugin and communicating with Hipcheck core over gRPC, allowing plugin authors 14 | to focus on the business logic of their plugin query endpoints. 15 | 16 | ## Getting Started 17 | 18 | The Hipcheck website has a [guide][sdk-guide] for writing plugins using the Rust 19 | SDK. For examples of using the SDK, the `plugins/` [subdirectory][plugins-src] 20 | of the Hipcheck repository contains a suite of plugins maintained by the 21 | Hipcheck team that are all written with the SDK. See the `docs.rs` 22 | [page][sdk-docs] for the official documentation. 23 | 24 | ## Links 25 | 26 | [Docs][sdk-docs] | [Guide][sdk-guide] | [Examples][plugin-src] 27 | 28 | ## License 29 | 30 | Hipcheck's software is licensed under the Apache 2.0 license, which can be 31 | found in the [`LICENSE`][license] file in this repository. 32 | 33 | [license]: https://github.com/mitre/hipcheck/blob/main/LICENSE 34 | [website]: https://hipcheck.mitre.org/ 35 | [sdk-guide]: https://hipcheck.mitre.org/docs/guide/making-plugins/rust-sdk/ 36 | [plugins-src]: https://github.com/mitre/hipcheck/tree/main/plugins 37 | [sdk-docs]: https://docs.rs/crate/hipcheck-sdk/latest 38 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-scoring.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc scoring 3 | extra: 4 | nav_title: "hc scoring" 5 | --- 6 | 7 | # `hc scoring` 8 | 9 | Hipcheck's scoring system works by calculating percentages for how much each 10 | analysis in the user's configured analysis tree contributes to the overall 11 | score, based on weights users set for each analysis and category. 12 | 13 | The `hc scoring` command takes that configured tree and weights, calculates 14 | scoring percentages, and displays them to the user to make it clear how their 15 | current policies will be converted to scores based on the results of a run 16 | of analyses. 17 | 18 | The help text looks like: 19 | 20 | ``` 21 | Print the tree used to weight analyses during scoring 22 | 23 | Usage: hc scoring [OPTIONS] 24 | 25 | Options: 26 | -h, --help Print help (see more with '--help') 27 | 28 | Output Flags: 29 | -v, --verbosity How verbose to be [possible values: quiet, normal] 30 | -k, --color When to use color [possible values: always, never, auto] 31 | -f, --format What format to use [possible values: json, human] 32 | 33 | Path Flags: 34 | -C, --cache Path to the cache folder 35 | -p, --policy Path to the policy file 36 | ``` 37 | 38 | The following is an example output: 39 | 40 | ``` 41 | risk 42 | |-- practices 43 | | |-- mitre::activity: 10.00% 44 | | |-- mitre::binary: 10.00% 45 | | |-- mitre::fuzz: 10.00% 46 | | |-- mitre::identity: 10.00% 47 | | `-- mitre::review: 10.00% 48 | `-- attacks 49 | |-- mitre::typo: 25.00% 50 | `-- commit 51 | |-- mitre::affiliation: 8.33% 52 | |-- mitre::churn: 8.33% 53 | `-- mitre::entropy: 8.33% 54 | ``` 55 | -------------------------------------------------------------------------------- /hipcheck/src/util/test.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Utilities for unit testing. 4 | 5 | use std::{ 6 | env, 7 | env::VarError, 8 | panic, 9 | panic::{RefUnwindSafe, UnwindSafe}, 10 | sync::{Mutex, OnceLock}, 11 | }; 12 | 13 | static SERIAL_TEST: OnceLock> = OnceLock::new(); 14 | 15 | /// Sets environment variables to the given value for the duration of the closure. 16 | /// Restores the previous values when the closure completes or panics, 17 | /// before unwinding the panic. 18 | /// 19 | /// Credit: Fabian Braun at https://stackoverflow.com/a/67433684 20 | pub fn with_env_vars(kvs: Vec<(&str, Option<&str>)>, closure: F) 21 | where 22 | F: Fn() + UnwindSafe + RefUnwindSafe, 23 | { 24 | let guard = SERIAL_TEST.get_or_init(Default::default).lock().unwrap(); 25 | let mut old_kvs: Vec<(&str, Result)> = Vec::new(); 26 | for (k, v) in kvs { 27 | let old_v = env::var(k); 28 | old_kvs.push((k, old_v)); 29 | match v { 30 | None => unsafe { env::remove_var(k) }, 31 | Some(v) => unsafe { env::set_var(k, v) }, 32 | } 33 | } 34 | 35 | let scrutinee = panic::catch_unwind(|| { 36 | closure(); 37 | }); 38 | 39 | match scrutinee { 40 | Ok(_) => { 41 | for (k, v) in old_kvs { 42 | reset_env(k, v); 43 | } 44 | } 45 | Err(err) => { 46 | for (k, v) in old_kvs { 47 | reset_env(k, v); 48 | } 49 | drop(guard); 50 | panic::resume_unwind(err); 51 | } 52 | }; 53 | } 54 | 55 | fn reset_env(k: &str, old: Result) { 56 | use std::env::VarError::*; 57 | match old { 58 | Ok(v) => unsafe { env::set_var(k, v) }, 59 | Err(NotUnicode(os_str)) => unsafe { env::set_var(k, os_str) }, 60 | Err(NotPresent) => unsafe { env::remove_var(k) }, 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-explain.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc explain 3 | extra: 4 | nav_title: "hc explain" 5 | --- 6 | 7 | # `hc explain` 8 | 9 | The `hc explain` command is provided to give users insight into some of the 10 | current settings, information, or logic to use for understanding or debugging. 11 | 12 | The following is the CLI help text for `hc explain`: 13 | 14 | ``` 15 | View setup information to help debug 16 | 17 | Usage: hc explain [OPTIONS] 18 | 19 | Commands: 20 | target-triple Show the current and known architecture targets 21 | help Print this message or the help of the given subcommand(s) 22 | 23 | Options: 24 | -h, --help Print help (see more with '--help') 25 | 26 | Output Flags: 27 | -v, --verbosity How verbose to be [possible values: quiet, normal] 28 | -k, --color When to use color [possible values: always, never, auto] 29 | -f, --format What format to use [possible values: json, debug, human] 30 | 31 | Path Flags: 32 | -C, --cache Path to the cache folder 33 | -p, --policy Path to the policy file 34 | -e, --exec Path to the exec config file 35 | ``` 36 | 37 | ## hc explain target-triple 38 | 39 | The `target-triple` commands prints out the current inferred architecture of 40 | the user as recognized by Hipcheck. It also prints out the other supported 41 | architectures. A sample output for `hc explain target-triple` would be: 42 | 43 | ``` 44 | Current target triple architecture (Known): 45 | > Apple Silicon (ARM64), macOS 46 | 47 | Other supported architectures: 48 | - Intel x86_64, macOS 49 | - Intel x86_64, Windows (MSVC) 50 | - Intel x86_64, Linux (GNU) 51 | - ARM64, Linux 52 | ``` 53 | -------------------------------------------------------------------------------- /site/content/docs/guide/cli/hc-ready.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: hc ready 3 | extra: 4 | nav_title: "hc ready" 5 | --- 6 | 7 | # `hc ready` 8 | 9 | `hc ready` is a command for checking that Hipcheck is ready to run analyses. 10 | This is intended to help the user debug issues with a Hipcheck installation, 11 | including problems like missing configuration files, inaccessible config, 12 | data, or cache paths, missing authentication tokens, and more. 13 | 14 | `hc ready` starts all the plugins specified in the 15 | [policy file](@/docs/guide/config/policy-file.md) and confirms that initial 16 | configuration is successful. If `hc ready` doesn't report any problems with 17 | plugins, that means they are installed, runnable by Hipcheck, and are able to 18 | load their configuration without issues. 19 | 20 | Since `hc ready` does not involve the analysis subsystem like 21 | [`hc check`](@/docs/guide/cli/hc-check.md) does, it will not expose plugin 22 | issues that would only occur while analyzing a target. 23 | 24 | `hc ready` has no special flags currently, and only accepts the 25 | [General Flags](@/docs/guide/cli/general-flags.md) that _all_ Hipcheck 26 | commands accept. 27 | 28 | The output of `hc ready` is a report containing key information about 29 | Hipcheck, the third-party tools it relies on as external data sources, 30 | the paths it's currently using for configuration files, data files, 31 | and local repository clones, along with any API tokens it will use 32 | for external API access. 33 | 34 | If all required information is found and passes requirements for Hipcheck 35 | to run, it will report that Hipcheck is ready to run. 36 | 37 | We recommend running `hc ready` before running Hipcheck the first time, 38 | and as a good first debugging step if Hipcheck begins reporting issues. 39 | -------------------------------------------------------------------------------- /site/content/docs/guide/plugins/mitre-identity.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "mitre/identity" 3 | extra: 4 | nav_title: "mitre/identity" 5 | --- 6 | 7 | # `mitre/identity` 8 | 9 | Checks if a project's contributions have the same author and committer. 10 | 11 | ## Configuration 12 | 13 | | Parameter | Type | Explanation | 14 | |:--------------------|:--------|:--------------| 15 | | `percent-threshold` | `Float` | Percentage of "merge-by-self" contributions to accept. | 16 | 17 | ## Default Policy Expression 18 | 19 | ``` 20 | (lte 21 | (divz 22 | (count (filter (eq #t) $)) 23 | (count $)) 24 | {config.percent-threshold or 0.2}) 25 | ``` 26 | 27 | ## Default Query: `mitre/identity` 28 | 29 | Returns an array of booleans indicating if commits have matching committer 30 | and author. 31 | 32 | ## Explanation 33 | 34 | Identity analysis looks at whether the author and committer identities for 35 | each commit are the same, as part of gauging the likelihood that commits 36 | are receiving some degree of review before being merged into a repository. 37 | 38 | When author and committer identity are the same, that may indicate that a 39 | commit did _not_ receive review, which could be a cause for concern. At the 40 | larger level, having a large percentage of commits with the same author 41 | and committer identities may indicate a project that lacks code review. 42 | 43 | ## Limitations 44 | 45 | * __Not every project uses a workflow that accords with this analysis__: 46 | While some Git projects may use a workflow that involves the generation 47 | of patchfiles to then be reviewed and applied by project maintainers, 48 | many may not. In some cases, a workflow may produce final commits where 49 | the author and committer identity are the same, even though the commit 50 | received review. 51 | -------------------------------------------------------------------------------- /site/content/docs/guide/concepts/concerns.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Concerns 3 | weight: 6 4 | --- 5 | 6 | # Concerns 7 | 8 | Besides a risk score and a recommendation, Hipcheck's other major output 9 | is a list of "concerns" from individual analyses. "Concerns" are Hipcheck's 10 | mechanism for analyses to report specific information about what they found 11 | that they think the user may be interested in knowing and possibly 12 | investigating further. For example, some of Hipcheck's analyses that work 13 | on individual commits will produce the hashes of commits they find concerning, 14 | so users can audit those commits by hand if they want to do so. 15 | 16 | Concerns are the most flexible mechanism Hipcheck has, as they are essentially 17 | a way for analyses to report freeform text out to the user. They do not have 18 | a specific structured format, and they are not considered at all for the 19 | purpose of scoring. The specific concerns which may be reported vary from 20 | analysis to analysis. 21 | 22 | In general, we want analyses to report concerns wherever possible. For 23 | some analyses, there may not be a reasonable type of concern to report; 24 | for example, the "activity" analysis checks the date of the most recent 25 | commit to a project to see if the project appears "active," and the 26 | _only_ fact that it's assessing is also the fact which results in the 27 | measure the analysis produces, so there's not anything sensible for 28 | the analysis to report as a concern. 29 | 30 | However, many analysis _do_ have meaningful concerns they can report, and if an 31 | analysis _could_ report a type of concern but _doesn't_, we consider that 32 | something worth changing. Contributions to make Hipcheck report more concerns, 33 | or to make existing concerns more meaningful, are [always appreciated](@/docs/contributing/_index.md)! 34 | -------------------------------------------------------------------------------- /xtask/src/task/manifest/util/authenticated_agent.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Defines an authenticated [`Agent`] type that adds token auth to all requests. 4 | 5 | use crate::task::manifest::util::{agent, redacted::Redacted}; 6 | use anyhow::Result; 7 | use ureq::{Agent, Request}; 8 | 9 | /// An [`Agent`] which authenticates requests with token auth. 10 | /// 11 | /// This wrapper is used to work around the fact that `ureq` removed functionality 12 | /// to do this as part of the [`Agent`] type directly. 13 | pub struct AuthenticatedAgent<'token> { 14 | /// The agent used to make the request. 15 | agent: &'static Agent, 16 | 17 | /// The token to use with each request. 18 | token: Redacted<&'token str>, 19 | } 20 | 21 | impl<'token> AuthenticatedAgent<'token> { 22 | /// Construct a new authenticated agent. 23 | pub fn new(token: &'token str) -> Result> { 24 | Ok(AuthenticatedAgent { 25 | agent: agent::agent()?, 26 | token: Redacted::new(token), 27 | }) 28 | } 29 | 30 | /// Make an authenticated GET request. 31 | pub fn get(&self, path: &str) -> Request { 32 | self.agent.get(path).token_auth(self.token.as_ref()) 33 | } 34 | 35 | /// Make an authenticated POST request. 36 | #[allow(unused)] 37 | pub fn post(&self, path: &str) -> Request { 38 | self.agent.post(path).token_auth(self.token.as_ref()) 39 | } 40 | } 41 | 42 | /// The key to use for the authorization HTTP header. 43 | const AUTH_KEY: &str = "Authorization"; 44 | 45 | /// Extension trait to add a convenient "token auth" method. 46 | trait TokenAuth { 47 | /// Sets a token authentication header on a request. 48 | fn token_auth(self, token: &str) -> Self; 49 | } 50 | 51 | impl TokenAuth for Request { 52 | fn token_auth(self, token: &str) -> Self { 53 | self.set(AUTH_KEY, &format!("token {}", token)) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /hipcheck/src/benchmarking.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //! Special tools/utilities for benchmarking. 4 | //! 5 | //! The way this is intended to work is that when the "print-timings" feature is enabled, 6 | //! various lines of code that create instantiate structs like [PrintTime] will be activated. 7 | //! 8 | //! These structs have a special [Drop] implementation that prints the duration between instantiation and when they 9 | //! are dropped, effectively giving us function timings without being too intrusive to the codebase. 10 | //! 11 | //! A macro is provided to automatically tag timings with the file and line number that they were created on. 12 | 13 | use crate::shell::Shell; 14 | use std::time::Instant; 15 | 16 | /// Structure used to track timing that will print its location and elapsed time when dropped. 17 | #[derive(Debug)] 18 | pub struct PrintTime { 19 | pub location: String, 20 | pub start: Instant, 21 | } 22 | 23 | impl PrintTime { 24 | /// Create a new [PrintTime] that will print the number of seconds it was alive for when it gets dropped. 25 | pub fn new(location: impl Into) -> Self { 26 | PrintTime { 27 | location: location.into(), 28 | start: Instant::now(), 29 | } 30 | } 31 | } 32 | 33 | impl Drop for PrintTime { 34 | fn drop(&mut self) { 35 | Shell::print_timing(&self) 36 | } 37 | } 38 | 39 | macro_rules! print_scope_time { 40 | () => { 41 | $crate::benchmarking::PrintTime::new(format!( 42 | "{}:{}:{}", 43 | module_path!(), 44 | line!(), 45 | column!() 46 | )) 47 | }; 48 | 49 | ($msg:expr) => { 50 | $crate::benchmarking::PrintTime::new(format!( 51 | "{}:{}:{} ({})", 52 | module_path!(), 53 | line!(), 54 | column!(), 55 | $msg 56 | )) 57 | }; 58 | } 59 | 60 | // Make `print_scope_time` available through `benchmarking` module 61 | pub(super) use print_scope_time; 62 | -------------------------------------------------------------------------------- /site/content/docs/guide/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Complete Guide 3 | weight: 2 4 | template: docs.html 5 | page_template: docs_page.html 6 | sort_by: weight 7 | --- 8 | 9 | # Complete Guide 10 | 11 | Welcome to the Complete Guide to Hipcheck! This guide is intended to explain: 12 | 13 | - What Hipcheck is 14 | - How to use Hipcheck effectively 15 | - The key concepts underlying Hipcheck's design 16 | - How to configure Hipcheck 17 | - How to interpret Hipcheck's output 18 | - How to debug Hipcheck if you encounter an error 19 | 20 | Since we intend this to be a __complete__ guide, if you encounter questions 21 | you don't feel are adequately answered by this guide, please let us know 22 | by opening an issue on our [issue tracker](https://github.com/mitre/hipcheck/issues)! 23 | 24 |
25 | 26 | {% waypoint(title="Key Concepts", path="@/docs/guide/concepts/_index.md", icon="key") %} 27 | An explanation of the ideas underpinning Hipcheck's design. 28 | {% end %} 29 | 30 | {% waypoint(title="Configuration", path="@/docs/guide/config/_index.md", icon="settings") %} 31 | How to configure Hipcheck and describe your policies to apply. 32 | {% end %} 33 | 34 | {% waypoint(title="CLI Reference", path="@/docs/guide/cli/_index.md", icon="terminal") %} 35 | Reference for all CLI commands and arguments. 36 | {% end %} 37 | 38 | {% waypoint(title="Debugging", path="@/docs/guide/debugging/_index.md", icon="target") %} 39 | How to identify errors during Hipcheck execution. 40 | {% end %} 41 | 42 | {% waypoint(title="Plugins", path="@/docs/guide/plugins/_index.md", icon="box") %} 43 | Index of existing plugins for Hipcheck, both for data and analyses. 44 | {% end %} 45 | 46 | {% waypoint(title="Making Plugins", path="@/docs/guide/making-plugins/_index.md", icon="tool") %} 47 | A guide for making new Hipcheck plugins. 48 | {% end %} 49 | 50 |
51 | -------------------------------------------------------------------------------- /hipcheck/src/init/mod.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | mod git2_log_shim; 4 | mod git2_rustls_transport; 5 | mod indicatif_log_bridge; 6 | 7 | use crate::shell::{Shell, verbosity::Verbosity}; 8 | use env_logger::Env; 9 | use rustls::crypto::{CryptoProvider, ring}; 10 | 11 | /// Initialize global state for the program. 12 | /// 13 | /// **NOTE:** The order in which these operations are done is precise, and 14 | /// should not be changed! 15 | pub fn init() { 16 | init_shell(); 17 | init_logging(); 18 | init_libgit2(); 19 | init_cryptography(); 20 | init_software_versions(); 21 | } 22 | 23 | fn init_shell() { 24 | Shell::init(Verbosity::Normal); 25 | } 26 | 27 | fn init_logging() { 28 | let env = Env::new().filter("HC_LOG").write_style("HC_LOG_STYLE"); 29 | let logger = env_logger::Builder::from_env(env).build(); 30 | indicatif_log_bridge::LogWrapper(logger) 31 | .try_init() 32 | .expect("logging initialization must succeed"); 33 | } 34 | 35 | fn init_libgit2() { 36 | // Tell the `git2` crate to pass its tracing messages to the log crate. 37 | git2_log_shim::git2_set_trace_log_shim(); 38 | 39 | // Make libgit2 use a rustls + ureq based transport for executing the git 40 | // protocol over http(s). I would normally just let libgit2 use its own 41 | // implementation but have seen that this rustls/ureq transport is 2-3 times 42 | // faster on my machine — enough of a performance bump to warrant using this. 43 | git2_rustls_transport::register(); 44 | } 45 | 46 | fn init_cryptography() { 47 | // Install a process-wide default crypto provider. 48 | CryptoProvider::install_default(ring::default_provider()) 49 | .expect("installed process-wide default crypto provider"); 50 | } 51 | 52 | fn init_software_versions() { 53 | if let Err(e) = crate::version::init_software_versions() { 54 | panic!("initial dependency version checking failed: {:?}", e); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dist-workspace.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | # All the packages which 'cargo-dist' is responsible for. 4 | # This is _only_ the binary packages in the overall project, so it excludes 5 | # libraries including any SDKs and our supporting libraries. 6 | members = ["cargo:."] 7 | 8 | # Config for 'dist' 9 | [dist] 10 | # The preferred dist version to use in CI (Cargo.toml SemVer syntax) 11 | cargo-dist-version = "0.30.2" 12 | # CI backends to support 13 | ci = "github" 14 | # Which actions to run on pull requests 15 | pr-run-mode = "plan" 16 | # Path that installers should place binaries in 17 | install-path = ["~/.local/bin", "~/.hipcheck/bin"] 18 | # Target platforms to build apps for (Rust target-triple syntax) 19 | targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] 20 | # Whether to install an updater program 21 | install-updater = true 22 | # Build only the required packages, and individually 23 | precise-builds = true 24 | # The installers to generate for each app 25 | installers = [] 26 | 27 | # NOTE: MUST be synced manually with runners in `.github/workflows/hipcheck.yml` 28 | [dist.github-custom-runners] 29 | global = "ubuntu-22.04" 30 | # Ensure Apple Silicon macOS builds run natively rather than cross-compiling 31 | # from x86. Also makes sure our Apple Silicon macOS release builds match the 32 | # runner used for regular CI testing. 33 | aarch64-apple-darwin = "macos-14" 34 | # Update our Ubuntu release runs away from Ubuntu 20.04, which is now being 35 | # sunset by GitHub. They only track the last two LTS Ubuntu releases for free 36 | # runners, and with 24.04 out they're sunsetting 20.04. We're *just* moving to 37 | # 22.04, since releases compiled against 22.04's glibc should be forwards- 38 | # compatible with 24.04, but if we built on 24.04 the glibc *would not* be 39 | # backwards-compatible. 40 | x86_64-unknown-linux-gnu = "ubuntu-22.04" 41 | -------------------------------------------------------------------------------- /site/templates/shortcodes/install.html: -------------------------------------------------------------------------------- 1 | 2 | {% import "macros/icon.tera.html" as ic %} 3 | 4 |
5 |
6 |
7 | macOS 8 | Linux 9 | Windows 10 |
11 |
12 |
13 |
14 |
15 |
curl -LsSf {{ config.base_url }}/dl/install.sh | sh
16 | {{ ic::icon(name="clipboard", classes="-mt-[2px]") }} 17 |
18 |
19 | -------------------------------------------------------------------------------- /sdk/python/src/hipcheck_sdk/gen/types.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # generated by datamodel-codegen: 3 | # filename: hipcheck_target_schema.json 4 | 5 | from __future__ import annotations 6 | 7 | from enum import Enum 8 | from typing import Optional 9 | 10 | from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel 11 | 12 | 13 | class GitHub(BaseModel): 14 | owner: str 15 | repo: str 16 | 17 | 18 | class KnownRemote1(BaseModel): 19 | model_config = ConfigDict( 20 | extra='forbid', 21 | ) 22 | GitHub_1: GitHub = Field(..., alias='GitHub') 23 | 24 | 25 | class KnownRemote(RootModel[KnownRemote1]): 26 | root: KnownRemote1 27 | 28 | 29 | class LocalGitRepo(BaseModel): 30 | git_ref: str = Field(..., description="The Git ref we're referring to.") 31 | path: str = Field(..., description='The path to the repo.') 32 | 33 | 34 | class PackageHost(Enum): 35 | Npm = 'Npm' 36 | PyPI = 'PyPI' 37 | 38 | 39 | class RemoteGitRepo(BaseModel): 40 | known_remote: Optional[KnownRemote] = None 41 | url: AnyUrl 42 | 43 | 44 | class Package(BaseModel): 45 | host: PackageHost = Field(..., description='What host the package is from.') 46 | name: str = Field(..., description='The package name') 47 | purl: AnyUrl = Field(..., description='A package url for the package.') 48 | version: str = Field(..., description='The package version') 49 | 50 | 51 | class Target(BaseModel): 52 | local: LocalGitRepo = Field(..., description='The path to the local repository.') 53 | package: Optional[Package] = Field( 54 | None, description='The package associated with the target, if any.' 55 | ) 56 | remote: Optional[RemoteGitRepo] = Field( 57 | None, description='The url of the remote repository, if any.' 58 | ) 59 | specifier: str = Field( 60 | ..., description='The original specifier provided by the user.' 61 | ) 62 | --------------------------------------------------------------------------------