--- url: https://docs.sysreptor.com/setup/installation.md --- ::: details System Requirements ### Server * Ubuntu * 8GB RAM Even though we officially support **Ubuntu** only, installation is technically possible on most UNIX-based target systems including Kali, Fedora, macOS or RHEL. Follow the [manual installation](#manual-installation) steps and adapt the commands to your system. If all dependencies are installed, [easy script installation](#easy-script-installation) might also work.\ On Windows, use [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install) with an Ubuntu distribution. ### Client · * Network connection to the server * Up-to-date desktop browser, one of: * Chrome * Edge * Firefox * Safari ::: ::: tabs \== Easy Script Installation Installation via script is the easiest option. Install additonal requirements: ```shell sudo apt update sudo apt install -y sed curl openssl uuid-runtime coreutils ``` Install Docker: ```shell curl -fsSL https://get.docker.com | sudo bash ``` Make sure your user is allowed to use Docker. For this, you can add your user to the docker group: ```shell sudo groupadd docker 2>/dev/null # Creates the Docker group if it doesn't exist sudo usermod -aG docker $USER # Add the current user to the Docker group newgrp docker # Instantly apply the group membership ``` Download the SysReptor install script and run: ```shell bash <(curl -s https://docs.sysreptor.com/install.sh) ``` The installation script creates a new `sysreptor` directory holding the source code and everything you need.\ It will set up all configurations, create volumes and secrets, download images from Docker hub and bring up your containers. \== Manual Installation Install Docker: ```shell curl -fsSL https://get.docker.com | sudo bash ``` Make sure your user is allowed to use Docker. For this, you can add your user to the docker group: ```shell sudo groupadd docker 2>/dev/null # Creates the Docker group if it doesn't exist sudo usermod -aG docker $USER # Add the current user to the Docker group newgrp docker # Instantly apply the group membership ``` Download and extract the latest SysReptor setup files: ```shell curl -s -L --output sysreptor.tar.gz https://github.com/syslifters/sysreptor/releases/latest/download/setup.tar.gz tar xzf sysreptor.tar.gz ``` Create your `app.env`: ```shell cd sysreptor/deploy cp app.env.example app.env ``` Generate Django secret key and add to `app.env`: ```shell printf "SECRET_KEY=\"$(openssl rand -base64 64 | tr -d '\r\n=')\"\n" ``` Generate database and Redis passwords and add to `.env` (copy from `.env.example` if needed): ```shell cp -n .env.example .env printf "POSTGRES_PASSWORD=$(openssl rand -hex 32 | tr -d '\r\n')\nREDIS_PASSWORD=$(openssl rand -hex 32 | tr -d '\r\n')\n" ``` Optional: If you want to encrypt sensitive data at rest (data in the database and uploaded files and images), generate encryption keys and add to `app.env`: ```shell KEY_ID=$(uuidgen | tr -d '\r\n') && printf "ENCRYPTION_KEYS=[{\"id\": \"${KEY_ID}\", \"key\": \"$(openssl rand -base64 32 | tr -d '\r\n')\", \"cipher\": \"AES-GCM\", \"revoked\": false}]\nDEFAULT_ENCRYPTION_KEY_ID=\"${KEY_ID}\"\n" ``` Optional: Add Professional license key to `app.env`: ``` LICENSE="" ``` Optional: Professional installations need an additional docker container for the spell check. Add `languagetool/docker-compose.yml` to `docker-compose.yml` in the `deploy` directory: ``` name: sysreptor include: - sysreptor/docker-compose.yml - languagetool/docker-compose.yml ``` Create docker volumes: ```shell docker volume create sysreptor-db-data docker volume create sysreptor-app-data ``` Launch containers (from the `deploy` directory): ```shell docker compose up -d ``` Add initial superuser: ```shell username=reptor docker compose exec app python3 manage.py createsuperuser --username "$username" ``` Add demo data: ``` # Projects url="https://docs.sysreptor.com/assets/demo-projects.tar.gz" curl -s "$url" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=project --add-member="$username" # Designs url="https://docs.sysreptor.com/assets/demo-designs.tar.gz" curl -s "$url" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=design # Finding templates url="https://docs.sysreptor.com/assets/demo-templates.tar.gz" curl -s "$url" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=template ``` ::: ::: details Optional: Verify docker images ```shell SYSREPTOR_VERSION=$(cat sysreptor/deploy/.env | grep 'SYSREPTOR_VERSION=' | cut -d'=' -f2-) # SYSREPTOR_VERSION=$(docker exec -it sysreptor-app bash -c 'echo "$VERSION"') # Verify setup.tar.gz curl -s -L --output sysreptor.tar.gz.sigstore.json https://github.com/syslifters/sysreptor/releases/${SYSREPTOR_VERSION}/download/setup.tar.gz.sigstore.json cosign verify-blob sysreptor.tar.gz --key https://docs.sysreptor.com/cosign.pub --bundle sysreptor.tar.gz.sigstore.json # Verify docker images cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor:${SYSREPTOR_VERSION}" cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor-languagetool:${SYSREPTOR_VERSION}" # Pro only ``` ::: Access your application at http://127.0.0.1:8000/. We recommend [using a webserver](/setup/webserver) like Caddy (recommended), nginx or Apache to prevent [potential vulnerabilities](https://github.com/Syslifters/sysreptor/security/advisories) and to enable HTTPS. Further [configurations](/setup/configuration) can be edited in `sysreptor/deploy/app.env`. ## Stopping SysReptor To stop SysReptor and all associated containers, go to the `sysreptor/deploy` directory and run `docker compose stop`. ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/setup/configuration.md --- # Configuration `app.env` (located in `deploy` directory) controls the behaviour of your SysReptor installation. [Server settings](#server-settings) are defined in `app.env` and passed as environment variables to the SysReptor docker container. [Application settings](#application-settings) can be configured in `app.env` or via the settings page in the web interface. After making changes, go to `sysreptor/deploy` and restart the containers: ```shell docker compose up -d ``` ## Server Settings ### Django Secret Key Django server secret key (see https://docs.djangoproject.com/en/stable/ref/settings/#std-setting-SECRET\_KEY). Make sure this key remains secret. ```shell title="Generate random secret key:" printf "SECRET_KEY=$(openssl rand -base64 64 | tr -d '\r\n=')\n" ``` ```dotenv title="Example (regenerate this value!):" SECRET_KEY="TODO-change-me-Z6cuMithzO0fMn3ZqJ7nTg0YJznoHiJXoJCNngQM4Kqzzd3fiYKdVx9ZidvTzqsm" ``` If you renew the Django secret key, all existing sessions terminate and links for setting new passwords (e.g., from password reset emails) are invalidated. ### Data Encryption at Rest Encrypt data at rest by configuring an encryption key. This will encrypt sensitive data in your database and files uploaded in your notes (~~except images~~, images are also encrypted). Database and file storage administrators cannot access encrypted data. The key is held in the web application. Data encryption at rest does not help against malicious actors with access to the web server. You have to define one `DEFAULT_ENCRYPTION_KEY_ID` which will be used for data encryption. However, you can rotate your keys by defining multiple keys in `ENCRYPTION_KEYS`.\ All specified keys are used for decrypting stored data. Note that the `DEFAULT_ENCRYPTION_KEY_ID` must be part of `ENCRYPTION_KEYS`. ```shell title="Generate random encryption keys:" KEY_ID=$(uuidgen | tr -d '\r\n') && printf "ENCRYPTION_KEYS=[{\"id\": \"${KEY_ID}\", \"key\": \"$(openssl rand -base64 32 | tr -d '\r\n')\", \"cipher\": \"AES-GCM\", \"revoked\": false}]\nDEFAULT_ENCRYPTION_KEY_ID=\"${KEY_ID}\"\n" ``` ```dotenv title="Example (regenerate these values!):" ENCRYPTION_KEYS='[{"id": "TODO-change-me-unique-key-id-5cdda4c0-a16c-4ae2-8a16-aa2ff258530d", "key": "256 bit (32 byte) base64 encoded AES key", "cipher": "AES-GCM", "revoked": false}]' DEFAULT_ENCRYPTION_KEY_ID="TODO-change-me-unique-key-id-5cdda4c0-a16c-4ae2-8a16-aa2ff258530d" ``` ### Debug mode Debug mode enables Django's debug toolbar and stack traces. Do not use debug mode in production environments. ```dotenv title="Example:" DEBUG=off ``` ### Browsable API Enable the Django REST Framework browsable API interface for debugging and development purposes. The browsable API is enabled by default in debug mode. ```dotenv title="Example:" ENABLE_BROWSABLE_API=off ``` ### Allowed Hosts Comma-separated allowed hostnames/domain names for this installation. This setting might resolve issues with failing WebSocket connections. In production environments, `ALLOWED_HOSTS` must be set to your domain name(s). If left unset, any host header is accepted, which may expose your installation to security vulnerabilities. ```dotenv title="Example:" ALLOWED_HOSTS="sysreptor.example.com,sysreptor.example.local" ``` ::: warning Avoid wildcards A value with a leading dot (e.g. `.example.com`) is a wildcard that matches the domain and all its subdomains. Every host header matching the wildcard is accepted, including subdomains you do not control. Some links are built from the host header of the incoming request, most notably the confirmation link in password reset emails. An attacker who can send a request with a host header matching your wildcard can therefore trigger a password reset email that contains a link (including the valid reset token) pointing to a host they control. If the user clicks it, the token is leaked and their account can be taken over. List your exact hostnames instead of using a wildcard. ::: ### FIDO2/WebAuthn If you want to use FIDO2/WebAuthn for MFA, you have to define the hostname ([WebAuthn Relying Party ID](https://www.w3.org/TR/webauthn-2/#relying-party-identifier)) of your installation. ```dotenv title="Example:" MFA_FIDO2_RP_ID="sysreptor.example.com" ``` ### License Key License key for SysReptor Professional. ```dotenv title="Example:" LICENSE="your-license-key" ``` ### S3 Storage Uploaded files and images can be stored in an S3 bucket. Files are stored on the filesystem in a docker volume by default. If data at rest encryption is configured, all uploaded files (incl. images) are encrypted. `DEFAULT_S3_*` settings to apply to all file storages. It is possible to configure different settings per storage. ```dotenv title="Global storage configuration: store everything in S3 bucket" DEFAULT_STORAGE="s3" # Default: "filesystem" DEFAULT_S3_ACCESS_KEY="access-key" DEFAULT_S3_SECRET_KEY="secret-key" DEFAULT_S3_SESSION_TOKEN="session-token" # optional DEFAULT_S3_BUCKET_NAME="bucket-name" DEFAULT_S3_ENDPOINT_URL="endpoint-url" ``` ```dotenv title="Uploaded file storage configuration" UPLOADED_FILE_STORAGE="s3" # Default: "filesystem" UPLOADED_FILE_S3_ACCESS_KEY="access-key" UPLOADED_FILE_S3_SECRET_KEY="secret-key" UPLOADED_FILE_S3_SESSION_TOKEN="session-token" # optional UPLOADED_FILE_S3_BUCKET_NAME="bucket-name" UPLOADED_FILE_S3_ENDPOINT_URL="endpoint-url" UPLOADED_FILE_LOCATION="uploadedfiles" ``` ```dotenv title="Uploaded image storage configuration" UPLOADED_IMAGE_STORAGE="s3" # Default: "filesystem" UPLOADED_IMAGE_S3_ACCESS_KEY="access-key" UPLOADED_IMAGE_S3_SECRET_KEY="secret-key" UPLOADED_IMAGE_S3_SESSION_TOKEN="session-token" # optional UPLOADED_IMAGE_S3_BUCKET_NAME="bucket-name" UPLOADED_IMAGE_S3_ENDPOINT_URL="endpoint-url" UPLOADED_IMAGE_LOCATION="uploadedimages" ``` ```dotenv title="Uploaded asset storage configuration" UPLOADED_ASSET_STORAGE="s3" # Default: "filesystem" UPLOADED_ASSET_S3_ACCESS_KEY="access-key" UPLOADED_ASSET_S3_SECRET_KEY="secret-key" UPLOADED_ASSET_S3_SESSION_TOKEN="session-token" # optional UPLOADED_ASSET_S3_BUCKET_NAME="bucket-name" UPLOADED_ASSET_S3_ENDPOINT_URL="endpoint-url" UPLOADED_ASSET_LOCATION="uploadedasset" ``` Archived project files can also be uploaded to an S3 bucket. Archives are stored on the filesystem in a docker volume by default. ```dotenv title="Archived file storage configuratio" ARCHIVED_FILE_STORAGE="s3" # Default: "filesystem" ARCHIVED_FILE_S3_ACCESS_KEY="access-key" ARCHIVED_FILE_S3_SECRET_KEY="secret-key" ARCHIVED_FILE_S3_SESSION_TOKEN="session-token" # optional ARCHIVED_FILE_S3_BUCKET_NAME="bucket-name" ARCHIVED_FILE_S3_ENDPOINT_URL="endpoint-url" ARCHIVED_FILE_LOCATION="archivedfiles" ``` ### Emails SysReptor sends emails for password resets. Configure the SMTP server to use for sending emails. See https://docs.djangoproject.com/en/stable/ref/settings/#email-host ```dotenv title="Email settings" EMAIL_HOST=mail.example.com EMAIL_PORT=587 EMAIL_USE_TLS=on EMAIL_HOST_USER=username EMAIL_HOST_PASSWORD=password DEFAULT_FROM_EMAIL=sysreptor@example.com ``` To test your email settings, you can run the following command: ```shell title="Send test email" docker compose run --rm --no-TTY app python3 manage.py sendtestemail ``` ### Backup Key The backup key is used for creating backups via the [web interface](/setup/backups#create-backups-via-web-interface) or the [REST API](/setup/backups#create-backups-via-api). The key should be random and must have 20 or more characters.\ Make sure this key remains secret. ```shell title="Generate random backup key:" printf "BACKUP_KEY=$(openssl rand -base64 25 | tr -d '\r\n=')\n" ``` ```dotenv title="Example (do not use this value!):" BACKUP_KEY="WfyqYzRVZAOFbCtltYEFN36XBzRz6Ys6ZA" ``` Backup requests via the web interface or the REST API are long running requests that need to download a large backup file. These requests might be aborted when `gunicorn` server worker processes are restarted and the backup request exceeds the restart timeout. This timeout can be increased by setting the following value. ```dotenv title="Example:" SERVER_WORKER_RESTART_TIMEOUT=3600 # 1 hour ``` ### Reverse Proxy Interpret `X-Forwarded-*` headers when SysReptor is behind a reverse proxy. See also https://docs.djangoproject.com/en/stable/ref/settings/#use-x-forwarded-host ```dotenv USE_X_FORWARDED_HOST=on USE_X_FORWARDED_PORT=on ``` When SysReptor is accessible via HTTPS (recommended), use following setting to redirect all HTTP requests to HTTPS. This flag also enables setting the `Secure` flag for cookies. ```dotenv SECURE_SSL_REDIRECT=on ``` ### Proxy Server Set the proxy variables `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` to allow outbound connections using a proxy server. ```dotenv title="Example:" HTTP_PROXY="http://192.168.0.111:8080" HTTPS_PROXY="http://192.168.0.111:8080" ``` ::: info The proxy server must be reachable from container Make sure that the proxy server is reachable from inside your docker container. Loopback addresses (e. g. `127.0.0.1`) or `localhost` will not work. ::: ### Custom CA Certificates If your SysReptor is behind a proxy with a custom certificate, you can use this setting to specify your custom CA certificates. ```dotenv CA_CERTIFICATES="-----BEGIN CERTIFICATE-----\nMIIDqDCCApCgAwIBAgIFAMjv7sswDQYJKoZIhv..." ``` ### WebSockets Disable WebSockets and always use HTTP fallback for collaborative editing. This is not recommended because some features are only available with WebSockets and HTTP fallback has higher latency. This setting sould only be activated if WebSockets are blocked by a firewall or not supported by a reverse proxy. ```dotenv title="Example:" DISABLE_WEBSOCKETS=true ``` ## Application Settings Application settings can be configured in `app.env` or via the settings page in the web interface (stored in the database). When a setting is configured both in `app.env` (environment varaible) and via the settings page (database), the value from `app.env` takes precedence. Settings configured in `app.env` cannot be changed or overwridden via the web interface. ### Private Designs Users without Designer permission can create and edit private designs that cannot be read or used by other users. If a pentest project is created using a private design, a copy of the private design becomes accessible by project members. Use this setting to enable private designs. ```dotenv title="Example:" ENABLE_PRIVATE_DESIGNS=true ``` ### Compress Images Uploaded images are compressed to reduce file size, but to retain quality suitable for PDF files. Disable image compression using this setting. ```dotenv title="Example:" COMPRESS_IMAGES=false ``` ### PDF Rendering It is possible to generate accessible PDFs in PDF/UA format. Accessible PDFs can be read by screen readers and are compliant with accessibility standards. Generating accessible PDFs is incompatible with PDF compression. If you enable accessible PDFs, PDF compression is automatically disabled. ```dotenv title="Example:" GENERATE_ACCESSIBLE_PDFS=true ``` SysReptor limits the rendering time a PDF can take. If the rendering time exceeds the limit, the PDF render task is aborted. The default limit is 300 seconds (5 minutes). If you experience slow PDF rendering, try to [optimize your design](/designer/debugging#slow-pdf-rendering) before increasing the limit. ```dotenv title="Example:" PDF_RENDERING_TIME_LIMIT=300 ``` ### Sharing Settings Notes can be shared with people who do not have a SysReptor account via public links. See [Notes](/reporting/notes) for how to create and manage share links. These settings apply to the whole instance: you can turn off sharing completely, or require a password or read-only access on every shared link. ```dotenv title="Example:" DISABLE_SHARING=false SHARING_PASSWORD_REQUIRED=false SHARING_READONLY_REQUIRED=false ``` ### Languages Configure which languages are available in the language selection. By default all languages are shown. When this setting is configured, only selected languages are shown. All other languages are hidden. This setting also defines the order of languages in the selection. The first language is used as default. ```dotenv title="Example:" PREFERRED_LANGUAGES="de-DE,en-US" ``` ### Spell Check You can add words to the spell check dictionary in the markdown editor (see https://docs.sysreptor.com/reporting/spell-check/). Words are added to a global spell check dictionary by default, which is available to all users. If words should be added to user's personal spell check dictionaries, set this setting to `true`. Using both global and personal dictionaries at the same time is not possible. Words of personal dictionaries are not shared between users. If one user adds an unknown word to their personal dictionary, the spell checker will still detect an error for other users, even when they are working in the same project or finding. ```dotenv title="Spell check dictionary configuration" SPELLCHECK_DICTIONARY_PER_USER=false ``` The picky mode enables additional spell check rules. It is also possible to selectively enable and disable rules or rule-categories by passing a LanguageTool configuration as JSON. See https://languagetool.org/http-api/ for available options on the `/check` request. See https://community.languagetool.org/rule/list for available rules (note: rule IDs might differ for languages). ```dotenv title="Spell check rule configuration" SPELLCHECK_MODE_PICKY=true SPELLCHECK_LANGUAGETOOL_CONFIG='{"disabledRules": "TODO,TO_DO_HYPHEN,PASSIVE_VOICE,PASSIVE_SENTENCE_DE"}' ``` ### Archiving Archived projects require at least `ARCHIVING_THRESHOLD` number of users to restore the archive (see https://docs.sysreptor.com/reporting/archiving/). By default two users are required, enforcing a 4-eye principle. If `ARCHIVING_THRESHOLD=1` every user is able to restore archived projects on their own, disabling the 4-eye principle. Changing this setting does not affect previously archived projects. ```dotenv title="Example:" ARCHIVING_THRESHOLD=2 ``` If `PROJECT_MEMBERS_CAN_ARCHIVE_PROJECTS` is set to `true` (default), every project member can archive/restore a project. Otherwise, only users with global archiver permission can archive/restore projects. This means that encryption happens with fewer encryption keys and it will be more difficult to keep up the quorum (`ARCHIVING_THRESHOLD`) for restoring projects (this could lead to availability problems). ```dotenv title="Example:" PROJECT_MEMBERS_CAN_ARCHIVE_PROJECTS=false ``` The process of archiving finished projects and deleting old projects can be automated by following settings. The values are time spans in days. * `AUTOMATICALLY_ARCHIVE_PROJECTS_AFTER`: Finished projects are automatically archived X days after the project was finished (if possible). Re-activating the project resets the timer. * `AUTOMATICALLY_DELETE_PROJECTS_AFTER`: Finished (and archived) projects are automatically assigned a delete date X days after the project was finished. The delete date can be customized per project or set to never delete. Re-activating or restoring preserved the delete date. Active projects are never deleted. ```dotenv title="Example:" # Automatically archive finished projects after 3 months AUTOMATICALLY_ARCHIVE_PROJECTS_AFTER=90 # Automatically delete finished (and archived) projects after 2 years AUTOMATICALLY_DELETE_PROJECTS_AFTER=730 ``` ### Single Sign-On (SSO) Configuration for SSO via OIDC. Superusers can set this in **Settings → Authentication Settings** in the web interface, or in `app.env`. Find [detailed instructions](/users/oidc-setup). ```dotenv title="OIDC example:" OIDC_AUTHLIB_OAUTH_CLIENTS='{ "keycloak": { "label": "Keycloak", "client_id": "", "client_secret": "", "server_metadata_url": "https://keycloak.example.com/realms/dev/.well-known/openid-configuration", "client_kwargs": { "scope": "openid email", "code_challenge_method": "S256" }, "reauth_supported": false, "user_identifier_claim": "email", "require_email_verified": true } }' ``` We recommend SSO via OIDC. Use Remote-User authentication only if OIDC is not an option for your setup. If your reverse proxy enforces authentication and provides the username via a HTTP header, use the following settings to enable SSO. ```dotenv title="Remote-User example" REMOTE_USER_AUTH_ENABLED=true REMOTE_USER_AUTH_HEADER="Remote-User" ``` ::: danger The reverse proxy is the trust boundary With Remote-User authentication enabled, SysReptor trusts the configured header unconditionally. Anyone who can send this header to SysReptor can log in as any user, including superusers. * The SysReptor backend must not be reachable except through the authenticating reverse proxy. Bind it to localhost or an internal network and make sure no other route (container port mapping, load balancer, service mesh, VPN, host firewall rule) reaches it directly. * The reverse proxy must **overwrite** the authentication header on every inbound request, regardless of what the client sent. Removing the header only when it is present is not enough - it has to be set unconditionally from the authenticated identity. * Overwriting the canonical header name is not enough. HTTP headers reach the application as WSGI variables, where the header name is uppercased and `-` is replaced by `_`. `Remote-User`, `Remote_User`, `remote-user`, `remote_user` and any other case variant therefore all map to the same variable and are all accepted by SysReptor. Your proxy configuration must cover every spelling that normalizes to the configured header name, not just the canonical one. ::: By default users can decide whether they want to log in via SSO or username/password. It is possible to globally disable login via username/password via this setting. Make sure all users have SSO identities configured before enabling this option. Else they will not be able to log in anymore. It is also possible to disable username/password login for specific users via the user management. ```dotenv title="Disable username/password authentication example" LOCAL_USER_AUTH_ENABLED=false ``` Configuration of the default authentication provider when multiple authentication providers are enabled (e.g. OIDC via Microsoft Entra ID and username/password). This setting will redirect users to the default authentication provider, skipping the selection. Other authentication providers can still be used if login via the default provider fails. Possible values: `azure`, `google`, `remoteuser`, `local` (username/password authentication) ```dotenv title="Default authentication provider example" DEFAULT_AUTH_PROVIDER="azure" DEFAULT_REAUTH_PROVIDER="local" ``` ### Local User Authentication Local user authentication via username/password is enabled by default. Disable local user authentication to force users to use SSO. ```dotenv title="Example:" LOCAL_USER_AUTH_ENABLED=true FORGOT_PASSWORD_ENABLED=false ``` By enabling the `FORGOT_PASSWORD_ENABLED` option, users can reset their passwords via password-forgotten emails. This setting only takes effect if `ALLOWED_HOSTS` is set to a non-wildcard (`*`) value, `LOCAL_USER_AUTH_ENABLED=true` and email settings are configured. ### Guest User Permissions Restrict capabilities of guest users. ```dotenv title="Example:" GUEST_USERS_CAN_CREATE_PROJECTS=True GUEST_USERS_CAN_IMPORT_PROJECTS=False GUEST_USERS_CAN_EDIT_PROJECTS=True GUEST_USERS_CAN_UPDATE_PROJECT_SETTINGS=True GUEST_USERS_CAN_DELETE_PROJECTS=True GUEST_USERS_CAN_SEE_ALL_USERS=False GUEST_USERS_CAN_SHARE_NOTES=False ``` ### AI Agent Enable the AI Agent feature to assist with report writing and analysis. The AI Agent can be enabled or disabled globally. When disabled, the AI Agent feature is not available to any users. LLM models must be configured via `AI_AGENT_MODELS` before the feature can be used (see [LLM models](#llm-provider) below). ```dotenv title="Example:" AI_AGENT_ENABLED=true ``` Customize the disclaimer text shown to users when they use the AI Agent feature. ```dotenv title="Example:" AI_AGENT_DISCLAIMER="AI can make mistakes. Do not use without manual review." ``` Provide a custom system prompt to prime the AI Agent with specific instructions or context. This can be used to customize the behavior of the AI Agent for your organization's needs. This system prompt is appended to the default system prompt used by SysReptor. ```dotenv title="Example:" AI_AGENT_SYSTEM_PROMPT='Customized system prompt.' ``` #### LLM models {#llm-models} Configure LLM models for AI-assisted report writing and analysis. SysReptor uses [LangChain](https://docs.langchain.com/) to interface with different LLM providers. It is possible to use cloud-based LLM providers (e.g. OpenAI, Anthropic) as well as self-hosted LLMs (e.g. via VLLM). The quality of the output strongly depends on the chosen LLM model. Smaller (e.g. self-hosted) models might perform worse than larger (cloud-based) models. ```json AI_AGENT_MODELS='[ { "id": "gpt-oss-120b", "model": "gpt-oss-120b", "api_key": "...", "base_url": "https://llm.example.com/" } ]' ``` Each entry describes one model. The first entry is the default model. When multiple models are configured, users can select the model in the AI chat. Model IDs and labels are exposed to all authenticated users; API keys and other secrets are not. | Field | Description | | --- | --- | | `id` | Unique identifier used for model selection in SysReptor | | `model` | Model name passed to LangChain (e.g. `gpt-5`, `claude-opus-4-8`) | | `provider` | LangChain provider (e.g. `openai`, `anthropic`, `deepseek`, `mistralai`, `ollama`). Defaults to OpenAI-compatible provider (`deepseek`) | | `api_key` | API key for the provider | | `base_url` | API base URL (for OpenAI-compatible or custom endpoints) | | `label` | Display name in the UI (defaults to `id`) | | *other* | Additional model-specific LangChain parameters (e.g. `temperature`, `reasoning_effort`, etc.) | Many LLM providers offer OpenAI-compatible APIs. You can use the `openai` or `deepseek` provider to connect to OpenAI-compatible APIs by setting `base_url`. The provider name refers to API format capability, not the specific LLM vendor. LangChain's `deepseek` provider supports OpenAI-compatible APIs and parses reasoning outputs. This enables displaying reasoning steps in the web interface. The standard `openai` provider also works but omits reasoning content. The `deepseek` provider has nothing to do with the Deepseek LLM vendor. ::: details LLM provider examples **OpenAI-compatible** APIs with reasoning (e.g. LiteLLM, VLLM, OpenRouter, TogetherAI, DeepSeek, etc.) ```json { "id": "gpt-oss-120b", "label": "GPT OSS 120B", "provider": "deepseek", "model": "gpt-oss-120b", "api_key": "...", "base_url": "https://llm.example.com:4000/" } ``` **OpenAI** ```json { "id": "gpt-5", "label": "GPT 5", "provider": "openai", "model": "gpt-5", "api_key": "..." } ``` **Anthropic** ```json title="Anthropic" { "id": "claude-opus-4-8", "label": "Claude Opus 4.8", "provider": "anthropic", "model": "claude-opus-4-8", "api_key": "..." } ``` **Mistral AI** ```json { "id": "mistral-large", "label": "Mistral Large", "provider": "mistralai", "model": "mistral-large-2512", "api_key": "..." } ``` **Ollama** ```json { "id": "llama3.1", "label": "Llama 3.1", "provider": "ollama", "model": "llama3.1", "api_key": "...", "base_url": "https://llm.example.com/" } ``` If your LLM provider is not listed above, you can use an LLM proxy like [LiteLLM](https://docs.litellm.ai/) or [OpenRouter](https://openrouter.ai/) that provides an OpenAI-compatible API. Configure the proxy to connect to your LLM provider, then use the `deepseek` provider (as shown above) to connect SysReptor to the proxy. This approach works with any LLM that your proxy supports and enables reasoning output display when available. ::: To test your LLM settings, run: ```shell docker compose run --rm app python3 manage.py aichat --agent=project_ask --user= --project= ``` ### Custom Statuses It is possible to define custom statuses for findings and sections. In addition to the custom statuses the statuses `in-progress` and `finished` are always available. By default, the statuses `ready-for-review` and `needs-improvement` are also available. ```dotenv title="Example:" STATUS_DEFINITIONS='[ {"id": "ready-for-review", "label": "Ready for review", "icon": "mdi-check"}, {"id": "needs-improvement", "label": "Needs improvement", "icon": "mdi-exclamation-thick"}, ]' ``` It is possible to enforce specific status transition workflows by defining which statuses can follow each status. This is useful for implementing review processes where certain steps must be followed in order. Use the `allowed_next_statuses` field to specify which statuses can be set after the current status. When `allowed_next_statuses` is not defined or an empty list, any status transition is allowed. To define a terminal status where no further transitions are allowed, set `allowed_next_statuses` to the current status. Status transitions for built-in statuses (`in-progress`, `finished`) can also be restricted by defining them in `STATUS_DEFINITIONS`. Please note that `in-progress` is always the initial status and `finished` should be the last status. ```dotenv title="Example: Linear workflow" STATUS_DEFINITIONS='[ {"id": "in-progress", "label": "In progress", "icon": "mdi-pencil", "allowed_next_statuses": ["ready-for-review"]}, {"id": "ready-for-review", "label": "Ready for review", "icon": "mdi-check", "allowed_next_statuses": ["needs-improvement", "finished"]}, {"id": "needs-improvement", "label": "Needs improvement", "icon": "mdi-exclamation-thick", "allowed_next_statuses": ["ready-for-review"]}, {"id": "finished", "label": "Finished", "icon": "mdi-check-all", "allowed_next_statuses": ["finished"]} ]' ``` Note: `allowed_next_statuses` is not enforced for [superusers with enabled admin permissions](/users/user-permissions#superuser). This is to allow administrators to fix incorrect status assignments if necessary. ### Plugins Extend the functionality of SysReptor by enabling plugins. The plugins `cyberchef`, `renderfindings`, and `scanimport` are enabled by default. All other plugins need to be explicitly enabled. Enable plugins in the application settings page in the web interface by ticking plugin enabled checkboxes. You can also manage plugins via the environment variable `ENABLED_PLUGINS` in `app.env`. `ENABLED_PLUGINS` is a comma separated list of plugin names or plugin IDs. If `ENABLED_PLUGINS` is set in `app.env`, it takes precedence and the Settings UI will be read-only for plugin enable/disable. ```dotenv title="Example:" ENABLED_PLUGINS="cyberchef,graphqlvoyager,checkthehash" ``` Some plugins require additional configuration. These plugin settings are configured as separate entries in `app.env` or via the settings page in the web interface. Please refer to the plugin documentation for more information on available plugin setting. --- --- url: https://docs.sysreptor.com/setup/webserver.md --- # Setup Webserver The Django webserver is not recommended due to missing transport encryption, missing performance and security tests.\ We recommend a webserver like Caddy, [nginx](/setup/webserver-nginx) or Apache and to enable https. ## Easy setup with Caddy (recommended) {#caddy} You can run `setup.sh` in `deploy/caddy` to set up an additional Docker container with Caddy as a webserver. ``` bash deploy/caddy/setup.sh ``` ### Optional: LetsEncrypt HTTPS certificate If you want Caddy to take care of your LetsEncrypt certificate, you must set up: 1. a valid domain name resolving to your public IP address 2. port 80 of your must be publicly reachable --- --- url: https://docs.sysreptor.com/setup/updates.md --- # Updates We recommend to create a [backup](/setup/backups) of your installation before updating. ::: tabs \== Update via Script (recommended) We deliver the shell script `update.sh` in the `sysreptor` directory. If updates are available, the script downloads the release from GitHub. It replaces your Docker images by the newest release and restarts all containers. Your current SysReptor directory will be renamed for backup purposes. The script will download the newer version and place it into the directory where the old version was. It will then copy your `app.env`, `.env`, `docker-compose.yml` and if present the `Caddyfile` to the correct locations of your newer version. The new SysReptor version launched and the docker images of your old verions are cleaned up. ```shell title="Run update script:" bash sysreptor/update.sh ``` Using the `--backup` switch, a SysReptor backup will be created prior to the update. The update will fail if the backup fails. ```shell title="Run update script:" bash sysreptor/update.sh --backup ``` Please make sure to monitor your disk space and clean up old backups, as automatic backups might increase disk usage significantly. \== Manual update Download and extract the latest SysReptor release: ```shell curl -s -L --output sysreptor.tar.gz https://github.com/syslifters/sysreptor/releases/latest/download/setup.tar.gz tar xzf sysreptor.tar.gz ``` Copy the following files from your old installation to the new installation. * `deploy/app.env` * `deploy/docker-compose.yml` * `deploy/caddy/Caddyfile` (optional, if present) Copy the contents of your `deploy/.env` file to the new installation. Make sure to keep the new version number intact and don't replace it by the old version number. If the new release includes an executable `post_update.sh` in the SysReptor root directory, run it before launching the containers. This script performs host-level post-update tasks such as configuration or database upgrades: ```shell cd sysreptor ./post_update.sh ``` Then `cd` to `sysreptor/deploy` and launch the containers: ```shell docker compose up -d ``` ::: ::: details Optional: Verify docker images ```shell SYSREPTOR_VERSION=$(cat sysreptor/deploy/.env | grep 'SYSREPTOR_VERSION=' | cut -d'=' -f2-) # SYSREPTOR_VERSION=$(docker exec -it sysreptor-app bash -c 'echo "$VERSION"') # Verify setup.tar.gz curl -s -L --output sysreptor.tar.gz.sigstore.json https://github.com/syslifters/sysreptor/releases/${SYSREPTOR_VERSION}/download/setup.tar.gz.sigstore.json cosign verify-blob sysreptor.tar.gz --key https://docs.sysreptor.com/cosign.pub --bundle sysreptor.tar.gz.sigstore.json # Verify docker images cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor:${SYSREPTOR_VERSION}" cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor-languagetool:${SYSREPTOR_VERSION}" # Pro only ``` ::: Find instructions how to [downgrade](/setup/downgrades) to previous versions. ## Recommended: Automatic updates We recommend to deploy automatic updates and run the script once per day. This ensures you receive updates early. If `cron` is not installed, install and start: ```shell sudo apt update sudo apt install -y cron sudo systemctl start cron #sudo /etc/init.d/cron start ``` Open `crontab`: ```shell crontab -e ``` Schedule your update, e.g. every day at midnight: ```shell 0 0 * * * /bin/bash /home/yourpath/sysreptor/update.sh # Optional (pro only): --backup ``` Make sure your user has write permissions to the parent directory of your SysReptor directory. In this example, you need write permissions to `/home/yourpath/`. --- --- url: https://docs.sysreptor.com/setup/backups.md --- # Backups ## Create backups via CLI Backups can be created via a CLI command or an API request. The backup archive contains a database export and all uploaded files. Execute following command to create a backup: ```shell title="Create backup via CLI" docker compose run --rm app python3 manage.py backup > backup.zip ``` Backups can be encrypted using a 256-bit AES key. Specify the key as hex string via the `--key` CLI argument. ```shell title="Create encrypted backup via CLI" docker compose run --rm app python3 manage.py backup --key="" > backup.zip.crypt ``` To avoid exposing the key in the process list (e.g. interactive use), pass `--key=-` to enter the hex key from the terminal without echo: ```shell title="Create encrypted backup with key from terminal" docker compose run --rm -it app python3 manage.py backup --key=- > backup.zip.crypt ``` ## Create a backup during update When [updating](/setup/updates) SysReptor, you can use the `--backup` switch, which will create a backup before applying the update. ## Create backups via web interface · Users with [`superuser` permissions](/users/user-permissions#superuser) and access to the [`BACKUP_KEY`](/setup/configuration#backup-key) can create backups using the web interface. If no [`BACKUP_KEY`](/setup/configuration#backup-key) is configured, you cannot create backups via the web interface. ## Create backups via API · Users with [`superuser` permissions](/users/user-permissions#superuser) and [`system` users](/users/user-permissions#system) can [create backups via the API](https://demo.sysre.pt/api/public/utils/swagger-ui/#/v1/v1_utils_backup_create) in combination with the configured [`BACKUP_KEY`](/setup/configuration#backup-key). If no `BACKUP_KEY` is configured, the backup API endpoint is disabled. The backup can optionally be encrypted via a 256-bit AES key provided in the HTTP request body or pushed to an S3 bucket (see [API parameters](https://demo.sysre.pt/api/public/utils/swagger-ui/#/v1/v1_utils_backup_create)). ### API Requests ``` # Create backup curl -X POST https://sysreptor.example.com/api/v1/utils/backup/ -d '{"key": ""}' -H 'Authorization: Bearer ' -H "Content-Type: application/json" -o backup.zip # Create encrypted backup curl -X POST https://sysreptor.example.com/api/v1/utils/backup/ -d '{"key": "", "aes_key": ""}' -H 'Authorization: Bearer ' -H "Content-Type: application/json" -o backup.zip.crypt ``` ## Restore backups Make sure that you have an empty database and empty data directories (i.e. empty docker volumes). Otherwise, you will **lose your old data**. During the backup restore, all existing data in the database and file storages is deleted. It is recommended to import the backup into the same SysReptor version like the one that was used to create the backup. If a different version is used the database schema might not be compatible. ```shell title="Restore backup via CLI" cat backup.zip | docker compose run --rm --no-TTY app python3 manage.py restorebackup ``` Encrypted backups can be restored as well. Specify the AES key as hex string via the `--key` CLI argument. ```shell title="Restore encrypted backup via CLI" cat backup.zip.crypt | docker compose run --rm --no-TTY app python3 manage.py restorebackup --key="" ``` To avoid exposing the key in the process list, pass `--key=-` and provide the backup as a file path: ```shell title="Restore encrypted backup with key from terminal" docker compose run --rm -it app python3 manage.py restorebackup --key=- backup.zip.crypt ``` --- --- url: https://docs.sysreptor.com/setup/upgrade-to-professional.md --- # Upgrade to Professional You can upgrade from SysReptor Community to SysReptor Professional anytime without reinstallation. All your data will be preserved.\ Here's how: 1. Add your license key to `deploy/app.env` (`LICENSE='your_license_key'`) 2. Add languagetool to `deploy/docker-compose.yml`: ``` name: sysreptor include: - sysreptor/docker-compose.yml - languagetool/docker-compose.yml ``` 3. `cd` to `deploy` and run `docker compose up -d` 4. Enjoy ## From Professional to Community For reverting to community, remove or comment out the license key from `deploy/app.env`.\ You can also remove `languagetool/docker-compose.yml` from `deploy/docker-compose.yml`. This saves resources (one docker container), as languagetool is not available in SysReptor Community. Moving from Professional to Community does not result in data loss. All data will be preserved.\ Non-superuser accounts, will, however, no longer be able to log in. ::: info Interested in SysReptor Professional?\ Book a Teams call with us and get you questions answered. [Choose your time slot](https://cloud.syslifters.com/apps/appointments/pub/tBtAMcEwczA5CDMv/form) ::: --- --- url: https://docs.sysreptor.com/reporting/markdown-features.md --- # Markdown Features The markdown syntax used in this project is based on the [CommonMark spec](https://spec.commonmark.org/) with some extensions. This document briefly describes the most important markdown syntax. Non-standard markdown syntax is described more detailed. ## Common Markdown ````md # Heading h1 ## Heading h2 ### Heading h3 #### Heading h4 Inline text styling: **bold**, _italic_, ~~strikethrough~~, `code` Links: [Example Link](https://example.com) or * list * items * nested list 1. numbered 2. list ```shell echo "multiline code block"; # with syntax highlighting ``` ```` ## Underline Underline is not supported in markdown. However you can insert HTML `` tags to underline text. ```md Text with underlined content. ``` ## Images Images use the standard markdown syntax, but are rendered as figures with captions. ```md ![Figure Caption](img.png){width="50%"} ![caption _with_ **markdown** `code`](img.png) ``` ```html
Figure Caption
``` ## Footnotes ```md Text text^[footnote content] text. ``` ## Tables For tables the GFM-like table syntax is used. This syntax is extended to support table captions. ```md | table | header | | ------- | ------- | | cell | value | : table caption ``` Markdown tables are somewhat limited and do not support rowspans, colspans or multiline cell values. If you need one of these features, you can fall back to writing tables as [inline HTML](#inline-html). ## Code blocks Code blocks allow including source code and highlight it. The following example shows how to apply syntax highlighting to a HTTP request. Many other programming languages are also supported. ````md ```http POST /login.php HTTP/1.1 Host: sqli.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 33 username='or'1'='1&password=dummy ``` ```` ![Code Block Highlighting](/images/md_code_highlight.png) Syntax highlighting is great for readability, but it only highlights predefined keywords of the specified language. However, it does not allow to manually highlight certain text parts to draw the readers attention to it. You can enable manual highlighting by adding code-block meta attribute `highlight-manual`. It is now possible to encapsulate highlighted areas with `§§highlighted content§§`. In the rendered HTML code, the content inside the two `§§`-placeholders is wrapped by a HTML `` tag. This works in combination with language-based syntax highlighting. This example highlights the vulnerable POST-parameter `username` in the HTTP body. ````md ```http highlight-manual POST /login.php HTTP/1.1 Host: sqli.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 33 §§username='or'1'='1§§&password=dummy ``` ```` ![Manual Code Block Highlighting](/images/md_code_manual_highlight.png) If you need more advanced highlighting, you can place custom HTML code inside the `§§` placeholders e.g. `§§Highlight this text.§§`. If your code snippet includes `§`-characters, you cannot use them as escape characters for manual highlighting. It is possible to specify a different escaple character via the `highlight-manual=""` attribute. Make sure that the escape character is not present in the code block. The following example uses `"|"` as escape character and a custom HTML markup for highlighting. ````md ```http highlight-manual="|" POST /login.php HTTP/1.1 Host: sqli.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 33 ||username='or'1'='1||&password=dummy ``` ```` ## Mermaid Diagrams [Mermaid](https://mermaid.js.org/intro/) lets you create diagrams and visualizations using text and code. It is a JavaScript based diagramming and charting tool that renders Markdown-inspired text definitions to create and modify diagrams dynamically. Mermaid diagrams are written in markdown code blocks with the language set to `mermaid`. All diagram types supported by mermaid are avaialbe. Diagrams will be rendered as HTML `
` elements. Like with images, you can set a caption and with/height. The following example shows how to create a simple flowchart. ````md ```mermaid caption="Organizational Structure" width="50%" flowchart TD A[👔 CEO] A-->B[💻 CTO] A-->C[💰 CFO] A-->D[📈 COO] ``` ```` ![Mermaid Diagram Example: Organizational Structure](/images/md_mermaid_diagram_organization.png){width="50%"} ````md ```mermaid caption="Man in the Middle Attack" %%{init: {"sequence": {"mirrorActors": false}}}%% sequenceDiagram actor Alice actor Eve actor Bob Eve->>Alice: give public key, pretend it is Bob's Alice->>Alice: encrypt message with Eve's key
thinking it is Bob's Alice->>Eve: send encrypted message Eve->>Eve: decrypt message and copy content Eve->>Eve: encrypt message using Bob's key Eve->>Bob: send encrypted message ``` ```` ![Mermaid Diagram Example: Man in the Middle Attack](/images/md_mermaid_diagram_mitm.png) ## Math Expressions You can include mathematical expressions and equations using LaTeX syntax. Math expressions are rendered using KaTeX for high-quality mathematical typesetting. For inline math expressions within text, wrap the LaTeX code with single dollar signs `$`. ```md The quadratic formula is $x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$ which solves quadratic equations. Einstein's famous equation is $E = mc^2$. ``` For larger equations or formulas that should be displayed on their own line, use double dollar signs `$$` to create a math block. ```md The Gaussian integral: $$ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} $$ ``` ## HTML Attributes This extension allows you to set HTML attributes from markdown. Place attributes in curly braces directly after the targeted element (without spaces between). Attributes are key value pairs (`attr-name="attr-value"`) Shortcuts for setting the attribute `id` (`#id-value`) and `class` (`.class-value`) are supported. ````md ## Headline in Table of Contents {.in-toc .numbered} ![image](img.png){#img-id .image-class1 .image-class2 width="50%"} Text with [styled link](https://example.com/){class="link-class" style="color: red"} in it. ```shell {#code-id .code-class} echo "code block" ``` ```` ## Inline HTML If something is not possible with markdown, you can fall back to writing HTML code and embed it in the markdown document. Following example shows a figure containing two images side-by-side. ```md Text *with* **markdown** `code`.
Two images side-by-side
``` It is also possible to embed markdown inside HTML blocks. An empty line is required as a seperator between HTML and markdown. Following example shows a complex table that is not possible with the markdown table syntax. ```md Text *with* **markdown** `code`.
Col1 Col2
Sub-header spanning two columns
Cell 1 This cell is rendered as markdown. You can use * `markdown` _elements_ * such as **lists** for example * but make sure to seperate HTML and markdown blocks with an empty line
``` --- --- url: https://docs.sysreptor.com/reporting/notes.md --- # Notes Use **notes** as a scratchpad during an engagement: command output, screenshots, checklists, and anything else you do not want in the final PDF. You organize them in a free-form tree. The **report** (sections and findings) is the structured deliverable. It follows the project design and is what you publish for the client. SysReptor has two note areas: * **Project notes**: accessible by all project members, follows the project life cycle * **Personal notes**: accessible only by you ## Organizing notes Drag notes in the sidebar to reorder them or move them under another note. Any note can have child notes. ![Note tree in a project](/images/note-taking.png) Click the checkbox on a note to cycle through unchecked, checked, and emoji. On **project notes**, you can also set an assignee for ownership during the engagement. Select one or more notes and use the menu in the sidebar to import, export, export as PDF, copy, or delete in bulk. Project notes are included in [Version History](/reporting/version-history). Personal notes are not. ## Note types Pick a type from the **Add** menu when creating a note. **Text notes** use the same markdown as [report fields](/reporting/markdown-features). Paste images, upload files, and paste command output as you go. **Excalidraw notes** open an embedded [Excalidraw](https://excalidraw.com/) canvas for diagrams and sketches. ![Excalidraw notes](/images/note_excalidraw.gif) ## Downloading files Files attached to a note are downloaded by clicking the file link in the preview. Corporate proxies and firewalls often inspect downloads and block the files pentesters work with, such as tool output, captures or proof of concept code. **Right-click a file link** and choose *Download via encrypted channel* to work around this. ![Download a file via an encrypted channel](/images/encrypted-download.png) The file is then transferred as an encrypted text stream and decrypted in your browser. Proxies see neither the file content, nor its content type, nor its filename. The key is generated by your browser for every download, so a recorded response cannot be decrypted afterwards. The stream is compressed, so an encrypted download transfers roughly the same number of bytes as a normal one. This hides the download from proxies that inspect content. It is not a protection against a proxy that intercepts TLS and specifically targets SysReptor, because the key is sent over the same connection. ## Collaborative editing Several pentesters can edit the same note at once; changes sync in real time. See [Collaborative Editing](/reporting/collaborative-editing). ## Sharing Use the share button on a note to give someone without a SysReptor login access via a public link. The link includes that note and all of its children. You can create multiple links per note. Each link has its own settings: * **Password**: Optional. Visitors must enter the password in addition to opening the link. * **Expire date**: The link expires after this date. * **Read-only** or **read-write access**: When write access is enabled, visitors can edit note contents; otherwise the link is read-only. * **Revoked**: Disable the link immediately without deleting it. * **Comment**: Optional, internal comment about the share link to tell links apart and document with whom the link was shared. The link exposes the note and its children, plus files and images that were linked in that tree when the share was created, and any files uploaded through that share. Editing notes (by visitors or project members) cannot automatically pull in other existing project or personal files. If someone references a file that is not yet on the share, project members can use **Review shared files** to approve it and make it visible on the link. To expose a file without approval, re-upload it to the shared note tree. On **Publish**, *Share by Link* generates the report PDF, creates a project note with the file attached, and opens the same sharing dialog so you can send the PDF to the client. ![Share notes](/images/share_notes.gif) Instance administrators can turn off note sharing with `DISABLE_SHARING` in [Application Settings](/setup/configuration#application-settings) or `app.env`. --- --- url: https://docs.sysreptor.com/reporting/comments-and-review.md --- # Comments and Review Before a report goes to the client, findings and sections usually pass through an internal review. **Statuses** and **assignees** show where each item stands and who owns it. On SysReptor Professional, **comments** let the team discuss specific report fields without leaving the editor. ## Comments Comments are available on report sections and findings. You can attach them to **any report field** (markdown, string, CVSS, and so on) or to a **text selection** inside a markdown field. Selection comments are highlighted in the editor and quoted in the sidebar. ![Comments on report fields](/images/comments.png) The **Comments** sidebar groups threads by field. Each comment supports **replies**. `@username` mentions notify project members; assignees are notified when someone comments on their finding or section. See [Notifications](/users/notifications). Comments sync in real time with [collaborative editing](/reporting/collaborative-editing) on the same item. ## Statuses Every finding and report section has a **status** and an optional **assignee** (a project member). Out of the box you get *In progress*, *Ready for review*, *Needs improvement*, and *Finished*. Your instance may show more if an admin added custom statuses. Set status and assignee in the toolbar when you open a finding or section. The report sidebar shows both for every section and finding, so you can scan progress without opening each item. If your design defines a retest status field, that appears in the sidebar as well. Marking one finding *Finished* is not the same as finishing the project. When you mark a **project as finished** in project settings, the whole project becomes read-only until someone reactivates it. ## Custom status workflows By default you can move between any status. Some teams want a fixed review flow — for example, *In progress* may only go to *Ready for review*, and only from there to *Finished* or *Needs improvement*. Instance administrators configure that with `STATUS_DEFINITIONS` and `allowed_next_statuses`. Examples and the full option list are in [Custom Statuses](/setup/configuration#custom-statuses). Superusers with admin permissions can override restricted transitions when they need to correct a status. --- --- url: https://docs.sysreptor.com/reporting/version-history.md --- # Version History The Version History allows you to view previous versions of objects (such as Projects, Findings, Notes, Templates, Designs) and shows you who made changes and when. (Personal notes do not have a version history.) ![Version History of Finding](/images/finding_history.png) New versions are created time-based and action-based. Action-based versions are created when fields change that have a bigger impact on the state of the saved object. For example when: * an object is created or deleted * a project is marked as finished * the project design changes or * the status or assignee of an object changes Time-based versions are created with every save operation. A scheduled task then cleans up the versions so that there is one version for about every two hours. When users pauses for longer, the last state of their changes are saved. If other users make changes in the meantime, it is still possible to view the object at the time where the first user left off. ## Deletion If you delete a finding or a note in a project, the version history is preserved. You can access deleted items in the project overview. ![Access deleted note](/images/deleted_note.png) However, if you delete a Project, Design or Finding Template, the history is deleted either. ## Exports If you export an object (e.g. a project) it does not include the version history. This is to prevent unintended leaks of sensitive information and to reduce the file size of exported objects. This means that if you export and re-import a project, it will no longer have a version history (but the original project will). ## Encrypted Archiving If projects are [archived](/insights/archiving), the version history is deleted. ## Backups [Backups](/setup/backups) include the version history. If a backup is restored, the version history is either. --- --- url: https://docs.sysreptor.com/reporting/spell-check.md --- # Spell Check We provide spell checking via the Open Source version of [LanguageTool](https://github.com/languagetool-org/languagetool). Language Tool runs isolated from other processes in separate container. The application reaches LanguageTool via REST-API. ## Add Words to Dictionary Users can add words to the LanguageTool dictionary. ![Add to dictionary](/images/add_to_dictionary.png) This updates the dictionary for all users by default. You can configure your installation to add words to a per-user dictionary.\ Per-user dictionaries are not shared between users. When one user adds an unknown word to his dictionary, it will still be unknown for other users. This is even when they are working on the same project and the same finding. This is an installation-wide setting. It cannot be configured per user or project. Set the `SPELLCHECK_DICTIONARY_PER_USER=true` in your [application settings](/setup/configuration#spell-check). PS: You can also configure the [spell check rules](/setup/configuration#spell-check). --- --- url: https://docs.sysreptor.com/reporting/references.md --- # References Use the `id`-attributes of HTML elements for referencing items in your report. This allows you to reference for example: * Headings * Figures * Tables * Findings * and everything that has an `id` ## Reference Images ```md title="Markdown" ![SQL Injection](/assets/name/image.png){#sqli} As you see in [](#sqli) (e.g. rendered as "Figure 3") ``` ```html title="HTML"
SQL Injection
As you see in (e.g. rendered as "Figure 3") ``` ## Reference Findings You need the finding ID of the finding you want to reference. The markdown editor toolbar in projects provides a button to insert finding references. ![Insert finding reference](/images/reference-finding.png) ```md title="Markdown" See [](#00000000-0000-0000-0000-000000000000)... (e.g. rendered as "1.3 SQL injection") ``` ```html title="HTML" See ... (e.g. rendered as "1.3 SQL injection") ``` ## Reference Headings You can reference headings if your [design supports it](/designer/headings-and-table-of-contents#referencing-sections-in-text-outside-of-toc). ```md title="Markdown" # Findings {#findings .in-toc.numbered} Find details in [](#findings) (rendered as "1 Findings"). ``` ```html title="HTML"

Findings

Find details in (rendered as "1 Findings"). ``` --- --- url: https://docs.sysreptor.com/finding-templates/create-finding.md --- # Creating findings from templates When creating new findings, you can select a template to use. The contents of template fields are copied to a new finding. The template searchbar searches in template tags and the titles of all template translations. For example you can search for `xss` to find all templates containing the tag `xss` or the word `xss` in the title of any translation (English, German, etc.). ![Create finding from template](/images/create_finding_from_template.png) When selecting a template, you can select the language of the template to use. By default the language of the pentest project is selected. If no translation for the selected language is available, the main language of the template is used. --- --- url: https://docs.sysreptor.com/reporting/collaborative-editing.md --- # Collaborative Editing Collaborative editing allows multiple pentesters to simultaneously work on the same finding, section or note. Changes are synchronized in real-time, so you can see what others are typing. ![Collaborative Editing](/images/collaborative-editing.png) ## HTTP Fallback Collaborative editing uses WebSockets for real-time communication. If no WebSocket connection can be established (e.g. because your network blocks WebSocket connections or your reverse proxy is not configured propertly yet), we fall back to HTTP polling. HTTP Polling has higher delays than WebSockets and transmitting user's cursor positions is disabled. We recommend to fix your network or reverse proxy configuration to use WebSockets for a better user experience. --- --- url: https://docs.sysreptor.com/reporting/image-editor.md --- # Image Editor The built-in image editor supports annotating and cropping images directly in the markdown editor. It can be used to highlight areas, add labels, crop screenshots, and redact sensitive information without leaving the report. The editor can be opened from the markdown preview: click an image to open the image dialog, then select **Edit Image**. ![Image editor](/images/image-editor.png) The image editor supports the following annotations and tools: * **Select:** Move, resize, or rotate objects. * **Rectangle (outline)** / **Rectangle (filled):** Draw rectangles. * **Ellipse:** Draw ellipses. * **Line:** Draw straight lines. * **Text:** Place editable text labels. * **Numbered marker:** Place markers with numbers; drag the tip to point at regions. * **Crop:** Define a region; switch to another tool to apply. * **Color:** Set stroke and fill for new and selected shapes. * **Stroke width:** Set line thickness and text size. **Save** updates the image and the markdown reference. If the image was edited before, **Revert** restores the original. Color and stroke width are remembered for the next session. The original image is kept internally to support Revert. It is not included in reports and is never exported; only the annotated/redacted image is included. ## Redacting images Redaction is the removal or masking of sensitive information before an image is shared (e.g. passwords, API tokens, personal identifying information, etc.). SysReptor offers multiple methods for redaction: * **Pixelate**: Suitable for hiding details while keeping the screenshot visually consistent. * **Filled rectangle**: Suitable for a clear, unambiguous mask, especially for highly sensitive text such as secrets, credentials, or tokens. * **Crop**: Suitable when the sensitive area can be removed entirely without losing important context. ::: info The pixelated region is generated without sampling any source pixels from inside the redacted area. Instead, synthetic pixels are derived from image content outside the selection (around redaction borders). As a result, the exported image contains no embedded data from the redacted area, and the original content cannot be recovered from the saved file. ::: ![Pixelate image](/images/image-editor-pixelate.gif) --- --- url: https://docs.sysreptor.com/reporting/ai-agent.md --- # AI Agent The AI agent assists with pentest report writing and analysis. It can answer questions about your project, suggest and review content, create and edit findings and sections. To be able to use the agent, enable it in applications settings and configure an LLM provider (see [configuration](/setup/configuration#ai-agent)). Multiple LLM providers and also self-hosted models are supported. ![AI agent](/images/ai-agent.png) The agent has access to project data through context and tools. ## Project scoping The SysReptor AI agent is bound to the **current pentest project** only. It **can**: * Read that project's structure, report sections, findings, notes, and the project's design field definitions * See which section, finding, or note you currently have open in the UI * Search **finding templates** in the instance knowledge base (templates are shared, not limited to one project) It **cannot**: * Read or edit **other projects** * Access other users' private data, instance admin settings, or findings and notes that belong to a different project ## Agent Mode * **Ask**: Read-only. The agent can view the project and answer questions or suggest text. It does not create or edit any data; you copy and apply suggestions yourself. * **Agent** (): Full write access in this project. In addition to everything in Ask mode, the agent can create findings and notes and update section, finding, and note fields. ## Asking clarifying questions When information is missing or there are multiple valid approaches, the agent can pause and ask you a multiple-choice question. Pick an option (or type your own answer) to continue, or send a new message to skip the question. ## Example Use Cases * Generate executive summary from findings * Generate finding recommendation from technical description * Review texts for grammar and spelling * Create findings from notes * Analyze the report and ask questions about it * and much more --- --- url: https://docs.sysreptor.com/reporting/shortcuts.md --- # Shortcuts Below is a list of shortcuts that SysReptor currently supports. ## Project shortcuts These shortcuts work in SysReptor projects, including findings, sections and notes. * `CTRL + Z` - Undo * `CTRL + SHIFT + Z` / `CTRL + Y` - Redo * `CTRL + S` - Save design/template * `CTRL + SHIFT + F` - Search in all notes/findings/sections * `CTRL + J` - Create a new note/finding * `CTRL + ALT + M` - Create comment Multi-select in the reporting sidebar (findings, sections) and note tree: * `CLICK` - Select item and navigate * `CTRL + CLICK` - Toggle item in multi-selection * `SHIFT + CLICK` - Select range from last clicked item to current item ## Markdown shortcuts These shortcuts work while editing [markdown](/reporting/markdown-features) in report fields, text notes, and other markdown editors. * `CTRL + B` - Bold * `CTRL + I` - Italic * `CTRL + E` - Inline code * `CTRL + K` - Link * `TAB` / `SHIFT + TAB` - Indent / outdent * `CTRL + [` / `CTRL + ]` - Decrease / increase indent * `ALT + LEFT MOUSE` - Multi-line select * `SHIFT + ALT + UP/DOWN ARROW` - Duplicate line * `ALT + UP/DOWN ARROW` - Move line up/down * `ALT + LEFT/RIGHT ARROW` - Jump to the next markdown element * `ALT + I` - Select line * `CTRL + SHIFT + K` - Delete line * `SHIFT + ALT + A` - Add/remove HTML content * `CTRL + F` - Open search panel * `F3` / `CTRL + G` - Find next (in search panel) * `SHIFT + F3` / `SHIFT + CTRL + G` - Find previous (in search panel) * `ESCAPE` - Close search panel ## Image Editor shortcuts These shortcuts work in the [image editor](/reporting/image-editor). * `V` - Select and move * `R` - Rectangle (outline) * `SHIFT + R` - Rectangle (filled) * `P` - Pixelate * `O` - Ellipse * `L` - Line * `T` - Text * `M` - Numbered marker * `DELETE` / `BACKSPACE` - Delete selected object(s) * `CTRL + MOUSE WHEEL` - Zoom in/out ## Excalidraw shortcuts These shortcuts work in [Excalidraw notes](/reporting/notes#note-types). Press `?` or open **Help** from the Excalidraw menu for the full shortcut reference. **Tools** * `V` / `1` - Selection * `R` / `2` - Rectangle * `D` / `3` - Diamond * `O` / `4` - Ellipse * `A` / `5` - Arrow * `L` / `6` - Line * `P` / `7` - Draw * `T` / `8` - Text * `9` - Image (when image upload is available) * `E` / `0` - Eraser * `F` - Frame * `H` - Hand (pan) * `K` - Laser pointer * `Q` - Lock tool **View** * `CTRL + +` / `CTRL + -` / `CTRL + 0` - Zoom in / out / reset * `SHIFT + 1` / `SHIFT + 2` - Zoom to fit canvas / zoom to fit selection * `SPACE + DRAG` / `WHEEL + DRAG` - Pan canvas * `ALT + Z` - Zen mode * `ALT + S` - Toggle object snapping * `CTRL + '` - Toggle grid * `CTRL + F` - Search * `CTRL + /` / `CTRL + SHIFT + P` - Command palette **Editor** * `CTRL + Z` - Undo * `CTRL + SHIFT + Z` / `CTRL + Y` - Redo * `CTRL + C` / `CTRL + X` / `CTRL + V` - Copy / cut / paste * `CTRL + D` - Duplicate selection * `CTRL + A` - Select all * `SHIFT + CLICK` - Multi-select * `CTRL + CLICK` - Deep select * `CTRL + DRAG` - Deep box select * `DELETE` - Delete selection * `CTRL + G` / `CTRL + SHIFT + G` - Group / ungroup * `CTRL + [` / `CTRL + ]` - Send backward / bring forward * `CTRL + SHIFT + [` / `CTRL + SHIFT + ]` - Send to back / bring to front * `CTRL + K` - Add / edit link ## AI Agent shortcuts These shortcuts work in the [AI Agent](/reporting/ai-agent) chat sidebar. * `CTRL + L` - Start new chat * `ENTER` - Send message * `SHIFT + ENTER` - New line in message input --- --- url: https://docs.sysreptor.com/designer/designer.md --- # Report Designer The report designer allows you to fully customize the appearance and structure of your final PDF reports. There are no restrictions on design, ensuring that you can tailor reports to meet your specific needs. ## Getting Started There are two main approaches to designing a report: 1. Start from an existing design Copy an existing report design (see [Demo Reports](/demo-reports)) and modify it to fit your requirements. 2. Start from scratch We recommend following approach: * Before starting to design, define your report fields and finding fields * Include base styles in CSS (`@import '/assets/global/base.css';`) * Define the basic report structure in the Layout editor * Customize the HTML and CSS to your needs via the code editors * Hint: Use "Preview Data" to test your design ## Report Design Components A report design consists of the following key parts: 1. Field Definitions Field definitions determine what input fields are available in report sections and findings when writing reports (see [Field Types](/designer/field-types)). * These fields appear as form inputs in the web interface for report creation. * Field values can be used within Vue templates as variables for dynamic content rendering. 2. HTML + Vue.js Template The report layout is defined using the [VueJS template language](https://vuejs.org/guide/essentials/template-syntax.html), which is an extension of standard HTML and JavaScript. * HTML structure defines the layout of the report. * Vue.js enables dynamic content generation by using variables, loops, and conditions. 3. CSS Styles CSS is used to style the report for PDF output. ## Vue.js Template Basics Here are some essential Vue.js template features for report design: * Render variables with double curly braces `{{ var }}`: ```html

{{ report.title }}

``` * Conditional rendering with `v-if="var"` attributes: ```html
...
...
``` * Interations with `v-for="var_item in var_list"`-loops: ```html

Finding title: {{ finding.title }}

``` For more details and advanced features see the [VueJS documentation](https://vuejs.org/guide/essentials/template-syntax.html){target="\_blak"} ## Predefined Components Predefined components are ready-to-use HTML+CSS snippets that help streamline the report design process. They provide commonly used report elements (e.g. cover page, page header/footer, table of contents, findings list, appendix, etc.) that can be easily customized to fit specific needs. They serve as a starting point when initially creating report designs. Predefined components can be added via drag-and-drop in the desing editor's "Layout" tab. When adding, the HTML and CSS code predefined components is inserted in the design's HTML and CSS editor. This code can be customized afterwards. --- --- url: https://docs.sysreptor.com/designer/field-types.md --- # Report Field Types This page describes field types available in SysReptor and how to use them in reports and findings. Report and finding definitions define what input fields are available in report sections and findings when writing reports. Fields are available as form input fields when writing reports in the web interface. Field values are also available in Vue templates as variables. ## Common Options All fields have the following common options: * ID: A unique identifier for the field. This ID is used to access the field in the HTML/Vue template. * Data Type: The data type defines the structure of the field and its allowed values. See below for a list of available data types. * Label: The label is shown in the input form when writing a report. It is a friendly name for users to understand what the field is for. * Required: Mark the field as required (must be filled) or optional (can be empty). If a required field is not filled out, a warning message is generated before publishing the report. * Default Value: The default value is the initial value of the field when creating a new project. Some fields support TODOs in the default value to remind the user to fill out parts of the field. ## Markdown Markdown fields are used to write text blocks with markdown formatting. See [Markdown Syntax](/reporting/markdown-features) for more information on markdown formatting. ![Markdown field](/images/fields_markdown.png) ```html title="Usage in Vue templates" ``` ## String String fields are used to write a short, single-line text. Compared to markdown fields, only a single line is allowed and no text formatting is available. Options: * Spellcheck Supported: Enable or disable spellcheck for the field. Spellchecking is only useful for fields containing natural language text (e.g. a sentance, like for `short_description`). It is not useful for fields containing URLs, IDs, codes or other non-natural language text. * Pattern: Regex pattern to validate the input. If the input does not match the pattern, a warning message is generated before publishing the report. ![String field](/images/fields_string.png) ```html title="Usage in Vue templates" Text: {{ report.field_string }} ``` ## CVSS CVSS fields are used to write a CVSS vector. A graphical CVSS vector editor is available in the input form. Options: * CVSS Version: Require a specific CVSS version (CVSS:3.1 or CVSS:4.0) or allow both versions. ![CVSS field](/images/fields_cvss.png) The field content is a CVSS vector string or "n/a" to indicate that no CVSS vector is applicable. The CVSS score is calculated from the vector and shown in the input form and provided in Vue templates. ```html title="Usage in Vue templates" Vector: {{ report.field_cvss.vector }} Score: {{ report.field_cvss.score }} Level: {{ report.field_cvss.level }} Level (numeric): {{ report.field_cvss.level_number }} CVSS Version: {{ report.field_cvss.version }} ``` ## Enum Enum fields are used to select a single value from a list of predefined options. Options: * Choices: A list of options to choose from. Each option has a value and a label. The value is used as the field value and the label is shown in the input form. ![Enum field](/images/fields_enum.png) ```html title="Usage in Vue templates" Value: {{ report.field_enum.value }} Label: {{ report.field_enum.label }} ``` ## Combobox Combobox fields are a combination of an enum field and a string field. The user can select a predefined option or enter a custom value. Options: * Suggestions: A list of predefined texts to choose from. ![Combobox field](/images/fields_combobox.png) ```html title="Usage in Vue templates" Text: {{ report.field_combobox }} ``` ## CWE CWE fields are used to select a CWE (Common Weakness Enumeration). This field is similar to an enum field, but provides more information about CWEs and enhanced search capabilities. ![CWE field](/images/fields_cwe.png) ```html title="Usage in Vue templates" ID: {{ report.field_cwe.id }} Value: {{ report.field_cwe.value }} Name: {{ report.field_cwe.name }} Description: {{ report.field_cwe.description }} ``` ## Date Date fields are used to select a date. A date picker is available in the input form. ![Date field](/images/fields_date.png) Dates are stored in ISO 8601 format (YYYY-MM-DD). In Vue templates, the date can be formatted using the [`formatDate()` function](/designer/formatting-utils#date-formatting). ```html title="Usage in Vue templates" ISO Date: {{ report.field_date }} Formatted Date: {{ formatDate(report.field_date, 'long', 'en-US') }} ``` ## Number Number fields are used to enter a numeric value. ![Number field](/images/fields_number.png) ```html title="Usage in Vue templates" Value: {{ report.field_number }} ``` ## Boolean Boolean fields are used to select a true or false value. This field is represented as a checkbox in the input form. ![Boolean field](/images/fields_boolean.png) This field is useful enable/disable parts of the report rendering or change the behavior of the report template. Booleans values are often combined with `v-if` and `v-else` directives in Vue templates to conditionally render parts of the report. ```html title="Usage in Vue templates" Value: {{ report.field_boolean }} If:
...
...
``` ## User User fields are used to select a user from the list of project members. In the Vue template the whole user object is available with the user's ID, name, email, phone number, etc. ![User field definition](/images/fields_user.png) ![User field form](/images/fields_user2.png) ```html title="Usage in Vue templates" ID: {{ report.field_user.id }} Name: {{ report.field_user.name }} Email: {{ report.field_user.email }} Full Data:
{{ report.field_user }}
``` ## Object Object fields are used to group multiple fields together. This is useful to structure complex data in the report. Options: * Properties: A list of nested fields that are part of the object. Properties can have any data type. ![Object field](/images/fields_object.png) ```html title="Usage in Vue templates" Property value: {{ report.field_object.property1 }} Property value: {{ report.field_object.property2 }} ``` ## List List fields are used to dynamically add multiple values of a specific data type. Options: * Item Type: The data type of the list items. The item type can be any data type, including other lists or objects. ![List field](/images/fields_list.png) ```html title="Usage in Vue templates" List length: {{ report.field_list.length }} List item by index: {{ report.field_list[0] }} Iterate over list items:
{{ item }}
``` ## JSON JSON fields are used to enter structured JSON data. In Vue templates, the value is parsed and available as a JavaScript object or array. Options: * JSON Schema: Optional [JSON Schema](https://json-schema.org/) used to validate field values. Leave empty for no schema validation. If the value is not valid JSON or does not match the schema, a warning message is generated before publishing the report. ![JSON field](/images/fields_json.png) ```html title="Usage in Vue templates" Value: {{ report.field_json }} Nested data: {{ report.field_json.key1 }} {{ report.field_json.key2.length }} {{ report.field_json.key2[0] }} ``` --- --- url: https://docs.sysreptor.com/designer/design-guides.md --- # Design Guides We provide many useful default styles in our `base.css`. You can import them to your report's CSS using: ```css @import "/assets/global/base.css" ``` If you want to customize the styles (like fonts, code blocks, etc.), have a look at the following chapters. You can find the content of `base.css` [here](https://github.com/Syslifters/sysreptor/blob/main/api/src/sysreptor/pentests/rendering/global_assets/base.css). ::: tip Use the following snippets as a guide how to override the base styles. You do not need them, if you imported the base styles and don't need further customization. ::: ## Headings ```css /* Customize heading sizes */ h1 { font-size: 2rem; } h2 { font-size: 1.6rem; } h3 { font-size: 1.4rem; } h4 { font-size: 1.25rem; } h5 { font-size: 1.1rem; } h6 { font-size: 1rem; } ``` ## Code * `code`: code block and inline code * `pre code`: code block * `.code-block`: code block rendered from markdown * `.code-inline`: inline code rendered from markdown ```css pre code { border: 1px solid black; padding: 0.2em; } code { background-color: whitesmoke; } ``` Code block line number information is provided for markdown code blocks, but not shown by default. Use following CSS rules to display line numbers: ```css .code-block-line::before { content: attr(data-line-number); text-align: right; user-select: none; display: inline-block; width: 2em; margin-left: -1em; margin-right: 0.2em; padding-right: 0.3em; background-color: rgba(0, 0, 0, 0.1); } ``` ## Justified texts ```css p { text-align: justify; text-align-last: start; } ``` ## Lists Style list marker separately with `::marker` ```css li::marker { color: red; } ``` ## Footnotes ```css /* Footnote area at the bottom of the page, where the footnote text is placed */ @page { @footnote { ... } } /* Footnote number in text */ ::footnote-call { ... } /* Separator between multiple consecutive footnotes */ .footnote-call-separator { ... } /* Footnote number in footnote area */ ::footnote-marker { ... } /* Styling footnote content e.g. links */ footnote a { color: black; text-decoration: none; } ``` Additional resources: * https://printcss.net/articles/footnotes ## Fonts Fonts can be used in elements with the CSS rule `font-family`. Following example uses two fonts for the document: `Roboto` for regular text (set for the whole `html` document) and the monospace font `Source Code Pro` for `code` blocks. ```css html { font-family: "Noto Sans", sans-serif; font-size: 10pt; } code { font-family: "Noto Sans Mono", monospace; } ``` We provide a range of fonts ready to use. Following fonts are available: * [Noto Sans](https://fonts.google.com/noto/specimen/Noto+Sans) * [Noto Serif](https://fonts.google.com/noto/specimen/Noto+Serif) * [Open Sans](https://fonts.google.com/specimen/Open+Sans) - similar to Arial * [Roboto Flex](https://fonts.google.com/specimen/Roboto+Flex) * [Roboto Serif](https://fonts.google.com/specimen/Roboto+Serif) * [STIX Two Text](https://fonts.google.com/specimen/STIX+Two+Text) - similar to Times New Roman * [Arimo](https://fonts.google.com/specimen/Arimo) - similar to Verdana * [Exo](https://fonts.google.com/specimen/Exo) * \~~[Lato](https://fonts.google.com/specimen/Lato)~~\* * \~~[Roboto](https://fonts.google.com/specimen/Roboto)~~\* * \~~[Tinos](https://fonts.google.com/specimen/Tinos)~~\* Monospace fonts (for code blocks): * [Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) * [Noto Sans Mono](https://fonts.google.com/noto/specimen/Noto+Sans+Mono) * [Source Code Pro](https://fonts.google.com/specimen/Source+Sans+Pro) * [Red Hat Mono](https://fonts.google.com/specimen/Red+Hat+Mono) * \~~[Courier Prime](https://fonts.google.com/specimen/Courier+Prime)~~\* \*Deprecated, replaced by similar-looking fonts ### Custom Fonts Custom fonts can be added with CSS `@font-face` rules. Requests to external systems are blocked. Therefore you have to upload font files as assets and include them with their relative asset URL starting with `/asset/name/`. For google fonts you can generate the font files with this tool: https://google-webfonts-helper.herokuapp.com/fonts/ This generates all CSS rules and provides font files for download. It is possible to upload the `@font-face` CSS rules in a separate file and include it in the main stylesheet with their asset URLs. ```css @font-face { font-family: 'Roboto'; font-weight: 400; src: url('/assets/name/roboto-regular.woff2') } ``` --- --- url: https://docs.sysreptor.com/designer/page-layout.md --- # Page Layout ## Page size Set the page margin such that all regular content fits in the page and there is enough space on the page borders for headers and footers. Page headers and footers should be inside the margin box to not overlap with text content. ```css @page { size: A4 portrait; margin: 35mm 20mm 25mm 20mm; } ``` Additional resources: * https://printcss.net/articles/page-selectors-and-page-breaks ## Headers and Footers Headers and footers are placed inside the page margin box (outside the regular page content). To display headers and footers at a fixed position on every page use `position: running(header)` in combination with `content: element(header)`. See: * https://printcss.net/articles/running-headers-and-footers * https://printcss.net/articles/page-margin-boxes * https://www.w3.org/TR/css-gcpm-3/#running-syntax ```css @page { @top-left { content: element(header-left); } @top-right { content: element(header-right); } } #header { position: absolute; width: 0; } #header #header-left { position: running(header-left); } #header #header-right { position: running(header-right); text-align: right; } ``` ```html ``` ## Named Pages CSS named pages allow to define distinct styles for different pages using `@page` rules. By assigning a name to a page (`@page name {}`) and using `page: name;` within an element's styles, specific formatting like margins, size, orientation or headers/footers can be applied to designated sections. Headers and footers are also rendered on the title page by default. To hide them on specific pages, override `content` containing the `element(header)` on named pages. ```css .page-cover { page: page-cover; } @page page-cover { /* Hide headers */ @top-left { content: ""; } @top-right { content: ""; } /* Hide footers */ @bottom-right-corner { content: ""; } } ``` ```html
named page
unnamed page: default
``` ## Page numbers The page number is a built-in CSS counter that can be used in `content`. ```css /* Add page number at the bottom right corner of pages */ @page { @bottom-right-corner { content: counter(page) " / " counter(pages); } } /* Don't show page number on the title page */ @page page-cover { @bottom-right-corner { content: ""; } } ``` Page numbers can also be placed in footers together with additonal elements (see above). The page counter then has to be used in a pseudo element such as `::before` or `::after`. ## Pagebreaks The easiest way to add a pagebreak is to include a `` component in the HTML template. In CSS page breaks can be controlled with ```css .selector { break-before: always; break-inside: avoid; break-after: always; } ``` ## Front Page Styling The title page often is very different from the rest of the report, because it has no continuous text. Often, it contains the report title, a pretty background image and text blocks placed on specific locations not following any continuous text flow. It is best to place element at specific offsets using `position: absolute` in combination with `top/bottom` and `left/right`. You may also want to disable headers and footers on the title page with [named pages](#named-pages). ```css #page-cover-background { position: absolute; top: 0; left: 0; width: 100%; height: 12cm; overflow: hidden; } #page-cover-background img { width: 100%; } #page-cover-title { position: absolute; top: 6cm; left: 4cm; right: 4cm; } ``` --- --- url: https://docs.sysreptor.com/designer/headings-and-table-of-contents.md --- # Headings and Table of Contents We provide many useful default styles in our `base.css`. You can import them to your report's CSS using: ```css @import "/assets/global/base.css" ``` Headings and Table of Contents can be used out of the box with the imported styles.\ If you want to customize heading numberings or table of content (like margins, etc.), have a look at the following chapters. ## Customization ::: tip Use the following snippets as a guide how to override the base styles. You do not need them, if you imported the base styles and don't need further customization. ::: CSS has counters to automatically number items such as headings, figures, etc. and also generate table of contents and list of figures with these numbers. This allows you to automatically produce a structure similar to ```md 1 Heading 1.1 Subheading 1.2 Subheading 1.2.1 Subsubheading 2 Heading A Appendix A.1 Appendix Subheading ``` Additional resources: * https://printcss.net/articles/counter-and-cross-references * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS\_Counter\_Styles/Using\_CSS\_counters ## Heading Numbers This example contains code for numbering headings with pure CSS. The heading number is placed in the `::before` pseudo-element in the DOM using CSS. CSS counters first have to be defined with `counter-reset: ` (best place this rule in `html`). The counters by default start at `0`, but the start value can also be overwritten. Before the counter value is used, it should be incremented (such that chapter numbers start at 1, not 0) with `counter-increment: `. Now the counter has the correct value, we can embed it with `content: counter()` in `::before` pseudo-elements. Counters are incremented and referenced with CSS rules in selectors. Counters have no global value at a given time, instead their values depend on the DOM-position of the elements that use them. For example: the custom `h1-counter` is incremented at every `

` tag. This means that between the first and the second `

` tag in the DOM structure, the counter has the value `1`, between the second and third `

` it has the value 2 and so on. When the CSS rule `h2::before { counter-increment: h2-counter; content: counter(h1-counter) "." counter(h1-counter); }` accesses the counter value of `h1-counter` the value is different depending on where the targeted `h2` element is placed in the DOM. Note that this `h2::before` rule is defined only once and applies to all `

` tags. ### Basic Heading Numbering Add numbering to heading tags which have the class `numbered`. ```css html { /* Define counters and reset them */ counter-reset: h1-counter h2-counter h3-counter; } /* Heading numbers Usage in HTML:

Heading

=> 1 Heading

Subheading

=> 1.1 Subheading */ h1.numbered::before { padding-right: 5mm; counter-increment: h1-counter; content: counter(h1-counter); } h2.numbered::before{ padding-right: 5mm; counter-increment: h2-counter; content: counter(h1-counter) "." counter(h2-counter); } h3.numbered::before{ padding-right: 5mm; counter-increment: h3-counter; content: counter(h1-counter) "." counter(h2-counter) "." counter(h3-counter); } /* Reset counters of sub-headings below the current level */ h1.numbered { counter-reset: h2-counter h3-counter; } h2.numbered { counter-reset: h3-counter; } ``` ### Appendix Numbering If you want appendix sections that are numbered differently, an additional counter can be used that uses a different number formatting. E.g. with A, A.1, A.2, B, B.1, etc. instead contiuned numbering 4, 4.1, 4.2, 5, 5.1, etc. CSS counters can specify a counter style to use such as `upper-alpha` instead of decimal numbers. ```css html { /* NOTE: only one html {} block with counter-reset rules should exist; if there exist multiple, they overwrite each other */ counter-reset: h1-counter h2-counter h3-counter h1-appendix-counter; } /* Appendix heading numbers Usage in HTML:

Heading

=> A Heading

Subheading

=> A.1 Subheading
*/ .appendix h1.numbered::before { padding-right: 5mm; counter-increment: h1-appendix-counter; content: counter(h1-appendix-counter, upper-alpha); } .appendix h2.numbered::before { padding-right: 5mm; counter-increment: h2-counter; content: counter(h1-appendix-counter, upper-alpha) "." counter(h2-counter); } .appendix h3.numbered::before{ padding-right: 5mm; counter-increment: h3-counter; content: counter(h1-appendix-counter, upper-alpha) "." counter(h2-counter) "." counter(h3-counter); } /* Reset counters of sub-headings below the current level */ .appendix h1.numbered { counter-reset: h2-counter h3-counter; } .appendix h2.numbered { counter-reset: h3-counter; } ``` ## Table of Contents A table of contents can be included in reports via the `` component. This component collects all elements with the class `in-toc`, and provides them as variables. This component uses delayed multi-pass rendering to ensure that all items referenced in the TOC are already rendered and can be referenced. ### Heading Numbers in TOC Heading numbers can be added purely with CSS using counters. However, in order to use the correct counters, the nesting level of the heading needs to be known by CSS rules. These cannot be determined soely in CSS. The `` component determines the nesting level and provides this information. `h1` to `h6` tags are assigned the correct level. All HTML attributes of the target element are collected and passed to ``. This can be used to e.g. determine if an item is in an appendix section or regular chapter. ### Table of Contents Example This example renders a table of contents with * heading number (via CSS counters) * heading title * a leader (line of dots between title and page number) * page number * links entries to the target pages, such that you can click on the TOC entries and jump to the referenced page * supports regular chapters and appendix chapters ```html

Table of Contents

``` ```css #toc li { list-style: none; margin: 0; padding: 0; } #toc .ref::before { padding-right: 0.5em; } #toc .ref::after { content: " " leader(".") " " target-counter(attr(href), page); } #toc .toc-level1 { font-size: 1.5rem; font-weight: bold; margin-top: 0.8rem; } #toc .toc-level2 { font-size: 1.2rem; font-weight: bold; margin-top: 0.5rem; margin-left: 2rem; } #toc .toc-level3 { font-size: 1rem; margin-top: 0.4rem; margin-left: 4rem; } #toc .toc-level4 { font-size: 1rem; margin-top: 0; margin-left: 6rem; } ``` ### Include items in TOC ```html

Table of Contents

Section 1

Subsection 1.1

Subsubsection 1.1.1

Section 2: Not in TOC

Appendix A

Appendix A.1

``` ### Referencing sections in text (outside of TOC) Headings can not only be referenced in the table of contents, but anywhere in the document. References can be added via an `` tag that links to the `id` of an heading element. In HTML (and markdown), a `` helper component is used to generate the `a` tag with corresponding CSS classes for referencing. See [References](/reporting/references) for examples how to reference items. ```css /* Hide section title (show only number) e.g. "1.1" */ .ref-heading .ref-title { display: none;; } #toc .ref-heading .ref-title { display: initial; } /* Reference chapter title */ .chapter-ref-title::before { content: "Chapter " target-text(attr(href)); } ``` --- --- url: https://docs.sysreptor.com/designer/tables.md --- # Tables ## Basic Table Styling ```css table { width: 100%; caption-side: bottom; } /* Table borders */ table, th, td { border: 1px solid black; border-collapse: collapse; } /* Bold table headings */ th { font-weight: bold; } /* Table caption */ table caption { font-weight: bold; text-align: center; } ``` ## Complex Tables See: https://www.w3.org/WAI/tutorials/tables/irregular/ **TLDR**: * Header spanning multiple columns: `` * Header spanning multiple rows: `` ### Vertial Text in Row headers Rotate text with `transform`. ```html
Complex table with vertical text spanning multiple rows

Vertical Text

Horizontal Text
``` ```css .rowheader-vertical { width: 2em; } .rowheader-vertical p { white-space: nowrap; overflow: visible; width: 2em; margin-left: 0.5em; } .rowheader-vertical p span { display: inline-block; transform: translateX(-50%) rotate(270deg) translateY(50%); } ``` ## List of Tables Works similar like table of contents. The component uses multi-pass rendering. In the first render-pass it does nothing, in the second pass it collects all previously rendered `` tags and provides them in the variable `items`. ```html

List of Tables

``` ```css #lot li { list-style: none; margin: 0; padding: 0; } #lot .ref { color: black; text-decoration: none; } #lot .ref-table::before { content: "Table " target-counter(attr(href), table-counter) " - "; } #lot .ref-table::after { content: " " leader(".") " " target-counter(attr(href), page); } ``` --- --- url: https://docs.sysreptor.com/designer/figures.md --- # Figures ## Markdown images When you embed images in markdown with `![title](img.png)` the `` tags are wrapped in `
` tags. This allows to add captions with `
` tags. It is recommended that you also use `
` tags when placing images in your HTML template in text. Except for logos in headers or background images on the title page. ```html
Caption
``` ### Image width ```md ![Image with half the page width](img.png){width="50%"} ![Exactly sized image](img.png){width="10cm" height="7cm"} ``` ## Basic styling ```css /* Image styling */ /* Prevent images from overflowing figure or page width */ img { max-width: 100%; } figure { text-align: center; margin-left: 0; margin-right: 0; } figcaption { font-weight: bold; break-before: avoid; } ``` ## Figure numbering Figures with captions are numbered by default as `Figure : ` and referenced as `Figure `. ## List of Figures ### Template Component Works similar like table of contents. The component uses multi-pass rendering. In the first render-pass it does nothing, in the second pass it collects all previously rendered `
` tags and provides them in the variable `items`. ```html

List of Figures

``` ### Referencing figure numbers ```css #lof li { list-style: none; margin: 0; padding: 0; } #lof .ref-figure::before { content: var(--prefix-figure) target-counter(attr(href), figure-counter) " - "; } #lof .ref-figure > .ref-title { display: inline; } #lof .ref-figure::after { content: " " leader(".") " " target-counter(attr(href), page); } ``` --- --- url: https://docs.sysreptor.com/designer/charts.md --- # Charts Charts can be embedded into reports with a `` component. The `` component uses [ChartJS](https://www.chartjs.org/docs/latest/) for rendering charts. The resulting chart is embedded as an image in the PDF. How the chart looks like is specified by the `:config` argument. This argument accepts a [ChartJS config object](https://www.chartjs.org/docs/latest/configuration/). You can configure different chart types (e.g. pie chart, bar chart, line chart, etc.), chart styling, labels. The `config` also takes the datasets to be rendered in the `data` property. You can use all available ChartJS configuration options (except animations, since they are not possible in PDFs) to customize charts for your needs. Other options: * `width`: Width of the chart in centimeter * `height`: Height of the chart in centimeter ## Example: Bar Chart of vulnerability risks The following chart shows the number of vulnerabilities for each risk level (none, low, medium, high, critical) in a bar chart. Each risk level bar has a different color. ![](/images/chart_finding_distribution.png) ```html
Distribution of identified vulnerabilities
``` ## Example: Doughnut Chart of CVSS score The following chart shows the CVSS score criticality as a doughnut chart with the score inside as number. The higher the score, the more of the chart area is filled. ![](/images/chart_cvss.png) ```html
{{ finding.cvss.score }}
``` ```css .cvss-chart { position: relative; width: 3cm; height: 3cm; } .cvss-chart img { width: 100% !important; height: 100% !important; } .cvss-chart-label { position: absolute; width: 100%; text-align: center; top: 50%; transform: translateY(-50%); line-height: 1; font-size: 25pt; } ``` ## Plugins ChartJS supports plugins to extend the functionality of charts.\ We provide the following plugins: * [chartjs-plugin-datalabels](https://chartjs-plugin-datalabels.netlify.app/guide/getting-started.html#configuration): Show labels on top of bars, lines, etc. Plugins are disabled by default. You can enable them using the `plugins` option in the `config` object of charts. ```html ``` --- --- url: https://docs.sysreptor.com/designer/findings.md --- # Findings ## Findings List Findings are available in Vue templates via the `findings` variable. The `findings` list is an ordered list of all findings. Each finding is represented as a JSON object containing finding fields (see [Field Types](/designer/field-types)). Iterate over the `findings` list via Vue `v-for` loops: ```html

Findings

{{ finding.title }}

...
``` ## Finding Order Findings can be ordered based on specific finding fields. Finding fields used for ordering are defined in the design's finding field definition. The default sort order is to first sort findings by cvss in descending order, followed by title in ascending order. The `findings` variable provided in Vue templates is already ordered. ![Finding Ordering Definition](/images/finding-order-definition.png) If no fields are specified for ordering, findings can be manually sorted using drag-and-drop functionality. The order of findings can be customized in projects by overriding the default sort order via manually sorting findings via drag-and-drop. ![Custom Finding Order](/images/finding-order-manual.png) ## Finding Groups Findings can be grouped based on a specified field, which divides the list into virtual groups. By default, findings are not grouped. It is recommended to group findings using a field of type `combobox` or `enum` (see [Field Types](/designer/field-types)). `combobox` fields allow users to add custom groups when writing reports, while `enum` fields require all groups to be defined upfront in the design. ![Finding Grouping Definition](/images/finding-group-definition.png) The order of these groups is determined by sorting the selected grouping field in either ascending or descending order. Within each group, findings follow the finding ordering rules. The order of both findings and groups can be adjusted at the project level by manually sorting findings and groups via drang-and-drop. ![Custom Finding Group Order](/images/finding-group-manual.png) Designs need to support grouping in the Vue template. The grouped finding list is availalbe via the `finding_groups` variable. ```html

{{ group.label }}

{{ finding.title }}

...
``` --- --- url: https://docs.sysreptor.com/designer/formatting-utils.md --- # Formatting Utilities Multiple utility functions for formatting are available. ## Date Formatting The `formatDate()` function takes three arguments: * the date to be formatted * (optional) format options * if not specified, the date is formatted as `{dateStyle: 'long'}` in the current locale of the report * a string for either: `iso` (format: `yyyy-mm-dd`) or `full`, `long`, `medium`, `short` date style in the current locale of the report * a object for [Intl.DateTimeFormat options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#options) * (optional) locale to override the default locale: see [Intl.DateTimeFormat locales](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#locales) Examples: ```html 2022-09-21: {{ formatDate(report.report_date, 'iso') }} 21.09.22: {{ formatDate(report.report_date, 'short', 'de-DE') }} 21.09.2022: {{ formatDate(report.report_date, 'medium', 'de-DE') }} 21. September 2022: {{ formatDate(report.report_date, 'long', 'de-DE') }} Mittwoch, 21. September 2022: {{ formatDate(report.report_date, 'full', 'de-DE') }} 9/21/22: {{ formatDate(report.report_date, 'short', 'en-US') }} Sep 21, 2022: {{ formatDate(report.report_date, 'medium', 'en-US') }} September 21, 2022: {{ formatDate(report.report_date, 'long', 'en-US') }} Wednesday, September 21, 2022: {{ formatDate(report.report_date, 'full', 'en-US') }} S 21, 22: {{ formatDate('2022-09-21', {year: '2-digit', month: 'narrow', day: '2-digit', numberingSystem: 'latn'}, 'en-US') }} ``` ## Lodash Utilities All lodash utility functions are available in templates as `lodash`. See https://lodash.com/docs/ for a list of available functions. Examples: ```html {{ lodash.capitalize(finding.cvss.level) }} {{ lodash.toUpper(finding.cvss.level) }} ``` ## Text Enumeration Formatting The `` template component allows joining text enumerations with commas and the last item with "and". Some items might be optional and not be rendered always. This component takes care of inserting separators into the text. This example shows the basic usage for a static list of text parts. It renders the number of findings for each severity level. If there are no findings for a severity level, the level is omitted. ```html

In the course of this penetration test vulnerabilities were identified:

``` Following example renders a dynamic list of strings from a template variable joined with commas and "and": ```html ``` By default, `` concatenates text parts with commas and the last one with the english word "and". These separators can be changed via the parameters `comma=", "` and `and=" and "` to format other languages. This example joins text parts in different languages: ```html English (default): ... English (no commas, always "and"): ... German: ... French: ... ``` ## QR Codes The `` component generates QR codes from text or URLs. `` produces an `` element that can be styled via CSS or attributes. Examples: ```html ``` ## Helper Functions and Variables It is possible to define helper functions and variables inside the Vue template language to reuse logic. Defining variables and helper functions works by assigning a value to a variable in an inline JavaScript expression. Helper functions are defined at the start of the template, they can be used by following template elements. ```html
{{ helperFunction = function() { return report.title + ' processed by helper function'; } }} {{ calculateCustomScore = (finding) => finding.exploitability * finding.impact }} {{ helperVariable = 'Helper variable' }} {{ computedProperty = computed(() => report.title + ' processed by computed property') }} {{ tr = function (label, options = undefined) { // Define your translation table here const translations = { 'en': { example: 'Example', fallback: 'Fallback value' }, 'de': { example: 'Beispiel', }, 'fr': { example: 'exemple', }, }; // Use "en" as fallback language. Warnings are still generated when a fallback value is used. const translationFallback = translations['en']; // Get the current report language (configured in project settings) // Remove country postfix from language string e.g. "de-DE", "de-AT" and "de-CH" all use "de" translations const lang = (options?.lang || document.documentElement.getAttribute('lang'))?.split('-')?.[0]; // Check if a translation exists. If not generate a warning message. // The warning is displayed in the PDF preview and the project warning list before generating/publishing the final DF. if (!lang || !translations[lang]) { const msg = `Language "${lang}" not defined in the design's translation table` console.warn(msg, { message: 'Translation not defined', details: msg }); } else if (!(label in translations[lang])) { const msg = `Translation for "${label}" is not defined in translation table for language "${lang}"` console.warn(msg, { message: 'Translation not defined', details: msg }); } return translations[lang]?.[label] ?? translationFallback[label] ?? ''; } }}
Call helper function (without arguments): {{ helperFunction() }}
Call helper function (with arguments): {{ calculateCustomScore(report.findings[0]) }}
Use helper variable: {{ helperVariable }}
Use computed property: {{ computedProperty.value }}
Call translation function: {{ tr('example') }}
``` Note that defining variables and helper functions is not officially supported by the Vue template language, but rather a workaround. For more details see: https://stackoverflow.com/questions/43999618/how-to-define-a-temporary-variable-in-vue-js-template --- --- url: https://docs.sysreptor.com/designer/filenames.md --- # Filename Configure the filename used when downloading the rendered PDF report by setting a custom filename through HTML meta tags in your design template. This allows for dynamic, context-aware filenames based on report data. The filename is set using a `` tag with the name `sysreptor-filename`. Use Vue's `` component to inject this meta tag into the document head, and leverage Vue's template syntax to create dynamic filenames from report data, JavaScript expressions, and formatting utilities. All report fields are accessible via the `report` object. The filename should end with `.pdf`. ```html ``` --- --- url: https://docs.sysreptor.com/designer/debugging.md --- # Debugging ## Template Data Debugging JSON data of reports is available in templates for rendering. The structure of this data depends on your defined report and finding fields, i.e. it may be different for each Design. You can view the current data structure by dumping it in the PDF. ```html

All available data

{{ data }}

Report

{{ report }}

Findings

{{ findings }}
``` ## CSS Debugging There is no way to interactively debug CSS rules. The PDFs are rendered statically and returned as a file. There exists no interactive CSS editor like dev tools console in browsers. However, you can set background colors or borders on elements to see where they are positioned and how big they are, e.g. ```
...
#element-to-debug { background-color: rgba(255, 0, 0, 0.2); } ``` ## JS Debugging Use `console.log()` to print debug messages from custom helper functions and scripts. Only the first argument as string is displayed in the UI. When you need to log nested data structures, use `JSON.stringify()`. ```js console.log(`Debug: ${JSON.stringify(js_var)}`); console.log('', {name: 'JS Debug', details: JSON.stringify(js_var) }); ``` ## Slow PDF Rendering If you experience slow PDF rendering, here are a few tips to speed up rendering: * Identify the slow step: Is the slow step `chromium` (Vue template to HTML) or `weasyprint` (HTML+CSS to PDF)? * If `weasyprint` is slow (most likely): * Weasyprint render times increase with the number of pages and the complexity of the HTML/CSS. Rendering times up to 20s are normal for complex reports. * Table rendering is a common bottleneck, especially with large tables containing multiline cells with `table-layout: auto` (default). Try settings `table-layout: fixed;` in your design's CSS and assign fixed widths to columns. ```css table { table-layout: fixed; } .markdown table { /* Keep auto layout for markdown tables to not cause unexpected rendering, because we can't control the column widths in the design */ table-layout: auto; } ``` ```html ...
Column 1 Column 2
...
Column 1
``` * If that did not help, try to identify the slowest part by commenting out HTML and CSS blocks until rendering is fast again. Try to optimize the slow part, by using different CSS rules or HTML structures. * If `chromium` is slow: * Chromium has rendering times of up to 5s for complex reports. This step is usually faster than `weasyprint`. * If this step is slow, try to identify the slowest part by commenting out Vue template blocks (e.g. custom JS functions) until rendering is fast again. Try to optimize the slow part, by using different Vue template structures. --- --- url: https://docs.sysreptor.com/designer/faqs.md --- # Report Design FAQs These FAQs cover CSS and HTML for PDF report templates: page background, headers, fonts, markdown rendering, code blocks, and layout. Using SysReptor (permissions, designs in projects, licensing) is in the [application FAQs](/faq/application). Install and ops questions are in [self-hosted](/faq/self-hosted) or [cloud](/faq/cloud). Exam students: [exam report FAQs](/faq/exam-reports). ::: details How to set solid color as page background? Set background color for all pages ```css @page { background-color: red; } ``` Set background color only on the first page (cover page) ```css @page:first { background-color: red; } ``` ::: ::: details How to set a header background color? ```css @page { --header-background-color: red; --header-margin-bottom: 5mm; @top-left-corner { content: ""; background-color: var(--header-background-color); margin-bottom: var(--header-margin-bottom); } @top-center { content: ""; background-color: var(--header-background-color); margin-bottom: var(--header-margin-bottom); width: 100%; } @top-right-corner { content: ""; background-color: var(--header-background-color); margin-bottom: var(--header-margin-bottom); } } ``` ::: ::: details Why are my font styles (e.g. italic or bold) not working? We provide some [preinstalled fonts](/designer/design-guides#fonts) that should work out of the box. If you want to use custom font, make sure to [upload and include](/designer/design-guides#custom-fonts) them in your CSS. ::: ::: details Why are my images or markdown not rendered in the report? Your design may reference the variable incorrectly. Make sure to use this syntax: ```html ``` ::: ::: details How to format links like normal text? If you want all links to appear as normal text, use following CSS: ```css a { color: inherit; text-decoration: none; font-style: inherit; } ``` If you want only target specific links, define a CSS class: ```css .link-none { color: inherit; text-decoration: none; font-style: inherit; } ``` Then, add the defined class to your links. HTML: ```html
https://www.example.com ``` Markdown: ```md [example.com](https://www.example.com){.link-none} ``` ::: ::: details How to reference the filename in the report? This is not possible, unfortunately. However, if you want to display your filename in your report, you might define a custom report field (or generate a dynamic filename like `report_{report.customer_name}_{report.title}.pdf`) and copy the filename from the preview to the filename textbox. ::: ::: details How to highlight parts of code blocks with custom style? Highlighting within code-blocks works with the attribute `highlight-manual` and the marker `§§` ([see also](/reporting/markdown-features#code-blocks)): ````md ```http highlight-manual POST /§§important.php§§ HTTP/1.1 ``` ```` To customize the highlight style, add CSS styles for the `` tag, e.g.: ```css mark { background-color: red; } ``` ::: ::: details How to reduce the padding of code blocks? Add following rules to CSS ```css pre code { padding: 0.3em !important; } ``` ::: ::: details How to increase the space between list marker and text in lists? Add following rules to CSS ```css /* Bullet list */ ul > li { list-style: "\2022 "; } /* Numbered list */ ol > li::marker { content: counter(list-item) ". \200b"; } ``` ::: ::: details How to use landscape page orientation? SysReptor uses page orientation `portrait` by default. However, you can change that via CSS. ```css /* Make all pages landscape */ @page { size: A4 landscape; } /* Only target specific pages via CSS named pages */ .section-landscape { page: page-landscape; } @page page-landscape { size: A4 landscape; } ``` ::: ::: details How to add markdown headings to table of contents? SysReptor uses the CSS class `in-toc` to add headings to the table of contents. Optionally in combination with class `numbered` for chapter numbers. ```md ### Markdown Heading in ToC {.in-toc.numbered} ### Markdown Heading not in ToC ``` If you want to automatically add all markdown headings to table of contents, add following function at the top of your design's HTML code. ```vue {{ (function setMarkdownHeadingClasses() { new window.MutationObserver((m) => { document .querySelectorAll('.markdown h1,h2,h3,h4,h5,h6') .forEach(h => h.classList.add('in-toc', 'numbered')); }).observe(document, { childList: true, subtree: true }); })() }} ``` ::: ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/finding-templates/overview.md --- # Templates Templates are blueprints for findings. They contain common description texts for findings and vulnerabilities. Describe your finding texts once in a template and reuse them in multiple pentest reports. When writing a report, you just have to adapt the pentest specific details and add some screenshots. ## Create a template The template library is managed in the `Templates` section of the navigation bar. Every user is able to view and use all templates. Only users with the `is_template_editor` permission can create, edit and delete templates. You can either create a new empty template by clicking "Create", or from a finding an existing report: ![Create template from finding](/images/template_from_finding.gif) ## Template fields The fields available in templates are the same as in findings. The template field definition is created from the finding fields of all global designs and predefined finding fields (e.g. title, cvss, description, recommendation, impact, summary, etc.). This ensures that templates are independent of designs and templates can be used in projects of any design. Each design can define custom fields (additionally to a set of predefined fields). These custom fields are available in templates. Some fields might not be relevant when creating templates because they are only relevant for findings in a specific design or contain project-specific settings. You can hide these fields in the template editor to focus on the relevant fields. ![Template Fields](/images/template_fields.png) Markdown fields allow pasting images from your clipboard: ![Paste image to markdown field](/images/images_in_templates.gif) --- --- url: https://docs.sysreptor.com/finding-templates/multilingual.md --- # Multilingual templates Templates can contain texts for multiple languages. This enabled you to manage all data of a template in one place even when it is translated in multiple languages. ![Multilingual finding templates](/images/templates_multilanguage.gif) Each template has a (required) main language and (optionally) multiple translations. The main language defines all fields that are required in the template (e.g. title, cvss, description, recommendation, references, etc.). Translations can override language-specific fields (e.g. title, description, recommendation, etc.). Fields that are not overridden are inherited from the main language (e.g. cvss, references). This approach allows for maximum flexibility in template translations, since you can translate each field separately for each language. Consider following scenario: You are writing a template in English, German and Dutch, where English is the main language and German and Dutch are translations. In the English template you fill the text fields for title, description and recommendation with vulnerability descriptions (and some TODO markers to insert screenshots and pentest project specific details). Additionally you define the language-independent fields CVSS and references. In the German and Dutch translations you only translate the title, description and recommendation fields need to be translated. The CVSS and references fields are inherited from the English template. Let's consider you have found a great blog post describing the vulnerability in detail and want to use it as a reference in your report. However, the blog post is only available in German, so you cannot use the for the English and Dutch template. It is still possible to use them just for the German translation, by overriding the references field in the German translation. The Dutch translation still inherits the English references, but the German translation contains the additional reference. --- --- url: https://docs.sysreptor.com/users/user-permissions.md --- # User Permissions ## Users without dedicated Permissions Users without dedicated permissions have access to the frontend as regular pentesters. They have only read-write access to pentesting reports they are assigned to.\ They cannot read other pentesting reports. ## Superuser Superusers have the highest privileges available. They have all permissions without explicitly assigning them. They can access all projects, even if they are not members. **Note:** The permissions of superusers are restricted after login. Superusers must elevate their privileges via the "Enable Superuser Permissions" button in the main menu (Pro only). This requires the user to reauthenticate with his password and (if enabled) his second factor. ## User Manager User Managers can create and update other users, assign permissions and reset passwords (except superusers). Users without this permission can only update their own user information (e.g. name, email, phone number), change their own password, but are not allowed to modify their permissions. ## Project Admin Project Admins can access and manage all projects, even if they are not members. Users without this permission can only access projects they are members of. ## Designer Designers can create and edit report designs. Users without this permission can create and edit private designs that cannot be used by other users. They have read access to non-private designs. ## Template Editor Template Editors are allowed to create and edit finding templates. Users without this permission have only read access to templates. ## Guest Guest users permissions can be restricted via global configuration settings by the system operator. When all guest permissions are enabled, guest users are equivalent to regular users. * create projects (default: yes) * import projects (default: no) * edit projects (default: yes) - read-write access to projects they are assigned to * update project settings (default: yes) - update project settings like name, design, members, does not affect project content like findings, sections, notes * delete projects (default: yes) * see all users (default: no) - see all users on the SysReptor instance or only users working in the same projects as guest users * share notes (default: no) - create and manage note sharing links, including approving pending share assets Configure your installation by adding the following settings to your [application settings](/setup/configuration#guest-user-permissions): ```dotenv GUEST_USERS_CAN_CREATE_PROJECTS=True GUEST_USERS_CAN_IMPORT_PROJECTS=False GUEST_USERS_CAN_EDIT_PROJECTS=True GUEST_USERS_CAN_UPDATE_PROJECT_SETTINGS=True GUEST_USERS_CAN_DELETE_PROJECTS=True GUEST_USERS_CAN_SEE_ALL_USERS=False GUEST_USERS_CAN_SHARE_NOTES=False ``` ## System System is a special privilege that allows users to create backups via API. System users cannot be used in projects, templates and designs. This privilege can only be set via the Django interface: 1. Log in with superuser permissions 2. Elevate your privileges using the "Enable Superuser Permissions" button 3. Access https://sysreptor.example.com/admin/users/pentestuser/ 4. Choose the user 5. Tick "Is system user" 6. Save The `system` permission should only be used for backups. --- --- url: https://docs.sysreptor.com/users/oidc-setup.md --- # SSO Setup with OIDC 1. Configure your Identity Provider (IDP) and add the OIDC client details (`OIDC_AUTHLIB_OAUTH_CLIENTS`) in **Settings → Authentication Settings**, or in `app.env`. See [application settings](/setup/configuration#single-sign-on-sso). * [Microsoft Entra ID](/users/oidc-entra-id) * [Google Workplace/Google Identity](/users/oidc-google) * [Keycloak](/users/oidc-keycloak) * [Generic OIDC setup](/users/oidc-generic) * Need documentation for another IDP? Drop us a message at [GitHub Discussions](https://github.com/Syslifters/sysreptor/discussions/categories/ideas)! 2. Set up local users: a. Create user that should use SSO\ b. Go to "Identities"\ c. Add identity ("Add")\ d. Select Provider and enter the SSO identifier provided by your IdP (default: `email`, configurable via `user_identifier_claim`). Matching is case-sensitive and must use the same spelling and casing as the IdP returns. ![Add SSO identity](/images/add_identity.png) The user can now log in via their IdP. --- --- url: https://docs.sysreptor.com/users/oidc-keycloak.md --- # Keycloak OIDC Configuration ## Configuration at your OIDC provider 1. Create new Keycloak client for authentication and generate `client_id` and a `client_secret` 2. Add the callback-url: `https:///login/oidc/keycloak/callback` * Add the hostname where your SysReptor installation can be accessed. ## SysReptor Configuration Create your OIDC configuration for SysReptor... ```json { "keycloak": { "label": "Keycloak", "client_id": "", "client_secret": "", "server_metadata_url": "https://keycloak.example.com/realms/dev/.well-known/openid-configuration", "client_kwargs": { "scope": "openid email", "code_challenge_method": "S256" }, "reauth_supported": false, "user_identifier_claim": "email", "require_email_verified": false } } ``` ...and add it to your [application settings](/setup/configuration#single-sign-on-sso) (`OIDC_AUTHLIB_OAUTH_CLIENTS`). The OIDC client needs to be able to establish a network connection to Keycloak. Make sure to not block outgoing traffic. Other JSON fields, `user_identifier_claim`, and SSO limitations are covered in [Generic OIDC configuration](/users/oidc-generic#sysreptor-configuration) and [Limitations](/users/oidc-generic#limitations). ### Keycloak: `email_verified` Keycloak sets `email_verified` from the per-user “Email Verified” flag. Users created via API, imported, or brokered from another IdP may stay `false` until Keycloak’s email verification (realm “Verify Email”), an admin sets the flag, or the upstream IdP uses **Trust Email** so Keycloak trusts the address. Prefer `"require_email_verified": true` once Keycloak reliably emits `email_verified=true` for your users. --- --- url: https://docs.sysreptor.com/users/oidc-entra-id.md --- # Microsoft Entra ID OIDC Configuration ## Configuration in Microsoft Entra ID 1. Open [Microsoft Entra Admin Center](https://entra.microsoft.com) 2. Select Applications -> App registrations -> New registration 3. In following menu: * Enter a Name for your reference (1) * Select the types of accounts who are allowed to login (2) - this is the first option "Single tenant" in most cases * Enter the redirect url of your application in the following format: https://your.url/login/oidc/entra/callback (3) * Select type "Web" for redirect url (4) ![Register application menu](/images/oidc_1_register.png) 4. In the newly created "App registration", go to the Token configuration submenu and add the following *optional* claim: * TokenType: ID * Claims: auth\_time, login\_hint ![Register application menu](/images/oidc_2_claims.png) 5. Next go to the "Certificates & Secrets" submenu and add a new client secret with 24 months validity (this is the maximum) and any description. 6. Copy the value of the newly created secret and store it for later use. 7. Finally go to the "Overview" submenu and copy the values *Application (client) ID* and *Directory (tenant) ID*. You should now have the following values: * Client ID * Client secret * Entra tenant ID ## SysReptor Configuration Create your OIDC configuration for SysReptor... ```json { "entra": { "label": "Microsoft Entra ID", "client_id": "", "client_secret": "", "server_metadata_url": "https://login.microsoftonline.com//v2.0/.well-known/openid-configuration", "client_kwargs": { "scope": "openid email profile", "code_challenge_method": "S256" }, "reauth_supported": true, "user_identifier_claim": "email", "require_email_verified": true } } ``` ...and add it to your [application settings](/setup/configuration#single-sign-on-sso) (`OIDC_AUTHLIB_OAUTH_CLIENTS`). The OIDC client needs to be able to establish a network connection to Microsoft Entra ID. Make sure to not block outgoing traffic. Other JSON fields, `user_identifier_claim`, and general SSO limitations are covered in [Generic OIDC configuration](/users/oidc-generic#sysreptor-configuration) and [Limitations](/users/oidc-generic#limitations). ### Entra ID: `email_verified` Some Entra ID configurations omit `email_verified` or return `email_verified=false`. See [Verified Emails](/users/oidc-generic#verified-emails) and adjust `require_email_verified` only if you understand the trade-off. --- --- url: https://docs.sysreptor.com/users/oidc-google.md --- # Google OIDC Configuration ## Configuration at Google 1. Open [Google Cloud Console](https://console.cloud.google.com/) * Make sure to select the correct organization: ![Google Cloud Console Organization](/images/google_cloud_console.png){ style="width: 60%" } 2. Use search box and click "Create a Project" ![Click "Create a Project"](/images/google_call_create_project.png){ style="width: 60%" } 3. Enter Name, Organization, Location and "Create" ![Enter project details](/images/google_create_project.png){ style="width: 60%" } 4. Search for and call "OAuth consent screen" 5. Select "Internal" for "User Type" and "Create" ![Select "User Type" "Internal"](/images/google_user_type_internal.png){ style="width: 60%" } 6. Enter "App information" ![Enter App information](/images/google_app_information.png){ style="width: 60%" } 7. Optional: Add App logo * You can use [this](/images/sysreptor_120x120.png){ style="width: 60%" } 8. Enter App domain info ![App domain info](/images/google_app_domain.png){ style="width: 60%" } 9. Enter Developer contact information and click "Save and Continue" ![Add contact information and continue](/images/google_developer_info.png){ style="width: 60%" } 10. Add the scopes `email`, `profile`, `openid` (don't forget to click "Update") ![Add scopes](/images/google_add_scopes.png){ style="width: 60%" } 11. Click "Save and Continue" and verify your data 12. Go to "Credentials", "Create Credentials" and select "OAuth client ID" ![Create credentials](/images/google_create_credentials.png){ style="width: 60%" } 13. Select "Web Application" at "Application type" and enter a name ![Enter client details](/images/google_client_data.png){ style="width: 60%" } 14. You don't need any JavaScript origins 15. Enter the URL to your SysReptor installation with the path `/login/oidc/google/callback` as Authorized redirect URI ![Enter redirect URL](/images/google_authorized_redirect_uri.png){ style="width: 60%" } 16. Click "Create" You should now have the following values: * Client ID * Client secret ## SysReptor Configuration Create your OIDC configuration for SysReptor... ```json { "google": { "label": "Google", "client_id": "", "client_secret": "", "server_metadata_url": "https://accounts.google.com/.well-known/openid-configuration", "client_kwargs": { "scope": "openid email profile", "code_challenge_method": "S256" }, "reauth_supported": false, "user_identifier_claim": "email", "require_email_verified": true } } ``` ...and add it to your [application settings](/setup/configuration#single-sign-on-sso) (`OIDC_AUTHLIB_OAUTH_CLIENTS`). The OIDC client needs to be able to establish a network connection to Google. Make sure to not block outgoing traffic. Other JSON fields, `user_identifier_claim`, and general SSO limitations are covered in [Generic OIDC configuration](/users/oidc-generic#sysreptor-configuration) and [Limitations](/users/oidc-generic#limitations). ## Limitation: Reauthentication SysReptor reauthenticates users before critical actions. It therefore requires users to enter their authentication details (e.g. password and second factor, if configured). Google does not support enforced reauthentication. The reauthentication therefore redirects to Google. If the users are still authenticated at Google, they are redirected back and SysReptor regards the reauthentication as successful. This is a limitation by Google. To enforce reauthentication, users can set a password for their local SysReptor user. This will enforce reauthentication with the local user's credentials. --- --- url: https://docs.sysreptor.com/users/oidc-adfs.md --- # Microsoft ADFS OIDC Configuration ## Configuration in Microsoft ADFS 1. Open the ADFS Management tool. 2. Register an application group: * Go to "Application Groups" (1) * Add a new Application Group (2) * Enter an Application Group Name (3) * Select the Template "Server application accessing a web API" (4) * Click "Next" ![Register application group](/images/oidc-adfs-add-application-group.png) 3. Register a server application: * Copy the client identifier for later (1) * Enter the redirect url of your application in the following format: https://your.url/login/oidc/adfs/callback (2) * Click "Next" ![Register server application](/images/oidc-adfs-add-server-application.png) 4. Configure Application credentials: * Select "Generate a shared secret" * As mentioned, copy and save the secret for later. * Click "Next" ![Register server application](/images/oidc-adfs-configure-application-credentials.png) 5. Configure Web API: * Copy the client identifier from the point 3. in the `Identifier` field. * Click "Next" ![Register server application](/images/oidc-adfs-configure-web-api.png) 6. Configure Access Control Policy: * Here we will allow a specific group only and require MFA for users (1) * Click the `parameter` link in the `Policy` field (2) * Add the AD Group you want to add (3 and 4) * Click "OK" and "Next" ![Register server application](/images/oidc-adfs-configure-access-control-policy.png) 7. Configure Application Permissions: * In the permitted scope check `allatclaims`, `email`, `openid` and `profile`. * Click "Next" ![Register server application](/images/oidc-adfs-configure-application-permissions.png) 8. Configure Claim Rules: * After creating your application group successfully, right click on your application and click on `Properties` * Then Select the "Web API" (1) and click "Edit" (2) * In the new window, select the "Issuance Transform Rules" tab (3) and click "Add Rule" (4) * Select the rule template "Send LDAP Attributes as Claims" * Finally, add a rule named "email" which maps the "E-Mail-Addresses" LDAP Attribute to the claim type "email". ![Register server application](/images/oidc-adfs-claims-application-group-list.png) ![Register server application](/images/oidc-adfs-claims-add-transform-rule.png) ![Register server application](/images/oidc-adfs-claims-configure-transform-rule.png) You should now have the following values: * Client ID * Client secret ## SysReptor Configuration Create your OIDC configuration for SysReptor... ```json { "adfs": { "label": "ADFS", "client_id": "", "client_secret": "", "server_metadata_url": "https://adfs.your.domain/adfs/.well-known/openid-configuration", "client_kwargs": { "scope": "openid profile email", "code_challenge_method": "S256" }, "reauth_supported": false, "user_identifier_claim": "email", "require_email_verified": false } } ``` ...and add it to your [application settings](/setup/configuration#single-sign-on-sso) (`OIDC_AUTHLIB_OAUTH_CLIENTS`). The OIDC client needs to be able to establish a network connection to Microsoft ADFS. Make sure to not block outgoing traffic. Other JSON fields, `user_identifier_claim`, and general SSO limitations are covered in [Generic OIDC configuration](/users/oidc-generic#sysreptor-configuration) and [Limitations](/users/oidc-generic#limitations). --- --- url: https://docs.sysreptor.com/users/oidc-generic.md --- # Generic OIDC Configuration ## Configuration at your OIDC provider 1. Create a `client_id` and a `client_secret` in your OIDC provider 2. Add the callback-url: `https:///login/oidc//callback` * Add the hostname where your SysReptor installation can be accessed. * Choose a custom **SSO provider id** (top-level key in `OIDC_AUTHLIB_OAUTH_CLIENTS`, e. g. `keycloak`). ## SysReptor Configuration `OIDC_AUTHLIB_OAUTH_CLIENTS` is one JSON object. Each **top-level key** is an **SSO provider id**: it identifies this IdP in SysReptor (login URL, user SSO identity **Provider** field, `DEFAULT_AUTH_PROVIDER`, etc.). Choose a stable id (for example `keycloak`, `google`, `entra`). ```json { "": { "label": "", "client_id": "", "client_secret": "", "server_metadata_url": "", "client_kwargs": { "scope": "openid email", "code_challenge_method": "S256" }, "reauth_supported": false, "user_identifier_claim": "email", "require_email_verified": true } } ``` ...and add it to your [application settings](/setup/configuration#single-sign-on-sso) (`OIDC_AUTHLIB_OAUTH_CLIENTS`). ### OIDC Config JSON {#oidc-authlib-json} The **SSO provider id** (each JSON object key) names one OIDC connection. Its value is one inner configuration object. SysReptor registers that object with [Authlib](https://docs.authlib.org/en/stable/oauth2/client/web/index.html): * `label`: Display name of the OIDC provider. Shown on the login screen. * `client_id`: OAuth 2.0 client identifier from the IdP. * `client_secret`: OAuth 2.0 client secret from the IdP. * `server_metadata_url`: Discovery document URL (OpenID Provider Metadata, usually `https://example.com/.../.well-known/openid-configuration`). * `client_kwargs`: Arguments passed to the OAuth client (for example `scope` and `code_challenge_method` for PKCE on the authorization request). SysReptor-specific: * `user_identifier_claim`: Which UserInfo field is the user's SSO identifier (default `email`). See [User identifier claim](#user-identifier-claim). * `require_email_verified`: When `user_identifier_claim` is `email`, require `email_verified` to be true in UserInfo. See [Verified Emails](#verified-emails). * `reauth_supported`: If `true`, SysReptor may use `prompt=login` and `max_age=0` for sensitive reauthentication when the IdP supports it. See [Reauthentication](#reauthentication). ### User identifier claim {#user-identifier-claim} After OIDC login, SysReptor looks up one claim in the IdP’s UserInfo response. The setting `user_identifier_claim` is the **claim name** (for example `email` or `sub`). If you omit it, SysReptor uses `email`. That claim’s **value** is the string SysReptor compares to each user’s saved SSO identity for this same provider (User management → Identities). It must match **exactly**, including upper- and lowercase. The IdP must return the claim (scopes and IdP configuration); otherwise login cannot find a user. If the claim name is `email`, the separate `require_email_verified` option applies (see [Verified Emails](#verified-emails)). !!! warning "Account takeover risk" ``` If the IdP lets users change the chosen UserInfo field without verification (e.g. `preferred_username` for some IdPs), an attacker can set that value to another user’s stored SSO identifier and SysReptor will log them in as that account—including privileged users. Prefer claims the IdP assigns and does not let end users repoint freely; avoid profile-style fields users can edit to arbitrary values. ``` ### Verified Emails If `"require_email_verified": true`, SysReptor requires the OIDC `email_verified` claim to be present and `true` for login. Some OIDC providers do not include this claim at all, or it may be `false` even if the user has an email address. Setting `"require_email_verified": false` means SysReptor will not require proof of email ownership via the OIDC `email_verified` claim. This is fine for many IdPs because they only release verified email addresses. However, if your IdP can emit an unverified or user-controlled `email` (or `preferred_username`) claim, a user could set it to another person's email address and be logged in to SysReptor as that user (including any admin/superuser privileges). ### Reauthentication SysReptor reauthenticates users before critical actions. It therefore requires users to enter their authentication details (e.g. password and second factor, if configured). Your OIDC provider might not support enforced reauthentication. You can try `"reauth_supported": true`. If the "Enable Superuser Permissions" flow does not work, set it to `false`. When `"reauth_supported": true`, SysReptor attempts to trigger reauthentication by setting the OIDC parameters `prompt=login` and `max_age=0` on the authorization request. This forces a fresh login at the OIDC provider. SysReptor verifies that `auth_time` in the response indicates a recent authentication. To enforce reauthentication, users can set a password for their local SysReptor user. This will enforce reauthentication with the local user's credentials. --- --- url: https://docs.sysreptor.com/users/forgot-password.md --- # Forgot Password? ## Reset Password via Forgot Password Email If you've forgotten your password, you can reset it via email by following these steps: 1. Visit the SysReptor login page at `https://sysreptor.example.com/login/` 2. Click on the "Forgot Password?" link below the login form 3. Enter your email address of your SysReptor account 4. We will send you an email with a link to reset your password 5. Click on the reset password link in the email 6. On the password reset page, enter your new password and confirm it 7. You can now log in with your new password ::: info [Email sending](/setup/configuration#emails), [`FORGOT_PASSWORD_ENABLED`](/setup/configuration#local-user-authentication) and [`ALLOWED_HOSTS`](/setup/configuration#allowed-hosts) need to be configured. Your user also must have an email address. ::: ## Reset Password via User Admin Interface Administrators with superuser or user manager permissions can reset passwords for any user through the admin interface at `https://sysreptor.example.com/users//reset-password/`: 1. Log in to SysReptor with an account that has [superuser](/users/user-permissions#superuser) or [user manager permission](/users/user-permissions#user-manager) 2. Navigate to the Users section by clicking on "Users" in the main navigation menu 3. Find and select the user whose password needs to be reset in the user list 4. Click on the "Reset Password" button for that user 5. Set a new password for the user. You can also check "Must change password" to force the user to change their password upon their next login 6. The user can now log in with the new password ## Reset Password via CLI As a last resort, you can reset your password via the command line.\ Go to `sysreptor/deploy` and run: ```shell docker compose exec app python3 manage.py changepassword "" ``` --- --- url: https://docs.sysreptor.com/users/notifications.md --- # Notifications SysReptor provides a notification system to keep you informed about important events related to your projects and findings. In-app notifications are displayed in the menu bar of the web interface. ![](/images/notifications.png) The menu bar shows only unread notifications. A full list (including already read) notifications is available in your user profile. Click the bell icon to temporarily hide notifications for uninterrupted work. ## Notification Triggers Notifications are created for following events: * Added as a member to a project * Assigned a finding, section, or note * Commented on a finding/section assigned to you * Mentioned in a comment via `@username` * New replies in comment threads you are part of (created by you or mentioned) * Project finished where you are a member * Project deleted where you are a member * Project archived where you are a member * No backup created for more than 30 days * Remote notification e.g. SysReptor update available * Custom notifications created by superusers ## Custom Notifications Superusers can create custom notifications through the Django admin interface at `/admin/notifications/customnotificationspec/` to inform users about announcements, maintenance windows, design changes, or other information. **Fields:** * **Title** (required): Notification title displayed to users * **Text** (required): Main notification message body * **Link URL** (optional): URL for more information or action * **Active Until** (optional): Date when notification automatically expires * **Visible For Days** (optional): Number of days notification remains visible per user. New users receive the notification with visibility starting from their creation date. * **User Conditions** (optional): JSON filter for targeting specific users, e.g. `{"is_superuser": true}` or `{"is_designer": false}`. Leave empty to target all users. When both `active_until` and `visible_for_days` are set, the notification expires at whichever date comes first. --- --- url: https://docs.sysreptor.com/python-library.md --- # reptor reptor allows you to integrate your Python applications with SysReptor. * Manage projects * Read, update, create findings * Download PDF reports * Read, update, create notes * Export notes as PDF * and more... **GitHub:** \ **PyPi:** ## Prerequisites * Python 3.9-3.12 * pip3 ## Installation ### From pypi ```shell pip3 install reptor ``` ### From source ```shell git clone https://github.com/Syslifters/reptor.git cd reptor pip3 install . ``` --- --- url: https://docs.sysreptor.com/python-library/tutorial/part-1/projects.md --- # Interacting with SysReptor projects ```python title="Initialize reptor" import os from reptor import Reptor reptor = Reptor( server=os.environ.get("REPTOR_SERVER"), token=os.environ.get("REPTOR_TOKEN"), ) ``` Use the [Projects API](/python-library/api/projects) to interact with your SysReptor projects and findings. ```python title="Search projects" reptor.api.projects.search() # Get all projects reptor.api.projects.search(search_term="Web") # Search for "Web" reptor.api.projects.search(finished=False) # Include active projects only # Out: [ProjectOverview(name="Calzone Report Demo", id="41c09e60-44f1-453b-98f3-3f1875fe90fe")] ``` The search endpoint returns a list of [ProjectOverview](/python-library/dataclasses/project#reptor.models.Project.ProjectOverview) objects, which don't hold findings or section information (such as report fields). ```python title="Get data from ProjectOverview" project_overview = reptor.api.projects.search()[0] project_overview.id # Out: 41c09e60-44f1-453b-98f3-3f1875fe90fe project_overview.name # Out: Calzone Report Demo project_overview.tags # Out: ['web', 'important'] project_overview.members # Out: [User(username="reptor-user-test", name="John Doe", email="", id="ed4196c7-f60a-48bf-8119-dc1642946231")] project_overview.findings # Out: https://example.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe/findings project_overview.sections # Out: https://example.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe/sections ``` You can convert data data classes to Python dictionaries (or check the data class definitions, like [ProjectOverview](/python-library/dataclasses/project#reptor.models.Project.ProjectOverview)). ```python title="Convert ProjectOverview to dict" my_project.to_dict() # Out: # {'id': '41c09e60-44f1-453b-98f3-3f1875fe90fe', # 'copy_of': None, # 'created': '2023-09-21T00:00:01Z', # 'details': 'https://example.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe', # 'findings': 'https://example.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe/findings', # 'images': 'https://example.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe/images', # 'imported_members': [], # 'language': 'en-US', # ``` If you want to interact with a specific project, specify the project id when initializing `reptor`.\ (Instead of re-initializing reptor with the project ID, you can also call `reptor.api.projects.init_project("41c09e60-44f1-453b-98f3-3f1875fe90fe")`.) ```python title="Access information from specific project" reptor = Reptor( server=os.environ.get("REPTOR_SERVER"), token=os.environ.get("REPTOR_TOKEN"), project_id="41c09e60-44f1-453b-98f3-3f1875fe90fe", ) my_project = reptor.api.projects.fetch_project() my_project.id # Out: 41c09e60-44f1-453b-98f3-3f1875fe90fe my_project.name # Out: Calzone Report Demo my_project.findings # Out: # [Finding(title="Reflected XSS", id="3014d72f-6edd-48a8-907b-a15a363f4fce"), # Finding(title="XML External Entity Injection (XXE)", id="b8917e5b-e087-44fb-8461-e9de511d2117"), # Finding(title="Stored Cross-Site Scripting (XSS)", id="5fb537e6-385b-4c15-9f18-4c319c6e625e"), # Finding(title="Cross-Site Request Forgery (CSRF)", id="9a5f580f-bfa5-4ab1-b9e4-daee0bf5fff2"), # my_project.sections # Out: # [Section(id="executive_summary"), # Section(id="scope"), # Section(id="customer"), # Section(id="other"), # Section(id="appendix")] my_project.sections[1].data.duration # Out: SectionDataField(name="duration", type="string", value="5 person days") ``` You can, again, convert the data objects ([Project](/python-library/dataclasses/project#reptor.models.Project.Project) and [Section](/python-library/dataclasses/section#reptor.models.Section.Section)) to Python dictionaries. ```python title="Convert Project and Section to dict" my_project.to_dict() # Out: # {'id': '41c09e60-44f1-453b-98f3-3f1875fe90fe', # 'created': '2023-09-21T00:00:01Z', # 'details': 'https://reptortest.sysre.pt/api/v1/pentestprojects/41c09e60-44f1-453b-98f3-3f1875fe90fe', # 'findings': [{'assignee': None, # 'created': '2025-07-09T08:02:10.017137Z', # 'data': {'affected_components': ['https://example.com/alert(1)', # 'https://example.com/q=alert(1)'], # my_project.sections[1].to_dict() # Out: # {'assignee': None, # 'created': '2022-10-19T16:59:04.488000Z', # 'data': {'duration': '5 person days', # 'end_date': '2022-04-22', # 'provided_users': 'Duis autem vel eum iriure dolor in hendrerit in ' # ``` Pentesters write their reports in markdown. If you need the data as HTML, you can use the `html` parameter.\ (Note that the method still returns JSON data. Markdown content is, however, converted to HTML.) ```python title="Download fields as HTML instead of Markdown" my_project = reptor.api.projects.fetch_project(html=True) my_project.findings[0].data.description.value # Out: '

This was originally written in markdown.

\n
    \n
  • Now
  • it seems
  • to be
  • HTML
  • \n
\n' ``` --- --- url: https://docs.sysreptor.com/python-library/tutorial/part-2/findings.md --- # Interacting with SysReptor findings Now let us look at how to add data to projects. Let's create a finding. ```python title="Create finding" finding = { "status": "in-progress", "data": { "title": "Test Finding", "description": "This is a test finding.", "affected_components": ["example.com", "example-1.com"], }, } my_finding = reptor.api.projects.create_finding(finding) my_finding # Out: FindingRaw(title="Test Finding", id="33ddc5f3-7396-4076-8c17-3eee16465840") ``` The input finding dictionary consists of metadata (like `status`, `assignee`, etc.) and the actual finding data (your finding fields). Add the data you want to add to your finding fields into the `data` dictionary. The keys map to the finding IDs from your project designs. Now let's update the finding that we just created. The [FindingRaw](/python-library/dataclasses/finding#reptor.models.Finding.FindingRaw) object has an ID that we can use for referencing the finding that we want to update.\ We'll just fill out the `summary` field and change the `status` to `finished`. ```python title="Update the finding we just created" my_finding = reptor.api.projects.update_finding( my_finding.id, { "status": "finished", "data": { "summary": "My summary", } } ) ``` The `update_finding` method returns the updated [FindingRaw](/python-library/dataclasses/finding#reptor.models.Finding.FindingRaw) objects. We can use the [FindingRaw](/python-library/dataclasses/finding#reptor.models.Finding.FindingRaw) object to duplicate our finding... ```python title="Duplicate finding" duplicated_finding = reptor.api.projects.create_finding( my_finding.to_dict() ) ``` ...or to delete it. ```python title="Delete finding" reptor.api.projects.delete_finding(duplicated_finding.id) ``` We can also create new findings from finding templates. For this, we introduce the [Finding Templates API](/python-library/api/templates).\ Searching for finding templates works the same way as searching for projects. ```python title="Search finding templates" reptor.api.templates.search() # Get all finding templates reptor.api.templates.search(search_term="XSS") # Search for "XSS" # Out: # [FindingTemplate(title="Stored Cross-Site Scripting (XSS)", id="2bfc61fe-7003-4c95-8e2d-322cc3206a7a"), # FindingTemplate(title="Insecure HTTP cookies", id="3d7491be-cf81-4d1c-82cd-d71451786f9f"), # FindingTemplate(title="Incorrectly configured HTTP security headers", id="e63df410-42f2-49ad-837c-0d6d343a040c")] ``` The search returns a list of [FindingTemplate](/python-library/dataclasses/finding-template#reptor.models.FindingTemplate.FindingTemplate) objects. We now use the finding template ID to create a new finding from the template. ```python title="Create finding from templates" reptor.api.projects.create_finding_from_template( template_id="2bfc61fe-7003-4c95-8e2d-322cc3206a7a" ) # Out: FindingRaw(title="Stored Cross-Site Scripting (XSS)", id="79d2abd6-74f6-417a-878f-2d46fc78eef0") ``` We might also want to update report fields in our report sections. ![Sections and report fields](/images/sections.png) We get access to available [Sections](/python-library/dataclasses/section#reptor.models.Section.Section) and report fields through the project. ```python title="Get available sections and report fields" my_project.sections # Out: #[Section(id="executive_summary"), # Section(id="scope"), # Section(id="customer"), # Section(id="other"), # Section(id="appendix")] my_project.sections[1].fields # Out: #['scope', 'start_date', 'end_date', 'duration', 'provided_users'] ``` Use this data to update fields in the section `scope`. ```python title="Update report fields" reptor.api.projects.update_section( "scope", { "start_date": "2025-08-01", "end_date": "2025-08-31", "duration": "5 person days" }, ) # Out: SectionRaw(id="scope") ``` As we now filled in all relevant data, we now want to download our rendered PDF report. ```python title="Render report and save as file" with open("my_report.pdf", "wb") as f: f.write(reptor.api.projects.render()) ``` Finally, we can finish, or delete our projects. ```python title="Finish or delete projects" reptor.api.projects.finish_project() # Out: True # Indicates that the project is now finished/read only reptor.api.projects.delete_project() ``` We can also duplicate projects. ```python title="Duplicate project" reptor.api.projects.duplicate_project() # Out: Project(name="Copy of Margherita Report Demo", id="2fe0ab2b-8482-49fa-a3b5-1d0d7bb49c01") ``` The `duplicate_project` method returns the newly created [Project](/python-library/dataclasses/project#reptor.models.Project.Project). If you now want to interact with that project, you need to re-initialize your `reptor` object. ```python title="Switch project after duplicate" duplicate = reptor.api.projects.duplicate_project() reptor.api.projects.init_project(duplicate.id) ``` If you want to duplicate a project to interact with it and want to clean it up right away, you can also use the contect manager `duplicate_and_cleanup`.\ The following code snippet duplicates the project, changes the design and renders the PDF. When leaving the context menu, the duplicated project is cleaned up. ```python title="Duplicate project and render with alternative design" design_id = "9eb56f02-c71b-4c1a-8392-06ab4d633336" with reptor.api.projects.duplicate_and_cleanup(): reptor.api.projects.update_project_design(design_id, force=True) with open("my_report.pdf", "wb") as f: f.write(reptor.api.projects.render()) ``` The `force` parameter in `update_project_design` forces the design change, even if there are incompatible field definitions (e.g., a `string` finding field in the original design, which is a `number` in the new design would lead to data loss). This makes duplicating the project useful, because incompatibilities won't affect the original project. --- --- url: https://docs.sysreptor.com/python-library/tutorial/part-3/notes.md --- # Interacting with SysReptor notes The `reptor` library also allows you to interact with your notes structures. Use the [Notes API](/python-library/api/notes) to get the your project's note structures. ```python title="Get project notes" notes = reptor.api.notes.get_notes() # Out: # [Note(title="Scoping", id="c90dbe1b-3ea7-4054-925d-c4c55b8d7404", parent="None"), # Note(title="Findings", id="38779b8f-a910-4191-8e0d-066f6b79cd95", parent="None") # Note(title="Web Security Checklist", id="c052da53-0b2e-401e-973d-3c1c92255b77", parent="None"), # Note(title="Session management", id="3e0cb97f-23a9-470d-a885-68cd9dbb5ada", parent="c052da53-0b2e-401e-973d-3c1c92255b77"), # notes[0].title # Out: 'Scoping' notes[0].text # Out: 'Those are our scoping notes.' notes[0].icon_emoji # Out: '🧐' ``` This method returns a list of [Notes](/python-library/dataclasses/note#reptor.models.Note.Note). We can also create notes. Let's add a new item to our "Web Security Checklist". ```python title="Add a new note" reptor.api.notes.create_note( title="Authorizations", parent_id="c052da53-0b2e-401e-973d-3c1c92255b77", checked=False, text="Check for authorization issues." ) # Out: Note(title="Authorizations", id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf", parent="c052da53-0b2e-401e-973d-3c1c92255b77") ``` ![A new note was added to the project notes](/images/created_note.png) Use the `write_note` method to append text to your note, or to update properties like the `title`, `checked` or `icon_emoji`. ```python title="Update the note" reptor.api.notes.write_note( id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf", title="Authorizations (Done)", text="Done by John Doe.", checked=True, ) ``` We can also use the library to upload files or images. ```python title="Upload files and images" reptor.api.notes.upload_file( note_id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf", file=open("evidence.tar.gz", "rb"), filename="evidence.tar.gz", caption="Evidence for authorization testing.", ) reptor.api.notes.upload_file( note_id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf", file=open("reptor.png", "rb"), filename="reptor.png", caption="Self Portrait.", ) ``` ![The note was updated with additional text and files](/images/updated_note.png) Let's download the note as PDF and save it to a file. ```python title="Download note as PDF and save to file" with open("note.pdf", "wb") as f: f.write( reptor.api.notes.render(id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf") ) ``` We can also duplicate or delete our notes. ```python title="Duplicate and delete note" reptor.api.notes.duplicate(id="dda820d2-57d7-4ff8-b4ac-99d102a5c8bf") # Out: Note(title="Authorizations (Done)", id="a1a1fd38-0c8e-4b42-b491-74cb61ed2d7f", parent="c052da53-0b2e-401e-973d-3c1c92255b77") reptor.api.notes.delete_note(id="a1a1fd38-0c8e-4b42-b491-74cb61ed2d7f") ``` --- --- url: https://docs.sysreptor.com/python-library/api/projects.md --- # Projects API ::: reptor.api.ProjectsAPI.ProjectsAPI options: show\_bases: false show\_source: true members\_order: source separate\_signature: true --- --- url: https://docs.sysreptor.com/python-library/api/notes.md --- # Notes API ::: reptor.api.NotesAPI.NotesAPI options: show\_bases: false show\_source: true members\_order: source separate\_signature: true --- --- url: https://docs.sysreptor.com/python-library/api/templates.md --- # Finding Templates API ::: reptor.api.TemplatesAPI.TemplatesAPI options: show\_bases: false show\_source: true members\_order: source separate\_signature: true --- --- url: https://docs.sysreptor.com/python-library/api/project-designs.md --- # Project Design API ::: reptor.api.ProjectDesignsAPI.ProjectDesignsAPI options: show\_bases: false show\_source: true members\_order: source separate\_signature: true --- --- url: https://docs.sysreptor.com/python-library/dataclasses/project.md --- # Project Data Classes ::: reptor.models.Project.Project options: show\_source: false ::: reptor.models.Project.ProjectOverview options: show\_source: false --- --- url: https://docs.sysreptor.com/python-library/dataclasses/finding.md --- # Finding Data Classes ::: reptor.models.Finding.FindingRaw options: show\_source: false ::: reptor.models.Finding.FindingDataRaw options: show\_source: false ::: reptor.models.Finding.Finding options: show\_source: false ::: reptor.models.Finding.FindingData options: show\_source: false ::: reptor.models.Finding.FindingDataField options: show\_source: false ::: reptor.models.Base.ProjectFieldTypes options: show\_source: true --- --- url: https://docs.sysreptor.com/python-library/dataclasses/section.md --- # Section Data Classes ::: reptor.models.Section.SectionRaw options: show\_source: false ::: reptor.models.Section.SectionDataRaw options: show\_source: false ::: reptor.models.Section.Section options: show\_source: false ::: reptor.models.Section.SectionData options: show\_source: false ::: reptor.models.Section.SectionDataField options: show\_source: false --- --- url: https://docs.sysreptor.com/python-library/dataclasses/note.md --- # Note Data Classes ::: reptor.models.Note.Note options: show\_source: false --- --- url: https://docs.sysreptor.com/python-library/dataclasses/finding-template.md --- # Finding Template Data Classes ::: reptor.models.FindingTemplate.FindingTemplate options: show\_source: false ::: reptor.models.FindingTemplate.FindingTemplateTranslation options: show\_source: false ::: reptor.models.Base.FindingTemplateSources options: show\_source: true --- --- url: https://docs.sysreptor.com/python-library/dataclasses/project-design.md --- # Project Design Data Classes ::: reptor.models.ProjectDesign.ProjectDesign options: show\_source: false ::: reptor.models.ProjectDesign.ProjectDesignOverview options: show\_source: false ::: reptor.models.ProjectDesign.ProjectDesignField options: show\_source: false --- --- url: https://docs.sysreptor.com/python-library/dataclasses/user.md --- # User Data Classes ::: reptor.models.User.User options: show\_source: false --- --- url: https://docs.sysreptor.com/cli/getting-started.md --- # reptor `reptor` allows you to automate pentest reporting with SysReptor. You can use `reptor` as a command line (CLI) tool: ```shell reptor exportfindings --format json ``` Or use it as a Python library: ```python from reptor import Reptor reptor = Reptor( server=os.environ.get("REPTOR_SERVER"), token=os.environ.get("REPTOR_TOKEN"), project_id="41c09e60-44f1-453b-98f3-3f1875fe90fe", ) reptor.api.projects.get_project() ``` You can use it to: * Create findings and notes from tool outputs * Upload evidences (also bulk upload) * Import data from other reporting tools * Manage projects * Read, update, create findings * Download PDF reports * Read, update, create notes * Export notes as PDF * and more... **GitHub:** \ **Python Library Docs:** \ **CLI Docs:** \ **PyPi:** ## Prerequisites * Python 3.10-3.14 * pip3 ## Installation ### From pypi ```shell pip3 install reptor ``` #### Optional dependencies * translate (requires deepl) * ghostwriter (requires gql) * dev (requires pytest) Install by `pip3 install reptor[translate]`.\ Install all optional dependencies using `pip3 install reptor[all]` ### From source ```shell git clone https://github.com/Syslifters/reptor.git cd reptor pip3 install . ``` Install [optional dependencies](#optional-dependencies) by `pip3 install .[all]`. ### From BlackArch ```shell pacman -S reptor ``` [![BlackArch package](https://repology.org/badge/version-for-repo/blackarch/reptor.svg)](https://repology.org/project/reptor/versions) ### Usage ```txt usage: reptor [-h] [-s SERVER] [-t TOKEN] [-k] [-p PROJECT_ID] [--timeout SECONDS] [--personal-note] [-v] [--debug] [-n NOTETITLE] [--no-timestamp] [--file FILE] Examples: reptor conf echo "Upload this!" | reptor note reptor file data/* cat sslyze.json | reptor sslyze --json --push-findings reptor nmap --xml --upload -i nmap.xml options: -h, --help show this help message and exit -v, --verbose increase output verbosity (> INFO) --debug sets logging to DEBUG -n NOTETITLE, --notetitle NOTETITLE --no-timestamp do not prepend timestamp to note --file FILE Local file to read subcommands: Core: conf Shows config and sets config mcp Starts the Model Context Protocol (MCP) server plugins Allows plugin management & development Projects & Templates: ai Process report sections using OpenAI with dynamic skill selection createproject Create a new pentest project deletefindings Deletes findings by title deleteprojects Deletes projects by title exportfindings Export your project findings as a summary or checklist file Uploads a file finding Uploads findings from JSON or TOML findingfromtemplate Creates findings from remote finding templates note Uploads and lists notes project Work with projects pushproject Push data to project from JSON or TOML template Queries Finding Templates from SysReptor translate Translate Projects to other languages via Deepl Tools: burp Burp vulnerability importer nessus Nessus vulnerability importer nmap format nmap output openvas OpenVAS vulnerability importer qualys Qualys vulnerability importer sslyze format sslyze JSON output zap Parses ZAP reports (JSON, XML) Importers: defectdojo Imports DefectDojo finding templates ghostwriter Imports GhostWriter finding templates importers Show importers to use to import finding templates Utils: packarchive Pack directories into a .tar.gz file unpackarchive Unpack .tar.gz exported archives configuration: -s SERVER, --server SERVER -t TOKEN, --token TOKEN SysReptor API token -k, --insecure do not verify server certificate -p PROJECT_ID, --project-id PROJECT_ID SysReptor project ID --timeout SECONDS HTTP request timeout in seconds (default: 30) --personal-note add notes to personal notes ``` --- --- url: https://docs.sysreptor.com/cli/configuration.md --- # Configuration ```shell reptor conf Server [https://demo.sysre.pt]: API Token [Create at https://demo.sysre.pt/users/self/apitokens/]: Project ID: 3fae023a-2632-4c88-a0ea-97ab5eb64c94 Store to config to C:\Users\user\.sysreptor\config.yaml? [y/n]: ``` Get your API token from https://{your-installation-url}/users/self/apitokens/.\ Find your project ID in the URL of your project (optional). ![Find the project ID in the URL](/cli/assets/project_id.png) You can also add your configuration as environment variables. Environment variables override the config file. ```shell export REPTOR_SERVER="https://demo.sysre.pt" export REPTOR_TOKEN="sysreptor_ZDM5NmQ5" export REPTOR_PROJECT_ID="3fae023a-2632-4c88-a0ea-97ab5eb64c94" ``` ### Custom CA If your SysReptor installation uses a self-signed certificate, you can specify the path to your CA bundle in your config file (`~/.sysreptor/config.yaml`): ```shell requests_ca_bundle=/etc/ssl/certs/ca-certificates.crt ``` As an alternative, you can set it as environment variable: ```shell export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt ``` Environment variables override config file settings. ### API timeout HTTP request timeout defaults to 30 seconds. Increase it for slow connections or large exports via config file, environment variable, or CLI: ```yaml # ~/.sysreptor/config.yaml api_timeout: 60 ``` ```shell export REPTOR_API_TIMEOUT=60 reptor project --timeout 60 ``` Long-running operations (report render, project/template export) use at least 300 seconds, or your configured timeout if higher. ### Usage ```txt usage: reptor [-h] [-s SERVER] [-t TOKEN] [-k] [-p PROJECT_ID] [--timeout SECONDS] [--personal-note] [-v] [--debug] [-n NOTETITLE] [--no-timestamp] [--file FILE] Examples: reptor conf echo "Upload this!" | reptor note reptor file data/* cat sslyze.json | reptor sslyze --json --push-findings reptor nmap --xml --upload -i nmap.xml options: -h, --help show this help message and exit -v, --verbose increase output verbosity (> INFO) --debug sets logging to DEBUG -n NOTETITLE, --notetitle NOTETITLE --no-timestamp do not prepend timestamp to note --file FILE Local file to read subcommands: Core: conf Shows config and sets config mcp Starts the Model Context Protocol (MCP) server plugins Allows plugin management & development Projects & Templates: ai Process report sections using OpenAI with dynamic skill selection createproject Create a new pentest project deletefindings Deletes findings by title deleteprojects Deletes projects by title exportfindings Export your project findings as a summary or checklist file Uploads a file finding Uploads findings from JSON or TOML findingfromtemplate Creates findings from remote finding templates note Uploads and lists notes project Work with projects pushproject Push data to project from JSON or TOML template Queries Finding Templates from SysReptor translate Translate Projects to other languages via Deepl Tools: burp Burp vulnerability importer nessus Nessus vulnerability importer nmap format nmap output openvas OpenVAS vulnerability importer qualys Qualys vulnerability importer sslyze format sslyze JSON output zap Parses ZAP reports (JSON, XML) Importers: defectdojo Imports DefectDojo finding templates ghostwriter Imports GhostWriter finding templates importers Show importers to use to import finding templates Utils: packarchive Pack directories into a .tar.gz file unpackarchive Unpack .tar.gz exported archives configuration: -s SERVER, --server SERVER -t TOKEN, --token TOKEN SysReptor API token -k, --insecure do not verify server certificate -p PROJECT_ID, --project-id PROJECT_ID SysReptor project ID --timeout SECONDS HTTP request timeout in seconds (default: 30) --personal-note add notes to personal notes ``` --- --- url: https://docs.sysreptor.com/cli/tools/burp.md --- # Burp ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ```shell cat burp.xml | reptor burp cat burp.xml | reptor burp --upload # Upload findings as notes cat burp.xml | reptor burp --push-findings # Create findings from scan results ``` ![Pushed Burp findings](/cli/assets/burp_uploaded_findings.png) ![Burp findings as notes](/cli/assets/burp_uploaded_notes.png) Filter your Burp results: ```shell cat burp.xml | reptor burp --filter-severity medium-high --push-findings cat burp.xml | reptor burp --include-plugins 2097928,2097936 --push-findings # Include only plugin IDs 2097928, 2097936 cat burp.xml | reptor burp --exclude-plugins 2097928,2097936 --push-findings # Exclude plugin IDs 2097928, 2097936 reptor burp -i burp_1.xml burp_2.xml --push-findings # Use multiple input files ``` You can add those filter settings to your config by running: ```shell reptor burp --conf ``` ## Retrieve the XML file Export the scanning results from [Burp Professional](https://portswigger.net/burp/documentation/desktop/getting-started/generate-reports) or [Burp Enterprise](https://portswigger.net/burp/documentation/enterprise/user-guide/work-with-scan-results/generate-reports). ## Known limitations ### All uploaded findings are rated as "Info" Burp scans/reports don't offer a CVSS score. If you use CVSS scores for severity ratings in your SysReptor reports, all findings are rated as "Info" because the CVSS vector is not available. ![Burp findings rated as "Info"](/cli/assets/burp_findings_info.png) There are the following solutions: 1. Add CVSS ratings manually after the upload 2. [Add CVSS ratings to your finding templates](./customize-pushed-findings) 3. Change the risk rating in your SysReptor design from CVSS to severity ## Usage ```txt usage: reptor burp [-h] [--conf] [-i [INPUT ...]] [--format | --upload | --push-findings | --template-vars | --parse | --upload-finding-templates] [--severity-filter SEVERITY_FILTER] [--exclude EXCLUDED_PLUGINS] [--include INCLUDED_PLUGINS] Burp vulnerability importer options: -h, --help show this help message and exit --conf, --config Configure plugin settings -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --upload-finding-templates Upload local finding templates to SysReptor --severity-filter SEVERITY_FILTER Filter findings by severity comma-separated ("info,low,medium,high") or as range ("medium-high") --exclude EXCLUDED_PLUGINS Exclude plugin IDs, comma-separated --include INCLUDED_PLUGINS Include plugin IDs, comma-separated; default: all are included ``` --- --- url: https://docs.sysreptor.com/cli/tools/nessus.md --- # Nessus ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ```shell cat nessus.xml | reptor nessus cat nessus.xml | reptor nessus --upload # Upload findings as notes cat nessus.xml | reptor nessus --push-findings # Create findings from scan results ``` ![Pushed Nessus findings](/cli/assets/nessus_uploaded_findings.png) ![Nessus findings as notes](/cli/assets/nessus_uploaded_notes.png) Filter your Nessus results: ```shell cat nessus.xml | reptor nessus --severity-filter medium-critical --push-findings cat nessus.xml | reptor nessus --include-plugins 11219,25216 --push-findings # Include only plugin IDs 11219, 25216 cat nessus.xml | reptor nessus --exclude-plugins 11219,25216 --push-findings # Exclude plugin IDs 11219, 25216 reptor nessus -i nessus_1.xml nessus_2.xml --push-findings # Use multiple input files ``` You can add those filter settings to your config by running: ```shell reptor nessus --conf ``` ## Advanced usage Check out our [video for advanced usage](https://www.youtube.com/watch?v=gVgsV_nx7D0). ## Usage ```txt usage: reptor nessus [-h] [--conf] [-i [INPUT ...]] [--format | --upload | --push-findings | --template-vars | --parse | --upload-finding-templates] [--severity-filter SEVERITY_FILTER] [--snoozed-filter] [--exclude EXCLUDED_PLUGINS] [--include INCLUDED_PLUGINS] Nessus vulnerability importer options: -h, --help show this help message and exit --conf, --config Configure plugin settings -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --upload-finding-templates Upload local finding templates to SysReptor --severity-filter SEVERITY_FILTER Filter findings by severity comma-separated ("info,low,medium,high,critical") or as range ("medium-critical") --snoozed-filter Exclude snoozed vulnerabilities --exclude EXCLUDED_PLUGINS Exclude plugin IDs, comma-separated --include INCLUDED_PLUGINS Include plugin IDs, comma-separated; default: all are included ``` --- --- url: https://docs.sysreptor.com/cli/tools/qualys.md --- # Qualys ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples This importer supports both, Qualys *Web Application Scans* and *Vulnerability Management Scans*. *Limitations*: The Qualys XML exports don't include CVSS vectors, which is why CVSS scores are not populated to the findings. It, however, populates the "severity" field if your design uses it as a finding field. ```shell cat qualys.xml | reptor qualys cat qualys.xml | reptor qualys --upload # Upload findings as notes cat qualys.xml | reptor qualys --push-findings # Create findings from scan results ``` ![Pushed Qualys findings](/cli/assets/qualys_uploaded_findings.png) ![Qualys findings as notes](/cli/assets/qualys_uploaded_notes.png) Filter your Qualys results: ```shell cat qualys.xml | reptor qualys --severity-filter medium-critical --push-findings cat qualys.xml | reptor qualys --include-plugins 150158 --push-findings cat qualys.xml | reptor qualys --exclude-plugins 150158 --push-findings reptor qualys -i qualys_1.xml qualys_2.xml --push-findings # Use multiple input files ``` You can add those filter settings to your config by running: ```shell reptor qualys --conf ``` ## Usage ```txt usage: reptor qualys [-h] [--conf] [-i [INPUT ...]] [--format | --upload | --push-findings | --template-vars | --parse | --upload-finding-templates] [--severity-filter SEVERITY_FILTER] [--exclude EXCLUDED_PLUGINS] [--include INCLUDED_PLUGINS] Qualys vulnerability importer options: -h, --help show this help message and exit --conf, --config Configure plugin settings -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --upload-finding-templates Upload local finding templates to SysReptor --severity-filter SEVERITY_FILTER Filter findings by severity comma-separated ("high,medium") or as range ("medium-critical") --exclude EXCLUDED_PLUGINS Exclude plugin IDs, comma-separated --include INCLUDED_PLUGINS Include plugin IDs, comma-separated; default: all are included ``` --- --- url: https://docs.sysreptor.com/cli/tools/openvas.md --- # OpenVAS ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ```shell cat openvas.xml | reptor openvas cat openvas.xml | reptor openvas --upload # Upload findings as notes cat openvas.xml | reptor openvas --push-findings # Create findings from scan results ``` ![Pushed OpenVAS findings](/cli/assets/openvas_uploaded_findings.png) ![OpenVAS findings as notes](/cli/assets/openvas_uploaded_notes.png) Filter your OpenVAS results: ```shell cat openvas.xml | reptor openvas --min-qod 50 --push-findings cat openvas.xml | reptor openvas --severity-filter medium-critical --push-findings cat openvas.xml | reptor openvas --include-plugins 1.3.6.1.4.1.25623.1.0.103674 --push-findings cat openvas.xml | reptor openvas --exclude-plugins 1.3.6.1.4.1.25623.1.0.103674 --push-findings reptor openvas -i openvas_1.xml openvas_2.xml --push-findings # Use multiple input files ``` You can add those filter settings to your config by running: ```shell reptor openvas --conf ``` ## Usage ```txt usage: reptor openvas [-h] [--conf] [-i [INPUT ...]] [--format | --upload | --push-findings | --template-vars | --parse | --upload-finding-templates] [--severity-filter SEVERITY_FILTER] [--min-qod MIN_QOD] [--exclude EXCLUDED_PLUGINS] [--include INCLUDED_PLUGINS] OpenVAS vulnerability importer options: -h, --help show this help message and exit --conf, --config Configure plugin settings -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --upload-finding-templates Upload local finding templates to SysReptor --severity-filter SEVERITY_FILTER Filter findings by severity comma-separated ("high,medium") or as range ("medium-critical") --min-qod MIN_QOD Minimum OpenVAS Quality of Detection (QoD) to include (0-100) --exclude EXCLUDED_PLUGINS Exclude plugin IDs, comma-separated --include INCLUDED_PLUGINS Include plugin IDs, comma-separated; default: all are included ``` ## OpenVAS XML export You can use the following filter to export all findings. ``` apply_overrides=0 min_qod=0 first=1 sort-reverse=severity rows=1000 ``` If you want to export (more than 1.000) rows, set [`ignore_pagination="1"`](https://forum.greenbone.net/t/export-all-scan-results-from-a-single-report-or-multiple-when-then-are-more-than-1000-results/12383/8). One way to do this is to run the following commands as an **unprivileged user**. ```shell user="your OpenVAS username" report_id="your report id" gvm-cli --gmp-username "$user" socket --xml "" ``` --- --- url: https://docs.sysreptor.com/cli/tools/nmap.md --- # nmap ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ```shell sudo -n nmap -Pn -n -sV -oX - -p 0-65535 $target | tee nmap-output.xml ``` ```shell cat nmap-output.xml | reptor nmap -oX | Hostname | IP | Port | Service | Version | | ------- | ------- | ------- | ------- | ------- | | www.google.com | 142.250.180.228 | 80/tcp | http | gws | | www.google.com | 142.250.180.228 | 443/tcp | https | gws | | www.syslifters.com | 34.249.200.254 | 80/tcp | http | n/a | | www.syslifters.com | 34.249.200.254 | 443/tcp | https | n/a | ``` ```shell cat nmap-output.xml | reptor nmap -oX --upload # Upload table to notes reptor nmap -oX -i nmap_1.xml nmap_2.xml --upload # Use multiple input files ``` ![Uploaded nmap notes](/cli/assets/nmap-notes.png) ## Usage ```txt usage: reptor nmap [-h] [-i [INPUT ...]] [--format | --upload | --parse] [--xml | -oX | -oG] format nmap output options: -h, --help show this help message and exit -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --parse --xml -oX nmap XML output format, same as --xml (recommended) -oG, --grepable nmap Grepable output format ``` --- --- url: https://docs.sysreptor.com/cli/tools/sslyze.md --- # SSLyze ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ```shell target=example.com:443 sslyze --sslv2 --sslv3 --tlsv1 --tlsv1_1 --tlsv1_2 --tlsv1_3 --certinfo --reneg --compression --heartbleed --openssl_ccs --fallback --robot "$target" --json_out=- | tee sslyze.json ``` ```shell cat sslyze.json | reptor sslyze # Format cat sslyze.json | reptor sslyze --upload # Format and upload as note cat sslyze.json | reptor sslyze --push-findings # Create findings from scan results reptor sslyze -i sslyze_1.json sslyze_2.json --push-findings # Use multiple input files ``` ![Pushed sslyze finding](/cli/assets/sslyze-finding.png) ## Usage ```txt usage: reptor sslyze [-h] [-i [INPUT ...]] [--format | --upload | --push-findings | --template-vars | --parse | --upload-finding-templates] format sslyze JSON output options: -h, --help show this help message and exit -i [INPUT ...], --input [INPUT ...] Input file, if not stdin (multiple files allowed) --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --upload-finding-templates Upload local finding templates to SysReptor ``` --- --- url: https://docs.sysreptor.com/cli/tools/zap.md --- # ZAP ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## Examples ZAP reports can be exported as XML or JSON. ```shell cat zap.json | reptor zap cat zap.json | reptor zap --upload # Upload findings as notes cat zap.json | reptor zap --push-findings # Create findings from scan results ``` ```shell cat zap.xml | reptor zap --xml cat zap.xml | reptor zap --xml --upload # Upload findings as notes cat zap.xml | reptor zap --xml --push-findings # Create findings from scan results ``` ## Usage ```txt usage: reptor zap [-h] [-i [INPUT]] [--format] [--upload] [--push-findings] [--template-vars] [--parse] [--xml | --json] [--upload-finding-templates] Parses ZAP reports (JSON, XML) options: -h, --help show this help message and exit -i [INPUT], --input [INPUT] Input file, if not stdin --format --upload --push-findings --template-vars Print template variables (needed for finding template customization). --parse --xml --json --upload-finding-templates Upload local finding templates to SysReptor ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/project.md --- # Project The project plugin lets you interact with your SysReptor projects. ## Render Reports ```shell reptor project --render # Render report to PDF and download reptor project --render -o file.pdf # Save to file.pdf reptor project --render -o - # Write to stdout reptor project --render --upload # Upload to notes reptor project --render --design 0222cdf1-4208-491c-8a23-7d49d67707ff # Render with alternative design ``` You can add the design ID of your alternative design to your `~/.sysreptor/config.yaml`: ```yaml project: design: 0222cdf1-4208-491c-8a23-7d49d67707ff ``` ## Export Reports ```shell reptor project --export tar.gz # Export your report to tar.gz reptor project --export tar.gz -o - # Export your report to tar.gz, write to stdout reptor project --export json reptor project --export toml -o - # Write report as toml to stdout reptor project --export yaml --upload # Export report as yaml and upload to notes ``` ## Usage ```txt usage: reptor project [-h] [--search SEARCHTERM | --export {tar.gz,json,toml,yaml} | --render | --duplicate] [--finish | --reactivate] [-o FILENAME] [--design DESIGN ID] [--upload] [--json] Work with projects options: -h, --help show this help message and exit --search SEARCHTERM Search for term --export {tar.gz,json,toml,yaml} Export project --render Render project --duplicate Duplicate project --finish Set project as finished --reactivate Reactivate a finished project -o FILENAME, --output FILENAME Filename for output --design DESIGN ID Render project with alternative design --upload Used with --export or --render; uploads file to note --json Used with --search; output as json ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/createproject.md --- # CreateProject Create a new pentest project via CLI. This module updates your reptor config with the newly created project ID, so you can immediately continue with other commands.\ Use `--no-update-config` to prevent this behavior. ## Examples ```shell reptor createproject --name "New project" --design "8a6ebd7b-637f-4f38-bfdd-3e8e9a24f64e" --tags web,auto reptor createproject --name "New project" --design "8a6ebd7b-637f-4f38-bfdd-3e8e9a24f64e" --no-update-config ``` ## Usage ```txt usage: reptor createproject [-h] [-n PROJECT NAME] -d DESIGN ID [-t TAGS] [--no-update-config] Create a new pentest project options: -h, --help show this help message and exit -n PROJECT NAME, --name PROJECT NAME Project name -d DESIGN ID, --design DESIGN ID Design UUID for the project -t TAGS, --tags TAGS Comma-separated project tags --no-update-config Do not update project ID in config file ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/pushproject.md --- # PushProject Push project data (section and finding data) to your pentest report by JSON or TOML. ## Example ```shell cat project.json | reptor pushproject cat project.toml | reptor pushproject ``` If to push your data to a new report, create a project beforehand. ```shell reptor createproject --name "New project" --design "8a6ebd7b-637f-4f38-bfdd-3e8e9a24f64e" cat project.json | reptor pushproject ``` ## Sample project Upload project data by using the following structures.\ You can add data to your report sections and create or update findings. If a finding has an `id`, reptor will update the finding instead of creating it. ```json { "sections": [ { "status": "finished", "data": { "title": "Report title", "customer_name": "GotBreached Ltd.", "receiver_name": "Maxima Doe", "executive_summary": "This is the Executive Summary\n", "report_date": "2022-04-25", "list_of_changes": [ { "description": "Draft", "date": "2022-04-22", "version": "0.1" }, { "description": "Final Report", "date": "2022-04-25", "version": "1.0" } ] } } ], "findings": [ { "status": "in-progress", "data": { "title": "Session management weaknesses", "cvss": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N", "summary": "My Summary", "affected_components": [ "example.com" ] } }, { "status": "finished", "data": { "title": "Untrusted TLS certificates", "cvss": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N", "summary": "Summary", "recommendation": "", "affected_components": [ "example.com" ] } } ] } ``` ```toml [[sections]] status = "finished" [sections.data] title = "Report title" customer_name = "GotBreached Ltd." receiver_name = "Maxima Doe" executive_summary = "This is the Executive Summary\n" report_date = "2022-04-25" list_of_changes = [ { description = "Draft", date = "2022-04-22", version = "0.1" }, { description = "Final Report", date = "2022-04-25", version = "1.0" }, ] [[findings]] status = "in-progress" [findings.data] title = "Session management weaknesses" cvss = "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N" summary = "My Summary" affected_components = [ "example.com", ] [[findings]] status = "finished" [findings.data] title = "Untrusted TLS certificates" cvss = "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N" summary = "Summary" recommendation = "" affected_components = [ "example.com", ] ``` ## Usage ```txt usage: reptor pushproject [-h] [projectdata] Push data to project from JSON or TOML positional arguments: projectdata options: -h, --help show this help message and exit ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/deleteprojects.md --- # DeleteProjects Delete SysReptor projects.\ Dry run is default: No projects are deleted unless you specify `--no-dry-run`. ## Example ```shell reptor deleteprojects --title-contains "delete me" # Delete projects matching the search query reptor deleteprojects --exclude-title-contains "leave me" # Exclude projects with search query reptor deleteprojects --no-dry-run # Delete all projects, no dry run ``` ## Usage ```txt usage: reptor deleteprojects [-h] [--title-contains SEARCHTERM] [--exclude-title-contains SEARCHTERM] [--no-dry-run] Deletes projects by title options: -h, --help show this help message and exit --title-contains SEARCHTERM Match string in title --exclude-title-contains SEARCHTERM Matched strings in title are not deleted --no-dry-run Do delete projects, default is dry-run ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/finding.md --- # Finding Create findings in your pentest report by JSON or TOML. ## Examples ### Create findings ```shell cat finding.json | reptor finding cat finding.toml | reptor finding ``` ### Update findings ```shell cat finding.json | reptor finding --update c46fd6f7-b265-4434-a5b1-872b3b90ab71 cat finding.toml | reptor finding --update c46fd6f7-b265-4434-a5b1-872b3b90ab71 ``` The `--update` switch takes the finding ID you want to update (find the ID in the finding URL). ### Sample finding Upload one finding by using the following structures.\ Use a list to upload multiple findings. ```json { "status": "in-progress", "data": { "cvss": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N", "title": "Reflected XSS", "summary": "We detected a reflected XSS vulnerability.", "references": [ "https://owasp.org/www-community/attacks/xss/" ], "description": "The impact was heavy.", "recommendation": "HTML encode user-supplied inputs.", "affected_components": [ "https://example.com/alert(1)", "https://example.com/q=alert(1)" ] } } ``` ```toml status = "in-progress" [data] cvss = "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N" title = "Reflected XSS" summary = "We detected a reflected XSS vulnerability." references = [ "https://owasp.org/www-community/attacks/xss/",] description = "The impact was heavy." recommendation = "HTML encode user-supplied inputs." affected_components = [ "https://example.com/alert(1)", "https://example.com/q=alert(1)",] ``` ## Usage ```txt usage: reptor finding [-h] [--update FINDING ID] Uploads findings from JSON or TOML options: -h, --help show this help message and exit --update FINDING ID Update finding with the given ID ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/findingfromtemplate.md --- # FindingFromTemplate Create new findings from finding templates by template ID or tag.\ Specifying a tag might create multiple findings. Tags can be comma-separated and are `and`-connected. If a finding exists in the report that was created from a finding template, it is not newly added. ## Examples ```shell reptor findingfromtemplate --template-id 8a6ebd7b-637f-4f38-bfdd-3e8e9a24f64e reptor findingfromtemplate --tags web reptor findingfromtemplate --tags web,sql # Create findings from templates that have both tags "web" and "sql" ``` ## Usage ```txt usage: reptor findingfromtemplate [-h] [--template-id [TEMPLATE_ID]] [--tags TAGS] Creates findings from remote finding templates options: -h, --help show this help message and exit --template-id [TEMPLATE_ID] UUID of the template to use --tags TAGS Create findings from finding templates with the specified tags; comma-separated list of tags ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/exportfindings.md --- # ExportFindings Export your project findings as a summary or checklist. ```shell reptor exportfindings # csv to stdout reptor exportfindings --format json --output "findings.json" # json to file reptor exportfindings --format toml --fieldnames title,cvss # export custom fieldnames ``` ## Usage ```txt usage: reptor exportfindings [-h] [--format {csv,json,toml,yaml}] [--fieldnames FIELDNAMES] [-o FILENAME] [--upload] Export your project findings as a summary or checklist options: -h, --help show this help message and exit --format {csv,json,toml,yaml} Output format --fieldnames FIELDNAMES Fieldnames to be included, comma-separated -o FILENAME, --output FILENAME Filename to store output, empty for stdout --upload Used with --export or --render; uploads file to note ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/deletefindings.md --- # DeleteFindings Delete findings from your project.\ Dry run is default: No findings are deleted unless you specify `--no-dry-run`. ## Example ```shell reptor deletefindings --title-contains "delete me" # Delete findings matching the search query reptor deletefindings --exclude-title-contains "leave me" # Exclude findings with search query reptor deletefindings --no-dry-run # Delete all findings, no dry run ``` ## Usage ```txt usage: reptor deletefindings [-h] [--title-contains SEARCHTERM] [--exclude-title-contains SEARCHTERM] [--no-dry-run] Deletes findings by title options: -h, --help show this help message and exit --title-contains SEARCHTERM Match string in title --exclude-title-contains SEARCHTERM Matched strings in title are not deleted --no-dry-run Do delete findings, default is dry-run ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/template.md --- # Template Upload and query Finding Templates from SysReptor ## Upload finding templates ```shell cat template.json | reptor template cat template.toml | reptor template ``` ### Sample finding template Upload one finding template by using the following structures.\ Use a list to upload multiple finding templates. ```json { "tags": [ "web" ], "translations": [ { "language": "en-US", "is_main": true, "status": "finished", "data": { "title": "My Title", "description": "My Description" } } ] } ``` ```toml tags = [ "web", ] [[translations]] is_main = true language = "en-US" status = "finished" [translations.data] title = "My title" description = "My description" ``` ## Update finding templates You can update an existing finding template by providing its UUID with the `--update` parameter. ```shell cat template.json | reptor template --update cat template.toml | reptor template --update ``` ::: info Only one template can be updated at a time. If you attempt to update with multiple templates, you will receive an error. ::: ::: tip To get the UUID of an existing template, use `reptor template --search ` to list templates with their IDs. ::: ## Read finding templates ```shell reptor template --list # template overview reptor template --search SQL # template overview, search for keywords reptor template --search SQL --export plain # print templates for copy&paste reptor template --search SQL --export plain --language en # filter for language reptor template --export json # export templates as json reptor template --search SQL --export json # search for keyword reptor template --export tar.gz # export all templates as tar.gz (importable via SysReptor web interface) ``` ## Usage ```txt usage: reptor template [-h] [--list] [--search SEARCH] [--update UPDATE] [--language LANGUAGE] [--export {tar.gz,json,yaml,plain}] [-o FILENAME] Queries Finding Templates from SysReptor options: -h, --help show this help message and exit -o FILENAME, --output FILENAME Filename for output --list List all finding templates --search SEARCH Search for term --update UPDATE Update existing template with given UUID --language LANGUAGE Template language for export format "plain", e.g. "en" --export {tar.gz,json,yaml,plain} Export templates ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/file.md --- # File `file` uploads files from your system into a SysReptor note. ## Examples ```shell reptor file archive.zip reptor file * # Upload all files ``` ![Uploaded files](/cli/assets/uploaded-files.png) ## Usage ```txt usage: reptor file [-h] [-fn FILENAME] [--no-link] [file ...] Uploads a file positional arguments: file files to upload; leave empty for stdin options: -h, --help show this help message and exit -fn FILENAME, --filename FILENAME filename if file provided via stdin --no-link upload file to project without adding markdown link to note (note that unreferenced files are deleted during regular cleanup jobs) ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/note.md --- # Note `note` creates a new note in SysReptor. ## Examples ```shell echo "*Upload me*" | reptor note # Appends to "Uploads" note echo "*Upload me*" | reptor note --notetitle "My Note" # Custom notetitle ``` ## Usage ```txt usage: reptor note [-h] [--list] [--json] Uploads and lists notes options: -h, --help show this help message and exit --list list available notes --json ``` --- --- url: https://docs.sysreptor.com/cli/projects-and-templates/translate.md --- # Translate Translate pentest reports using Deepl (bring your own Deepl API token). ## Examples ```shell reptor translate -to DE --dry-run reptor translate --from EN -to DE reptor translate -to DE --skip-fields recommendation,summary ``` ## Installation Make sure you installed required dependencies by using `pip install reptor[translate]` or `pip install reptor[all]`. ## Configuration The translate module needs additional configurations, which you can add to `~/.sysreptor/config.yaml`: ```yaml translate: deepl_api_token: skip_fields: - description ``` `skip_fields` can be used to do not translate certain report or finding fields. ## Usage ```txt usage: reptor translate [-h] [--conf] [--from LANGUAGE_CODE] [--to LANGUAGE_CODE] [--skip-fields FIELDS] [--dry-run] Translate Projects to other languages via Deepl options: -h, --help show this help message and exit --conf, --config Configure plugin settings --from LANGUAGE_CODE Language code of source language --to LANGUAGE_CODE Language code of dest language --skip-fields FIELDS Report and Finding fields, comma-separated --dry-run Do not translate, count characters to be translated and checks Deepl quota ``` --- --- url: https://docs.sysreptor.com/cli/utils/unpackarchive.md --- # Unpackarchive `unpackarchive` unpacks exported tar.gz archives (like exported projects, designs, finding templates) to json or toml structures. Use `packarchive` to convert back to tar.gz. ## Examples ```shell reptor unpackarchive --format json --output project ./project.tar.gz # Unpack project archive as json to "project" directory reptor unpackarchive --format toml --output design ./design.tar.gz # Unpack design archive as toml to "design" directory ``` ## Usage ```txt usage: reptor unpackarchive [-h] [-o OUTPUT] [-f {json,toml}] files [files ...] Unpack .tar.gz exported archives positional arguments: files options: -h, --help show this help message and exit -o OUTPUT, --output OUTPUT -f {json,toml}, --format {json,toml} ``` --- --- url: https://docs.sysreptor.com/cli/utils/packarchive.md --- # Packarchive `packarchive` packs unpacked toml and json data structures back to tar.gz archives. Use `unpackarchive` to unpack tar.gz archives (like exported projects, designs, finding templates). ## Examples ```shell reptor packarchive --output project.tar.gz ./project # Pack contents of "project" directory to project.tar.gz ``` ## Usage ```txt usage: reptor packarchive [-h] [-o OUTPUT] directories [directories ...] Pack directories into a .tar.gz file positional arguments: directories options: -h, --help show this help message and exit -o OUTPUT, --output OUTPUT ``` --- --- url: https://docs.sysreptor.com/cli/importers/defectdojo.md --- # Defect Dojo Import finding templates from DefectDojo to SysReptor. ## Examples ```shell reptor defectdojo --url http://localhost/ ``` ## Configuration This module needs additional configurations, which you can add to your config file by running: ```shell $ reptor defectdojo --conf DefectDojo URL: https://localhost DefectDojo API key v2: your-api-key ``` ## Usage ```txt usage: reptor defectdojo [-h] [--conf] [--tags TAGS] [--url [URL]] Imports DefectDojo finding templates options: -h, --help show this help message and exit --conf, --config Configure plugin settings Global Importer Settings: --tags TAGS Comma-separated tags for new templates --url [URL] DefectDojo API ``` --- --- url: https://docs.sysreptor.com/cli/importers/ghostwriter.md --- # Ghostwriter Migrates finding templates from Ghostwriter to SysReptor. ## Examples ```shell reptor ghostwriter --url http://localhost/ghostwriter ``` ## Installation Make sure you installed required dependencies by using `pip install reptor[ghostwriter]` or `pip install reptor[all]`. ## Configuration This module needs additional configurations, which you can add to your config file by running: ```shell $ reptor ghostwriter --conf Ghostwriter URL: https://localhost Ghostwriter API key (x-hasura-admin-secret or JWT token): your-api-key ``` ## Usage ```txt usage: reptor ghostwriter [-h] [--conf] [--tags TAGS] [--url [URL]] Imports GhostWriter finding templates options: -h, --help show this help message and exit --conf, --config Configure plugin settings Global Importer Settings: --tags TAGS Comma-separated tags for new templates --url [URL] Ghostwriter API ``` --- --- url: https://docs.sysreptor.com/cli/writing-plugins/tools.md --- # How to write a tool plugin ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: ## What a plugin does A plugin can... * read tool outputs via stdin on `-i` command line switch (multiple files are supported) * parse them * format them * upload as notes, or * create findings ## Where plugins are located `reptor` comes with a number of plugins.\ However, you can override any plugin by copying it to the `.sysreptor/plugins` folder in your home directory. You can do this by running `reptor plugins --copy --full` If you copy the entire plugin, it overrides the builtin plugins from `reptor`.\ If you want to override templates only, use `reptor plugins --copy `. So you can customize the templates used for formatting the data, while preserving the official functionality of the plugin. ## Create a new plugin Let's say we want to build a plugin for a fictional XSS-tool.\ We can start off using our plugin boilerplate by running `reptor plugins --new XssTool`. This will add the file structure to `.sysreptor/plugins/XssTool`.\ This directory is already dynamically included by `reptor`. When you run `reptor --help`, you should see `xsstool` under the section `Tools`.\ You can also call the help message of your plugin by `reptor xsstool --help`. ## Implement a parser Our XssTool has two output options: * Plaintext * JSON Our plugin already implements some parsing methods and the corresponding arguments: * `parse_json` (`--json`) * `parse_xml` (`--xml`) * `parse_csv` (`--csv`) As we do not need xml and csv parsing, we can remove the methods. This will also make them disappear in the help message.\ The `parse_json` method will be called if the CLI switch `--json` is provided. However, we are missing an option to parse plaintext outputs.\ An example plaintext output would be: ``` https://example.com/alert(1) https://example.com/q=alert(1) ``` Our parsing method should split the lines and store the result into a list: ```python def parse_plaintext(self): self.parsed_input = self.raw_input.splitlines() ``` This function must also be called. We can override the parent's `parse` method for this.\ Calling the parent method makes sure that json parsing is executed. ```python def parse(self): super().parse() if self.input_format == "plaintext": self.parse_plaintext() ``` We still need to add a commandline option for plaintext parsing. This can be done in the `add_arguments` method.\ In the course of this, let's delete the `--foo` and `--bar` commandline options of the boilerplate. We don't need them. (Make sure to leave the `super().add_arguments()` call.) Input formats are mutually exclusive. We want our plaintext parsing switch also to be mutually exclusive. Therefore, we get the mutually exclusive parsing group and add a `--plaintext` switch: ```python @classmethod def add_arguments(cls, parser, plugin_filepath=None): super().add_arguments(parser, plugin_filepath=plugin_filepath) input_format_group = cls.get_input_format_group(parser) input_format_group.add_argument( "--plaintext", help="plaintext output format", action="store_const", dest="format", const="plaintext", ) ``` The default `input_format` is `raw`. Specify the default `input_format` in the `__init__` method: ```python if self.input_format == "raw": self.input_format = "plaintext" ``` We are now done with implementing our parser. We can test it using: ```shell printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --parse ['https://example.com/alert(1)', 'https://example.com/q=alert(1)'] ``` ## Formatting tool output Now we want to bring our data into a beautiful and human-readable format. SysReptor uses markdown and allows HTML syntax there. `reptor` uses the [Django template language](https://docs.djangoproject.com/en/4.2/ref/templates/language/) with a slightly different syntax for formatting. The Django start tags are prepended with the HTML comment start tag and become: ::: v-pre * `{{` becomes `` * `%}` becomes `%}-->` * `#}` becomes `#}-->` ::: (Find the reason for this later in this tutorial.) Let's bring the list of our XSS outputs into the format of a markdown table.\ We find an empty template at `templates/mytemplate.md`. We rename it to `xss-table.md` and place the following template inside: ```md | XSS target | | ------- | | | ``` However, we have never defined the `data` variable.\ This was automatically done in the `preprocess_for_template` method: ```python def preprocess_for_template(self): return {"data": self.parsed_input} ``` This method is like a second parsing step for preparing the parsed data for usage in a template. You can add entries to the dictionary for easier template processing. We can now try to format our output: ```shell printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --format | XSS target | | ------- | | https://example.com/alert(1) | | https://example.com/q=alert(1) | ``` This gives us bad newlines within the table because the Django template engine leaves the newlines from the `for` loop there.\ We can resolve this by using the `noemptylines` tag: ```md | XSS target | | ------- | | | ``` ## Uploading to notes If you haven't done this yet, you can now add the configuration of your SysReptor installation.\ Create an API token at `https://yourinstallation.local/users/self/apitokens/` and run `reptor conf` to add all necessary information. Let's upload our formatted data to the project notes: ```shell printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --upload Successfully uploaded to notes. ``` If you experience any problems during upload, check if the user has permission for the project ID from your configuration. Use the `--debug` switch for further troubleshooting. Your formatted output is now uploaded to your project notes: ![XssTool Note](/cli/assets/xsstool-note.png) Use `--notetitle "My Notename"` for a different title and `--private-note` to add it to your private notes. You can also update the default note title and replace your note icon in the `__init__` method: ```python self.notetitle = kwargs.get("notetitle") or "XSS Tool" self.note_icon = "🔥" ``` ### More complex note structures We can also create more complex note structures, like one note per target: ![XssTool Multiple Notes](/cli/assets/xsstool-multinote.png) Therefore, we implement the `create_notes` method. In the first step, we group the data by URL, which should result in the following JSON structure: ```json { "https://example.com/alert(1)": [ "https://example.com/alert(1)" ], "https://example.com/q=alert(1)": [ "https://example.com/q=alert(1)" ] } ``` We can do this by implementing: ```python def create_notes(self): data = {t: [t] for t in self.parsed_input} ``` We then use the `NoteTemplate` model for creating our note stucture. Import the model using: ```python from reptor.models.Note import NoteTemplate ``` Our main parent note is a note called `xsstool`. It is created by: ```python main_note = NoteTemplate() main_note.title = self.notetitle main_note.icon_emoji = self.note_icon main_note.parent_title = "Uploads" # Put note below "Uploads" ``` We then iterate through our URLs, create one note per URL and append it as a child of our parent note. Finally, we return the parent note. ```python for url, target_list in data.items(): ip_note = NoteTemplate() ip_note.title = url ip_note.checked = False # Make note an unticked checkbox instead of emoji ip_note.template = "mytemplate" # Format note using our Django template ip_note.template_data = {"data": target_list} # Provide data for template main_note.children.append(ip_note) # Append as child of parent note return main_note # Return parent note ``` We can now upload one note per target as seen in the screenshot above: ```python printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --upload Successfully uploaded to notes. ``` ## Create findings Creating notes is nice but... We want to automate our report. The first thing we need to define is a name for your finding and a condition when the finding should be triggered. We call our finding `xss`. This means, we need to implement a method called `finding_xss`. This method should return data that can be used by Django templates. It many cases, the data might equal the return value of `preprocess_for_template`. The method should return `None` if no issue should be triggered. In our case, we want to trigger an issue if the list in parsed input is not empty. Let's implement this method: ```python def finding_xss(self): if len(self.parsed_input) > 0: return self.preprocess_for_template() return None ``` As soon as you have defined a `finding_*` method, you should have an option in your plugin's help message: `--push-findings`. Now we have to define, what the contents of the findings should be. Find a sample finding in the `findings` directory.\ Rename this file to `xss.toml` to match it our vulnerability name. The findings definitions are in [TOML](https://toml.io/) format. Adapt the contents of the file, as needed, e. g.: ```toml [data] title = "Reflected Cross-Site Scripting (XSS)" cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N" summary = """ We detected a reflected XSS vulnerability. """ recommendation = "HTML encode user-supplied inputs." references = [ "https://owasp.org/www-community/attacks/xss/", ] ``` You can use the adapted Django template language in the fields in the TOML structure. Note that you can now include templates that we defined earlier as `xss-table.md`. We can use our new switch `--push-findings` and create a new finding in our SysReptor report: ```python printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --push-findings Pushed finding "Reflected Cross-Site Scripting (XSS)" ``` It was pushed to the SysReptor server and can be found in the project from the configuration: ![Pushed XSS finding](/cli/assets/pushed-finding.png) Note that no affected components were added to the finding. We can add the field `affected_components` as a list to the dictionary returned by our `finding_xss` method to be filled out: ```python def finding_xss(self): if len(self.parsed_input) > 0: result = self.preprocess_for_template() result["affected_components"] = self.parsed_input return result return None ``` If you now push the finding again, it will not work because a finding with the same title already exists.\ Delete or rename the first finding, push again and the affected components will also be present in your finding. ## Create findings from SysReptor templates We just created a finding from a TOML file.\ However, if you maintain your finding templates in SysReptor, you might want to create your findings from your centrally managed library. That's easier done than said: Add a tag to your finding template in the format `:`. In our case this is `xsstool:xss`. ![Tag for finding template](/cli/assets/template-tag.png) We can use the string and markdown fields to insert our Django templates: ![Tag for finding template](/cli/assets/django-template-in-finding-template.png) The Django templates are now HTML comments. If you manually use your finding templates, the Django templates will not be rendered into your report. This is the reason the modified the Django tags. Templates from the SysReptor template library are preferred over TOML-templates. You can now generate your finding from your template library: ```shell printf "https://example.com/alert(1)\nhttps://example.com/q=alert(1)" | reptor xsstool --push-findings Pushed finding "Reflected Cross-Site Scripting (XSS)" ``` The finding was created successfully. You see from the "T" at the top that the finding was created from a template. ![Finding created from template library](/cli/assets/finding-from-library.png) If you now re-run the command, `reptor` will refuse to push the finding again. This is because the report holds a finding that was created from the same finding template. ## Source Code [Download](/cli/assets/XssTool.zip) the full source code of this plugin. --- --- url: https://docs.sysreptor.com/cli/writing-plugins/importers.md --- # How to write an importer Importers currently support the import of finding templates from other tools.\ (In the future it might also support the import of projects.) ## Copy an existing importer You can copy, for example, the Ghostwriter plugin to `.sysreptor/plugins` in your home directory. Rename the `Ghostwriter` directory and `Ghostwriter.py` to the desired name. Also update the `loader` variable at the bottom to your new class in your `.py` file. You will be able to call your plugin via `reptor `. In the future, we might provide an empty boilerplate for easier importer creation. ## Importer settings You will probably have to use some settings in your plugin, like from what URL the data should be fetched, or an API key. There are two options how to provide those settings: * CLI parameter * config.yaml ### Settings via CLI parameter Use the `add_arguments` method to add your custom CLI arguments ```python @classmethod def add_arguments(cls, parser, plugin_filepath=None): super().add_arguments(parser, plugin_filepath=plugin_filepath) action_group = parser.add_argument_group() action_group.add_argument( "--url", metavar="URL", action="store", const="", nargs="?", help="API Url", ) ``` You can use `--help` to check if your arguments are available: `reptor --help`. Access your arguments via the `kwargs` dictionary in `__init__.py`, e. g. `self.url = kwargs.get("url", "")` ### Settings via config.yaml reptor settings are managed in `.sysreptor/config.yaml` in your home directory. You can add plugin specific settings there, e. g.: ```yaml project_id: 42c2f73a-4383-4ec2-a3fa-281598edb0e8 server: https://demo.sysre.pt token: sysreptor_TOKEN your_plugin: apikey: your_api_key url: http://localhost:8080 ``` Those settings are attributes of `self` in your plugin. If those settings are mandatory, you can raise an exception if they are not present, e. g.: ```python def __init__(self, **kwargs) -> None: super().__init__(**kwargs) if not hasattr(self, "apikey"): raise ValueError( "API Key is required. Add to your user config." ) ``` ## Fetch finding templates from source It's time to get findings from your source. Use the `next_findings_batch` method to yield finding template by finding template, e. g.: ```python def next_findings_batch(self): findings = self._get_findings_from_source() for finding_data in findings: yield { "language": "en-US", "status": "in-progress", "data": finding_data, } ``` Note that you have to implement `_get_findings_from_source` yourself. This is where you access your source's API. `finding_data` is a dictionary containing the fields of your source. The full data structure might look like: ```json { "language": "en-US", "status": "in-progress", "data": { "title": "Finding Title", "description": "Finding Description", "links": "https://example.com/\nhttps://example.com/reference" }, } ``` The field names should be those from your source, not from SysReptor. If your source supports translations, you can yield a list containing this data structure, e. g. ```json [ { "language": "en-US", "status": "in-progress", "data": { "title": "Finding Title", "description": "Finding Description", "links": "https://example.com/\nhttps://example.com/reference" }, } ] ``` ## Mapping field names Define a `mapping` attribute in your class to map the field names of your source to the SysReptor fields, e. g.: ```json { "title": "title", "description": "description", "links": "references" } ``` In this example, the source field `title` maps to the SysReptor field `title`. However, the source field `links` should be mapped to the field `references`. We encourage you to map to predefined SysReptor fields only. This guarantees compatibility with all SysReptor installations and designs. ## Processing values In the example above, the `links` field containes a newline-separated field of links. However, `references` in SysReptor is a list. To process and/or convert values, you can define a method called `convert_`. This will be called to preprocess the values of the fields. ```python def convert_links(self, value): return value.splitlines() ``` ## Run and enjoy You can now run your newly created importer by `reptor `.\ Use the `--tags` switch to add tags to imported template to be able to search for the imported templates later. --- --- url: https://docs.sysreptor.com/insights/architecture.md --- # SysReptor Architecture This is a short explanation of the SysReptor architecture in self-hosted environments. ## Overview ![SysReptor self-hosted architecture](/images/architecture.png) ## The Happy SysReptor User The happy SysReptor user accesses SysReptor with a browser. The user is so happy because pentest reporting is now more convenient. ## The Web Browser Web browser should be up to date. We officially support Chrome, Firefox, Safari and Edge. The browser displays the web contents and executes JavaScript and Vue.js code delivered from the SysReptor app. Communications happens via the HTTP(S) protocol and via WebSockets. ## The Server An Ubunutu server with preinstalled Docker v2 incl. the Docker Compose plugin is a prerequisiste of running SysReptor.\ It might be possible to use different Operating Systems or Distributions, which is, however, not officially supported. ## The Web Server The web server is responsible for handling web requests and for proxying the requests to the SysReptor App server.\ We recommend setting up TLS for encrypted communication. Our [setup script](/setup/installation#easy-script-installation) offers the possibility to spin up a Caddy web server as reverse proxy, which also handles TLS certificates, incl. renewals. You can, however, also use reverse proxies that already exist in your infrastructure. They must be able to handle WebSocket communications. ## The SysReptor App This is our core component that we actively develop and maintain. It is a Python/Django application and uses the Django Rest Framework (DRF) as server technology, and Vue.js with Vuetify as client/frontend technology. The SysReptor app handles the application logic, permissions, data handling, etc. In self-hosted installations, it also does the PDF rendering jobs that [render data to PDF](/insights/rendering-workflow). For this, it uses a headless Chromium browser for rendering the final HTML and [Weasyprint](https://weasyprint.org/) for converting the HTML to PDF. ## The Database SysReptor uses a PostgreSQL database for storing data persistently. The SysReptor app optionally holds a secret which is used to store sensitive data in encrypted form.\ If encryption is enabled, you must have the secret to be able to restore data from the database. ## Redis SysReptor uses the in-memory database Redis for temporarily storing information. This is (among others) necessary for synchronizing activities between users during report writing, allowing for example collaborative editing.\ Data stored in Redis is mostly indexes and references and is not encypted. ## Languagetool SysReptor Professional users can use the integrated spell check. This requires the [languagetool](https://languagetool.org/) container which provides a web API to receive text and to suggest improvements. Data received by languagetool in unencrypted and stored in memory and/or local caches. ## The S3 Bucket Users can upload images to reports and any filetypes to notes. Those files are by default stored in the SysReptor app container. If encryption is enabled, all files are encrypted. You can optionally configure SysReptor to use an S3 bucket for storing files. If encryption is enabled, the S3 bucket provider has no access to file contents. (When enabling encryption you must run `docker compose run --rm app python3 manage.py encryptdata` from the `deploy` directory to force encryption of stored but unencrypted data.)\ You must have the secret to recover encrypted files from your S3 bucket. ## What about the Cloud? This was an overview of the self-hosted SysReptor architecture. In our Cloud service, we use the same components, but maintain them in a Kubernetes cluster in which every customer receives a dedicated namespaces. The database server is shared among the customers, but separated using dedicated users and databases for each customer.\ Files are stored on an internal hosted S3 bucket. The SysReptor apps can only access their own files using temporary S3 keys with permissions restricted to their customer files.\ PDF rendering is performed by a pool of rendering workers. The rendering worker pool is shared among all customers, but after each PDF render the worker job is shut down and replaced with a fresh worker instance. Rendering worker instances are never reused to render reports of different customers. --- --- url: https://docs.sysreptor.com/insights/rendering-workflow.md --- # Rendering Workflow Each pentest project needs a design which specifies how the final report looks like and what fields are available in the report and findings. The report designer lets you customize how your final PDF reports look like. We do not limit your report look and feel in any way and allow you to customize your reports to your needs. PDF rendering is a two-step process. First, the VueJS template is rendered to plain HTML with Headless Chromium. In this step report variables (section fields, findings) are embedded in the final HTML. Second, the HTML and CSS styles are rendered to a PDF using WeasyPrint. ![Rendering Workflow](/images/render-workflow.drawio.png) ## Two rendering engines: Chromium and Weasyprint You might be wondering why we combine two rendering engines. The short answer is: To make it easy to design amazing PDF reports with all features expected from a reporting tool. And here is the long answer: The rendering workflow may seem to require lot of resources and slow since we utilize Chromium. Yes, this approach is resource-intensive and rendering can take some time (typically between 3 and 10 seconds depending on the complexity and size of the report). However, we want to note that Chromium is not solely responsible for this. On average, the VueJS rendering with Chromium takes about 1 second. The remaining time is required by WeasyPrint to generate the PDF. ## WeasyPrint supports advanced CSS printing rules You may be wondering why we didn't just use Chromium to generate the PDFs and added the slow WeasyPrint. While Chromium does have a print to PDF feature, it is only suitable for printing web pages to save their content and is not ideal for creating aesthetically pleasing PDFs. This is because Chromium has not implemented many CSS rules that are specific to the CSS printing spec, which are crucial for printing and generating PDFs. On the other hand, WeasyPrint was designed specifically to render PDFs and supports many of these printing CSS rules. ## Server-side rendering renders in a single pass You may also be wondering why we chose to use VueJS with Chromium instead of a simpler or faster template engine to render HTML. Most template engines are designed for server-side rendering. They process the template from start to end, insert variables, evaluate expressions, iterate through loops and output the final HTML. Everything is rendered in a single pass. ## Complex documents need multi-pass rendering Let's consider following scenario: You are designing a pentest report. It contains a fancy title page, management summary, section with static text (e.g. disclaimer) and list of findings. You had an interesting pentest and found many vulnerabilities, the report grows in size. It is already 50 pages long and its hard to have an overview. Therefore, you want to add a table of contents to the beginning. With single-pass rendering, you would have to generate the table of contents upfront before everything else, because it is on top of the template. This is not very flexible because the table of contents may contain sections with static texts defined in HTML, finding list, conditional sections that are rendered only in some situations (e.g. list of figures hidden when there are no figures in the report, optional appendix section for portscan results, etc.) or you might event want to include sections/headlines from markdown fields. ## Manual handling of dynamic references is error-prone When generating the table of contents you would have to make sure that you do not forget anything. Manually syncing the table of contents with the actual chapters is error-prone, especially, when make quick changes after some time and forget to update the table of contents. It would be better and more convenient when the table of contents is automatically generated from the renderd HTML content, such that includes all chapters from static text, dynamic finding lists and even markdown text. The same problem applies for all kind of lists that should be auto-generated based on the content. Another examples are list of figures or list of tables. They should include all figures or tables from the whole document. Figures might occur in static texts from the design or markdown fields of sections or findings. All should appear in the list of figures, regardless of their source. ## Multi-pass: Render chapters first, then the references In order to achive that, we need multi-pass rendering: First render the actual chapters, in the second pass collect the defined chapters and render the table of contents. In LaTeX you need to compile at least twice for all references to be correct (table of contents, bibliography, citings, etc.). ## VueJS is super-dynamic... Here is where VueJS comes into play. Vue and other client-side JavaScript frameworks (React, Angular, etc.) are designed to be reactive. When some state changes or users interact with the website (user inputs, clicking, DOM events, etc.), the framework re-renders the HTML. It natively supports re-rendering parts of the template and therefore we can easily achieve multi-pass rendering. With Vue we can re-render the table of contents and other references until nothing changes anymore. ## ...and delivers a great ecosystem with additional features Besides multi-pass rendering, Vue (and JS) are client-side technologies with a great ecosystem of UI libraries, such as [charts](/designer/charts). We can reuse these libraries for PDF rendering and take advantage of existing, mature, actively maintained and well-documented UI libraries. --- --- url: https://docs.sysreptor.com/insights/archiving.md --- # Archiving This page describes how SysReptor archives and encrypts old pentest projects. It gives an overview of the cryptographic architecture used to protect archives and explains the motivations behind. ## Motivation - Why do we need to archive pentest projects? As a penetration tester, you know how important it is to keep your pentest data safe and secure. It contains highly sensitive data such as vulnerabilities of customer systems and how to exploit them. Sometimes it takes some time to fix the vulnerabilities (or they marked it as "risk accepted"). It's crucial to safeguard pentest reports and pentest data to protect your customer's systems from malicious actors. In fact, you may even have signed an NDA or be subject to contractual penalties if this data is stolen, leaked, or published. But what happens when a pentest is completed and you no longer need to access that data on a regular basis? The most secure option is to delete all data associated with the pentest. However, this is often not possible. The report and pentest evidence (e.g. burp state, command history, scripts, etc.) have to be kept for the purposes of proof of work and warranty. Old pentest data should not be stored in plaintext. Instead they should be encrypted. Restricting access with a permissions is not sufficient, since a system administrator or service provider, for example, could also have access to the data. Access restrictions must be enforced through the use of cryptography. When encrypting pentest data, the question araises who will be able to decrypt the archive again? Balancing confidentiality with availability is an important question. Here are some thoughts to consider: * Data is secure if no one can decrypt it anymore: This is certainly true, but it's important to remember that encryption is only one aspect of data security. There are other factors to consider, such availability. If no one can decrypt the data, it may become unavailable when it's needed, which can be a problem. * What happens if someone leaves the company or loses the key? * If one key is used to encrypt all pentest archives, this key may not get lost. Else all data is inaccessible. * If a different key is used to encrypt pentest archives (i.e. one key per archive), and they are all managed by the same person (e.g. in a password manager) and this person leaves the company, forgets the master key or dies. Again, everything is lost. * If archives are encrypted with multiple keys and these keys are distributed to different persons, when one person loses their key, you have the same problem. And once again, everything is lost. * Should one person be able to decrypt everything alone? To prevent unavailability through key loss, you can give the key to multiple persons. Or you can also design an archiving system where each pentest archive is encrypted with multiple keys and each key is given to a different person. Now everyone is able to decrypt all data on their own. Consider you are a pentesting team of four persons. The optimal compromise between confidientiality and availablity of pentest archives would be to require two persons to access pentest archives. This prevents losing all data when one person (or even a second person) loses their key. It also prevents everyone from accessing all data (e.g. if a key is compromizes or someone leaves the company and wants to steals all data) alone. At least two persons are required, thus enforcing a 4-eye principle. ## Crypto Architecture We use a threshold cryptography scheme in combination with key management based on public key cryptography to cryptographically enforce the 4-eye principle. The core component to cryptographically enforce the 4-eye principle is Shamir Secret Sharing. Shamir Secret Sharing is a threshold sheme for sharing a secret to a group of *n* people whereas *k* people are required to work together to reconstruct the secret. The secret is split into *n* shares and every user is given one share. The threshold *k* defines how many shares are required to reconstruct the secret. Shamir Secret Sharing has the property of information-theoretic security, meaning that even if an attacker steals some shares, it is impossible for the attacker to reconstruct the secret unless they have stolen *k* number of shares. No information about the secret can be gained from any number of shares below than the threshold In order to enforce a 4-eye principle to restore encrypted pentest archives, the threshold needs to be *k=2*. However it is possible to increase the threshold *k* to require 3 or more users for restoring pentest archives for larger companies. Shamir Secret Sharing only allows splitting secrets into shares. It does not handle encryption or key management. We use Shamir Secret Sharing for splitting an AES-Key into multiple Key Shares. Each Key Share is assigned to a different user. Key Shares are encrypted with user's public keys. The private keys are managed offline by users themselves. You can use software keys generated on your computer, but also security tokens such as YubiKeys that generate keys on hardware. Public-key cryptography allows users to create pentest project archives where multiple users have access, without requiring user interaction. For decrypting, user interaction is required. Each user has to decrypt their own Shamir Key Share with their private key. We use OpenPGP for public key encryption, because it supports RSA and elliptic curves and offers support for hardware tokens such as YubiKeys. OpenPGP is a secure, established and trustworthy crypto protocol with great tooling support. It is more user-friendly than using plain openssl and YubiKey CLI tools, and more trustworthy than custom developed crypto tools. Offloading cryptographic operations to hardware tokens such as YubiKeys is considered more secure than using software based encryption, because the secret key is generated on hardware and never leaves the device. This prevents the private key from being leaked or exported. The downside, however, is that it cannot be backed up. If you lose the hardware token, the encrypted data is inaccessible. This is why we support multiple public/private key pairs per user. For example if you use two public keys stored on hardware tokens and if you lose one, you can still restore archives with the second one. Following diagram outlines the process of archiving and encrypting a pentest project: ![Archive and encrypt pentest project](/images/archiving-crypto.drawio.png) 1. Export all project data to a tar.gz archive. This is the same format as directly exporting projects via the web interface. All project data, sections, findings, notes, images, files including the design are exported. 2. The tar.gz archive is encrypted with 256-bit AES-GCM. A random key is generated for each archive. AES-GCM is an authenticated cipher mode (AEAD). Besides encrypting the data, a authentication tag is calculated which is able to detect modifications and corruptions of encrypted data, adding integrity-protection of the ciphertext. The encrypted archive is stored in a file storage ([ARCHIVED\_FILE\_STORAGE](/setup/configuration#archiving)). 3. The AES-key is distributed to multiple users with Shamir Secret Sharing. 4. The Key Shares are encrypted with randomly generated 256-bit AES-GCM keys. Each Key Share is encrypted with a different key. Plain Shamir Secret Sharing does not offer integrity-protection of Key Shares and does not detect if a Key Share used for decryption is valid or not. This step adds integrity protection of Key Shares with the AES-GCM (and confidentiality protection with encryption). The encrypted Key Shares are stored in the database. 5. The AES keys are encrypted with user's public keys. ## How to use ### Prerequisite: Register user public keys Before users are able to archive pentest projects, all archiving users have to register their public keys. Public Keys need to be generated offline and uploaded to the user profile. SysReptor uses OpenPGP encryption keys as the public key format. RSA and elliptic curve keys are supported. Minimum key lengths are enforced to ensure a sufficient security level for some years. For RSA, the minimum accepted key length is 3072 bit. For elliptic curve, the minium curve size is 256 bit. ::: tabs \== Generate private keys with GPG Use following commands to generate an elliptic curve encryption key with `gpg`. Be sure to protect the key with a strong password and make backups. If you lose all your private keys, you can no longer restore archives. ``` cat << EOF > config.txt Key-Type: ECDSA Key-Curve: nistp521 Subkey-Type: ECDH Subkey-Curve: nistp521 Subkey-Usage: encrypt Expire-Date: 0 Name-Comment: SysReptor Archiving Name-Real: Name-Email: EOF gpg --batch --generate-key config.txt gpg --list-secret-keys --keyid-format=long gpg --armor --export ``` \== Generate private keys on YubiKey 5 Use the following command to generate a new Elliptic Curve key pair on a YubiKey 5. The private key is generated on the YubiKey and never leaves the device. Beware that you cannot backup the key. We recommend that you add a second key as a fallback in case you lose your YubiKey. ``` gpg --card-edit Reader ...........: Yubico YubiKey FIDO CCID 00 00 Application ID ...: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: Yubico Serial number ....: 19763721 Name of cardholder: [not set] Language prefs ...: [not set] Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off UIF setting ......: Sign=off Decrypt=off Auth=off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card> admin Admin commands are allowed # Change Yubikey Pin (optional) # Hint: default pin is 123456, default admin pin is 12345678 gpg/card> passwd gpg: OpenPGP card no. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX detected 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 3 PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 1 PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? Q gpg/card> name Cardholder's surname: Cardholder's given name: # Change key type to elliptic curve (optional) gpg/card> key-attr Changing card key attribute for: Signature key Please select what kind of key you want:    (1) RSA    (2) ECC Your selection? 2 Please select which elliptic curve you want:    (1) Curve 25519 *default*    (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 Note: There is no guarantee that the card supports the requested       key type or size. If the key generation does not succeed,       please check the documentation of your card to see which       key types and sizes are supported. Changing card key attribute for: Encryption key Please select what kind of key you want:    (1) RSA    (2) ECC Your selection? 2 Please select which elliptic curve you want:    (1) Curve 25519 *default*    (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: cv25519 Changing card key attribute for: Authentication key Please select what kind of key you want:    (1) RSA    (2) ECC Your selection? 2 Please select which elliptic curve you want:    (1) Curve 25519 *default*    (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 # Generate key pair gpg/card> generate Make off-card backup of encryption key? (Y/n) n Please specify how long the key should be valid. 0 = key does not expire      = key expires in n days    w = key expires in n weeks    m = key expires in n months    y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Email address: Comment: SysReptor Archiving Key You selected this USER-ID: " (SysReptor Archiving Key) " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O public and secret key created and signed. gpg/card> quit gpg --list-secret-keys --keyid-format=long gpg --armor --export ``` ::: During public key registration, you have to prove that you own the private key. A random verification message is generated and encrypted with the public key. You have to decrypt it with your private keys to prove that you own the private key and know how to decrypt data. ### Archive Project Pentest projects first have to be marked as finished, then they can be archived. Before the archive is created and encrypted, all users are displayed that will have access to the archive and are able to restore it. This includes all project members and global archivers. Global archivers are added to every archived project and can be considered archiving backup users. Users can be marked as global archivers in the user permission settings. If too few users (below threshold) are project members or global archivers or do not have any public keys, archiving is not possible. ![Archive project](/images/archive-create.png) ### Restore Archived Projects Archived projects are restored when the required number of users decrypt their key share with their private keys. Users decrypt their key shares separately, independently of each other. When the user threshold is reached, the archived project is restored. ![Restore archived project](/images/archive-restore.png) ![Restore archived project](/images/archive-restore2.png) All users should restore their key parts within 3 days. When some users decrypted their key shares, but others did not, the archive is reset. Decrypted key shares are deleted, meaning that users have to decrypt their key shares again later with their public keys. This prevents partly dearchived projects being stored in the database forever, lowering the required user threshold when archives are actually restored. ### Threshold Recommendations The recommended Shamir Secret Sharing threshold *k* is about half the number of users *n*, but at least 2. This ensures the best combination of confidentiality and availability. For large teams (e.g. >5 global archivers), you might want to use a *k* below *n / 2* to not require as many users for restoring archives. Note that not every user is added to an archive. Only project members and global archivers with public keys are added to archives and are able to access them. Example: You are a large pentesting company with 100 users. A finished project should be archived, where 3 pentesters are project members. Only the 3 project members and (lets say) 2 global archivers will be added to the archive. Our recommendations: * *n = 1* users: *k = 1* recommended * *n = 2* users: *k = 1* or *k = 2* recommended * *n = 3* users: *k = 2* recommended * *n = 4* users: *k = 2* recommended * *n = 5* users: *k = 2* recommended * *n = 10* users: *k = 3* or *k = 4* recommended The threshold value is configured globally per instance by the settings [ARCHIVING\_THRESHOLD](/setup/configuration#archiving). --- --- url: https://docs.sysreptor.com/insights/project-search.md --- # Searching encrypted project data SysReptor stores sensitive pentest report content (e.g. findings, sections) encrypted in the database. This is a security measure: even a compromised database should not expose sensitive pentest data. But database encryption creates challenges: the database cannot run queries against ciphertext, so any operation on encrypted content (e.g. search) requires special handling. This page explains how SysReptor implements full-text search over encrypted project data using a blind trigram index. ## The problem with encrypted fields Most tools search content by running `LIKE '%keyword%'` or full-text search queries directly in the database. This works because the database can read the stored values in plaintext. SysReptor encrypts sensitive project data at the application layer before it reaches the database. The database only ever sees ciphertext (i.e. opaque byte blobs). The encryption key is held by the application server, not the database. The following options to resolve this problem turned out to be infeasible: * **Decrypt everything in Python and filter**: The application has to fetch and decrypt every finding in every project on every search request. With thousands of projects this is slow and resource-intensive. * **Disable encryption for project data**: This defeats the purpose of encryption. * **Store a plaintext search index separately**: Storing plaintext alongside ciphertext eliminates the security benefits of encryption. An attacker with database access would be able to read the index and reconstruct plaintext data. The solution has to let the database do the filtering without ever seeing the plaintext content. ## Blind trigram index SysReptor uses a *blind trigram index*: the database stores a set of opaque tokens per project, derived from the project's text contents. A search term is converted to tokens the same way, and the database matches projects by comparing token sets. The database stores only encrypted data and the blind index but never plaintext data. ### Trigrams A trigram is a set of three consecutive characters. The word `"pentest"` produces the trigrams `pen`, `ent`, `nte`, `tes`, `est`. PostgreSQL's `pg_trgm` extension uses the same idea: if a search term occurs in a document, every trigram of that search term must also occur in the document. Containment over the set of trigrams is an efficient way to filter matches. ### HMAC-based blinding Each trigram is *blinded* by passing it through HMAC-SHA256, keyed with the application's encryption key: ``` token = HMAC-SHA256(key, "sysreptor|blind_trigram|v1|" + trigram_bytes)[:16] ``` Only those 16-byte tokens are stored, not the trigrams themselves. * Tokens are deterministic. The same trigram always produces the same token under the same key, so equality lookups work. * Without the key, tokens are indistinguishable from random bytes. A read-only attacker on the database cannot reverse a token back to its trigram. * 128 bits is enough that token collisions between distinct trigrams are negligible. The HMAC is keyed with the **same application secret** that encrypts the stored field blobs. That is a deliberate design choice, not an accident: anyone who can derive meaningful probes from the tokens already holds the key needed to decrypt the ciphertext directly, so the blind index does not introduce a weaker path than “the encryption key is compromised.” ## Indexing An asynchronous background task runs regularly and rebuilds the blind trigram index for any project whose content has changed since the last run. For each project, the process is: 1. **Collect text**: Every string field in every finding and section is extracted. 2. **Normalize**: Strings are Unicode-normalized, case-folded, and whitespace-collapsed, which makes search case- and accent-insensitive. 3. **Compute trigrams**: Normalized text is encoded as UTF-8 and split into sliding 3-byte windows. Trigrams are deduplicated across the project. 4. **Blind**: Each unique trigram becomes a 16-byte token via the HMAC above. 5. **Store**: All tokens are stored in the `BlindTrigramToken` table, one row per unique token, replacing any previous tokens for that project. ## Search A search term goes through the same normalization and trigram split as during indexing. Each trigram is HMAC'd, and a project is considered a content match if its token set contains every token derived from the term. This is the same containment check `pg_trgm` performs over plaintext. Search terms shorter than three characters skip the trigram lookup entirely. A 3-character term produces exactly one trigram; anything shorter has none. ## Key rotation The HMAC key follows the application's `DEFAULT_ENCRYPTION_KEY_ID`. SysReptor allows multiple encryption keys to be configured at once, so older data can still be decrypted while new data is written under a fresh key. At search time, the term is hashed under every currently configured key, and rows matching any of them count as hits. A project that was indexed under an old key therefore remains searchable; the background task picks it up and rebuilds the index under the new key on its next pass. ## Security properties and limitations **What it protects against**: The blind index protects against read-only attackers with database access. They see 128-bit tokens that look random; without the HMAC key, recovering the underlying trigrams (or plaintext) is not feasible. **Frequency analysis**: The HMAC key is shared across all projects, so the same trigram always hashes to the same token. An attacker with database access can identify projects that share tokens. They do not recover any plaintext, but they do learn which projects have content in common. **Dictionary attacks**: With the application encryption key, an attacker can derive tokens for guessed terms (e.g. a CVE id) and query the index for matches. The HMAC uses that same key as the ciphertext, so the capability is not separate from key compromise: whoever can run this probe can decrypt field data directly. A read-only database attacker without the key cannot. **False positives**: A project that contains every trigram of a search term scattered across different words, but not the term itself, will still match. The effect is small for longer terms and is the same trade-off `pg_trgm` makes. **Index lag**: The index is rebuilt asynchronously, so a project that was just edited may not be findable under its new content for a few minutes. --- --- url: https://docs.sysreptor.com/insights/security-considerations.md --- # Security Considerations ## Template Injection SysReptor uses server-side rendering for generating PDF reports. This allows template injection attackers. This is intentional. The template injection is sandboxed in a dedicated Chromium process. Chromium is running in offline mode. It has no possibility to connect to remote locations. It requires an exploit in the Chromium browser to get access to the container. ## Denial of Service (DoS) PDF rendering is a long-running and resource intensive process. Especially WeasyPrint can sometimes be slow when rendering long and complex reports. Attackers can inject long-running instructions (via Vue, HTML or CSS) in templates. This might cause DoS of the rendering process.\ A timeout cancels the Vue template rendering process as soon as rendering time reaches a certain threshold. DoS prevention is currently not implemented for WeasyPrint. For now, we accept the risk of DoS in WeasyPrint, since we do not want to prevent rendering long and complex reports which might take some time and system resources. This behavior might change in the future. ## Server-Side Request Forgery Prevention All Requests to external systems from within the rendering workflow are blocked. This prevents data exfiltration to external systems if attackers inject templates or if there are vulnerabilities in third-party JS libraries. This is ensured by two measures: 1. The headless Chromium instances uses the offline mode. This simulates that the browser is offline and blocks all outgoing requests. 2. For WeasyPrint, we use a custom URL fetcher. This prevents requests to external systems. It allows `data:`-URLs and access to files uploaded to SysReptor (designer assets, images) only. No HTTP requests are involved when including these resources (neither to localhost), but a custom handler that returns the resources as data following the [WeasyPrint security recommendations](https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#security). ::: info Discovered a security vulnerability?\ Report it responsibly through our vulnerability disclosure process. [Disclose responsibly](https://github.com/Syslifters/sysreptor/security) ::: --- --- url: https://docs.sysreptor.com/setup/plugins.md --- # Plugins SysReptor provides a plugin system to extend the functionality of the application without modifying the SysReptor core code. Plugins can hook into the SysReptor core and provide additional features both in the API and the web UI. The plugins `cyberchef`, `renderfindings`, and `scanimport` are enabled by default. All other plugins are disabled until you enable them. Enable or disable plugins in the application settings web interface (https://sysreptor.example.com/settings/) by ticking plugin enabled checkboxes. You can also enable plugins by setting [`ENABLED_PLUGINS`](/setup/configuration#plugins) in `app.env` (e.g. `ENABLED_PLUGINS=cyberchef,checkthehash`) and restarting your container (`docker compose up -d` from the `deploy` directory). If `ENABLED_PLUGINS` is set in `app.env`, it takes precedence and the Settings UI will be read-only for plugin enable/disable. ## Official Plugins Official plugins are maintained by the SysReptor team and are shipped inside official docker images. | Plugin | Description | | | ------ | ----------- | --- | | [cyberchef](https://github.com/Syslifters/sysreptor/tree/main/plugins/cyberchef) | CyberChef integration | | | [graphqlvoyager](https://github.com/Syslifters/sysreptor/tree/main/plugins/graphqlvoyager) | GraphQL Voyager integration | | | [checkthehash](https://github.com/Syslifters/sysreptor/tree/main/plugins/checkthehash) | Hash identifier | | | [customizetheme](https://github.com/Syslifters/sysreptor/tree/main/plugins/customizetheme) | Customize UI themes per instance | | | [demoplugin](https://github.com/Syslifters/sysreptor/tree/main/plugins/demoplugin) | A demo plugin that demonstrates the plugin system | | | [markdownexport](https://github.com/Syslifters/sysreptor/tree/main/plugins/markdownexport) | Export reports as Markdown documents in ZIP format | | | [projectnumber](https://github.com/Syslifters/sysreptor/tree/main/plugins/projectnumber) | Automatically adds an incremental project number to new projects | | | [webhooks](https://github.com/Syslifters/sysreptor/tree/main/plugins/webhooks) | Send webhooks on certain events | | | [renderfindings](https://github.com/Syslifters/sysreptor/tree/main/plugins/renderfindings) | Render selected findings to pdf | | | [rendersections](https://github.com/Syslifters/sysreptor/tree/main/plugins/rendersections) | Render single sections to PDF | | | [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) | Import scan results from various tools | | | [jira](https://github.com/Syslifters/sysreptor/tree/main/plugins/jira) | Export findings to Jira issues | | ## Developing Custom Plugins It is possible to develop and load custom plugins to extend the functionality of SysReptor. Custom plugins are only supported in self-hosted installations, but not in the cloud version. ### Getting Started We recommend to develop and manage custom plugins in a separate Git repository, not in the SysReptor repository. You can use our [example plugin repository](https://github.com/Syslifters/sysreptor-plugin-example) as a starting point. First, you need to set up a new repository (either on GitHub or your internal version control system) with a directory structure similar to: ``` plugin-repository ├── .gitignore ├── .dockerignogre ├── Dockerfile ├── sysreptor.docker-compose.override.yml ├── custom_plugins/ │ ├── myplugin1/ │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── models.py │ │ ├── urls.py │ │ ├── views.py │ │ ├── serializers.py │ │ ├── signals.py │ │ ├── ...other .py files │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── test_myplugin1.py │ │ ├── migrations/ │ │ │ ├── __init__.py │ │ │ └── ...auto-generated migrations │ │ └── static/ │ │ ├── plugin.js │ │ └── ...other HTML, CSS, JS assets │ ├── myplugin2/ │ │ └── ... │ └── ...additional plugins └── ...additional top-level files ``` We recommend to create a parent directory that contains all your custom plugins (e.g. `custom_plugins`). Plugin directories should contain a valid SysReptor plugin structure that can be loaded by the SysReptor core. Use [demoplugin](https://github.com/Syslifters/sysreptor/tree/main/plugins/demoplugin) as a starting point. ::: info Use a unique `plugin_id` and module name. When copying an existing plugin, make sure to change the module (plugin directory) name and to change the `plugin_id` in `apps.py`. ::: ### Plugin Loading Custom plugins need to be made available to the SysReptor docker container. This can be achieved by extending the SysReptor docker image and adding your custom plugins to the image. ```dockerfile title="Dockerfile example" ARG SYSREPTOR_VERSION="latest" # Optional build stage for frontend assets FROM node:24-alpine3.22 AS plugin-builder # Build frontend assets COPY custom_plugins /custom_plugins RUN cd /custom_plugins/myplugin1/frontend && npm install && npm run generate # Extend the Sysreptor image with custom plugins FROM syslifters/sysreptor:${SYSREPTOR_VERSION} # Optional: install additional dependencies # RUN pip install ... ENV PLUGIN_DIRS=${PLUGIN_DIRS},/custom_plugins COPY --from=plugin-builder /custom_plugins /custom_plugins ``` Use following code snippets to plug your extended docker image to the SysReptor docker-compose file: ::: info Directly modifying `sysreptor/deploy/sysreptor/docker-compose.yml` is not recommended, because changes might get overwritten during [updates](/setup/updates). The presented way is compatible with the `update.sh` script. ::: First, modify `sysreptor/deploy/docker-compose.yml` to add an include docker compose include file. ```yaml title="sysreptor/deploy/docker-compose.yml" name: sysreptor include: - path: - sysreptor/docker-compose.yml # Path to sysreptor.docker-compose.override.yml in your plugin repository # Note: Path is relative to sysreptor/deploy/docker-compose.yml (or an absolute path) - ../../plugin-repository/sysreptor.docker-compose.override.yml ``` The content of `../../plugin-repository/sysreptor.docker-compose.override.yml` is merged with the original `sysreptor/docker-compose.yml` (from SysReptor core) and allows extending or overriding docker compose configurations. See https://docs.docker.com/reference/compose-file/include/ for more information about docker compose includes. Then, override the `image` and `build` options in `sysreptor.docker-compose.override.yml` to use your extended SysReptor docker image with custom plugins included. Note that paths in this file are relative to the `sysreptor/deploy` directory (from SysReptor core docker compose file). ```yaml title="sysreptor.docker-compose.override.yml example" services: app: # Override the docker image image: !reset null build: # Note: Path is relative to sysreptor/deploy/docker-compose.yml (or an absolute path) context: ../../plugin-repository args: SYSREPTOR_VERSION: ${SYSREPTOR_VERSION:-latest} ``` ### Server-side Plugin SysReptor plugins are Django apps can hook into the SysReptor core and provide additional functionality. See the [Django documentation](https://docs.djangoproject.com/en/stable/ref/applications/) and [Django app tutorial](https://docs.djangoproject.com/en/stable/intro/tutorial01/) for more information about Django apps. Each plugin needs at least an `__init__.py` and `apps.py` file with a minimal plugin configuration. Use the [demoplugin](https://github.com/Syslifters/sysreptor/tree/main/plugins/demoplugin) as a starting point. ```py import logging # Import the necessary classes. # Official plugin APIs are provided by the "sysreptor.plugins" module. # Other "sysreptor.*" modules are considered internal and might change any time. It is still possible to use them, though. from sysreptor.plugins import FieldDefinition, PluginConfig, StringField, configuration log = logging.getLogger(__name__) class DemoPluginConfig(PluginConfig): """ This is a demo plugin that demonstrates the plugin system. Use this plugin as a reference to develop your own plugins. This doc string is used as the plugin description in the settings page. """ # When writing a new plugin, generate a new plugin ID via `python3 -m uuid` plugin_id = 'db365aa0-ed36-4e90-93b6-a28effc4ed47' configuration_definition = FieldDefinition(fields=[ StringField( id='PLUGIN_DEMOPLUGIN_SETTING', default='default value', help_text='Here you can define available plugin settings. ' 'Settings can be configured as environment variables or via the API (stored in database). ' 'It is recommended to follow the nameing convention "PLUGIN__".'), ]) def ready(self) -> None: # Perform plugin initialization # e.g. register signal handlers, do some monkey patching, etc. log.info('Loading DemoPlugin...') from . import signals # noqa def get_frontend_settings(self, request): # Pass settings to JavaScript frontend. # Use the value of the setting defined in configuration_definition. return { 'setting_value': configuration.PLUGIN_DEMOPLUGIN_SETTING, } ``` Besides `apps.py`, you can add arbitrary Python files to the plugin directory to structure your plugin code. We recommend to stick to the Django app structure: * `models.py` for database model classes * `migrations/` directory for database migrations * `admin.py` for Django admin configuration for your models * `urls.py` for URL routing: URLs in variable `urlpatterns` are registered at `/api/plugins//api/...` * `views.py` for API views e.g. [Django REST framework](https://www.django-rest-framework.org/) viewsets * `serializers.py` for Django REST framework serializers * `signals.py` for signal handlers listening to Django or SysReptor signals * `static/` directory for static assets (e.g. JS, CSS, images): served at `/static/plugins//...` * `plugin.js` is the entrypoint for frontend plugins * `tests/` directory for unit tests (highly recommended) #### Python Imports and Dependencies You are able to import and reuse modules from SysReptor core as well as other third-party libraries that are installed in the server's python environment (e.g. django). Please note that the SysReptor core and third-party libraries are subject to change and updates, so be aware of potential breaking changes when importing internal modules. In order to detect breaking changes early, we recommend writing [unit tests](#testing) for your plugin code. When importing modules from your own plugin, prefer relative imports over absolute imports. ```python title="imports example" # Prefer relative imports from .models import DemoPluginModel # over absolute imports from sysreptor_plugins.demoplugin.models import DemoPluginModel ``` Plugins are able to reuse existing third-party libraries that are installed in the server's python environment. If you need to install additional dependencies, you need to extend the `Dockerfile` and install the dependencies via `pip`. #### Database models If your plugin needs to store data in the database, you can define Django models in `models.py`. You also need to create database migrations for your models to create/update the database schema. SysReptor automatically applies plugin migrations on startup if the plugin is enabled and also includes plugin models in [backups and restores](/setup/backups). Here are the basic steps to create a Django models: * Define your django model classes in `models.py` * Create a `migrations/` directory and `migrations/__init__.py` file * Ensure your plugin is loaded and enabled * Run `docker compose run --rm app python3 manage.py makemigrations` to create the initial migration files * Run `docker compose run --rm api python3 manage.py migrate` to apply the migrations See the Django documentation for more information: * https://docs.djangoproject.com/en/stable/topics/db/models/ * https://docs.djangoproject.com/en/stable/topics/migrations/ #### API Endpoints You can define API endpoints in your plugin by defining API views in `views.py` and registering them in URL patterns to `urls.py`. ```py from django.http import HttpResponse from django.urls import include, path from rest_framework.routers import DefaultRouter from .consumers import DemoPluginConsumer from .views import DemoPluginModelViewSet router = DefaultRouter() router.register('demopluginmodels', DemoPluginModelViewSet, basename='demopluginmodel') """ API endpoints defined by plugin. Accessible at /api/plugins//api/... """ urlpatterns = [ path('helloworld/', lambda *args, **kwargs: HttpResponse("Hello world", content_type="text/plain"), name='helloworld'), path('', include(router.urls)), ] """ WebSocket consumers defined by plugin. Accessible at /api/plugins//ws/... """ websocket_urlpatterns = [ path('projects//hellowebsocket/', DemoPluginConsumer.as_asgi(), name='hellowebsocket'), ] ``` API views can be implemented as Django views or [Django REST framework](https://www.django-rest-framework.org/) viewsets. ```py from rest_framework import viewsets from .models import DemoPluginModel from .serializers import DemoPluginModelSerializer class DemoPluginModelViewSet(viewsets.ModelViewSet): """ API viewset for DemoPluginModel providing CRUD operations. See https://www.django-rest-framework.org/api-guide/viewsets/ """ queryset = DemoPluginModel.objects.all() serializer_class = DemoPluginModelSerializer ``` Django REST framework uses serializers to serialize and deserialize data between Python objects and JSON. Define your serializers in `serializers.py`. ```py from rest_framework import serializers from .models import DemoPluginModel class DemoPluginModelSerializer(serializers.ModelSerializer): """ Serializers specify how to convert model instances into JSON and vice versa. See: https://www.django-rest-framework.org/api-guide/serializers/ https://www.django-rest-framework.org/api-guide/fields/ """ class Meta: model = DemoPluginModel fields = ['id', 'created', 'updated', 'name'] ``` #### Signals Plugins can listen to [Django signals](https://docs.djangoproject.com/en/stable/topics/signals/) to react to certain events in the SysReptor core. SysReptor provides additional signals that are not part of Django in the `sysreptor.signals` module. Signal handlers should be defined in your plugin's `signals.py` file. In order to load the signal handlers, you need to register them in the `ready()` method of your plugin's `apps.py`. ```python title="apps.py example" class DemoPluginConfig(PluginConfig): def ready(self): from . import signals # noqa ``` ```py import logging from django.dispatch import receiver from sysreptor.pentests.models import PentestProject from sysreptor import signals as sysreptor_signals log = logging.getLogger(__name__) # Register django signal handlers # https://docs.djangoproject.com/en/stable/topics/signals/ @receiver(sysreptor_signals.post_update, sender=PentestProject) def on_project_updated(sender, instance, changed_fields, *args, **kwargs): """ Signal handler for project save event. """ if 'name' in changed_fields: old_name, new_name = instance.get_field_diff('name') log.info(f'Someone renamed project "{old_name}" to "{new_name}"') ``` #### Testing We highly recommend writing unit tests for your plugins. Unit tests ensure that * your plugins work as expected and help in detecting breaking changes early * detect when updates of SysReptor core break your plugins * detect when your plugins break SysReptor core (especially when using signal handlers) Unit tests should be placed in the `tests/` directory of your plugin. [`pytest`](https://docs.pytest.org/en/stable/) and [`pytest-django`](https://pytest-django.readthedocs.io/en/latest/) are available in the SysReptor container and can be used to run your tests. ```py """ Unit tests for plugin functionality. To run this test, execute the following command: cd sysreptor/dev docker compose run --rm -e ENABLED_PLUGINS=demoplugin api pytest --pyargs sysreptor_plugins.demoplugin """ import pytest from django.urls import reverse from sysreptor.tests.mock import ( api_client, create_user, ) from ..apps import DemoPluginConfig from ..models import DemoPluginModel PLUGIN_ID = DemoPluginConfig.plugin_id URL_NAMESPACE = DemoPluginConfig.label @pytest.mark.django_db() class TestDemoPluginApi: @pytest.fixture(autouse=True) def setUp(self): self.user = create_user() self.client = api_client(self.user) self.demopluginmodel = DemoPluginModel.objects.create(name='Test') def test_retrieve(self): res = self.client.get(reverse(URL_NAMESPACE + ':demopluginmodel-detail', kwargs={'pk': self.demopluginmodel.id})) assert res.status_code == 200 assert res.data['id'] == str(self.demopluginmodel.id) assert res.data['name'] == self.demopluginmodel.name def test_create(self): res = self.client.post(reverse(URL_NAMESPACE + ':demopluginmodel-list'), data={'name': 'New'}) assert res.status_code == 201 obj = DemoPluginModel.objects.get(id=res.data['id']) assert obj.name == 'New' def test_update(self): res = self.client.patch(reverse(URL_NAMESPACE + ':demopluginmodel-detail', kwargs={'pk': self.demopluginmodel.id}), data={'name': 'Updated'}) assert res.status_code == 200 self.demopluginmodel.refresh_from_db() assert self.demopluginmodel.name == 'Updated' def test_delete(self): res = self.client.delete(reverse(URL_NAMESPACE + ':demopluginmodel-detail', kwargs={'pk': self.demopluginmodel.id})) assert res.status_code == 204 assert not DemoPluginModel.objects.filter(id=self.demopluginmodel.id).exists() ``` Run unit tests: ```shell # Test a single plugin docker compose run --rm -e ENABLED_PLUGINS=demoplugin app pytest --pyargs sysreptor_plugins.demoplugin # Test all plugins docker compose run --rm app pytest --pyargs sysreptor_plugins # Run all tests (core + all plugins) docker compose run --rm app pytest -n auto ``` ### Frontend Plugin Frontend plugins hook into the SysReptor web UI (single page application) and can register new menu entries and pages. #### Frontend Plugin Entrypoint Frontend plugins are loaded from the `/static/` directory and need to provide pre-built assets. The entrypoint for frontend plugins is `plugin.js` in the `static/` directory. `plugin.js` should perform setup actions for the frontend plugin, e.g. registering new menu entries and pages. ```js /** * This is the plugin frontend entry point. * It is called once while loading the single page application in the client's browser. * Register plugin routes here and perform initializations. */ export default function (options) { // Register a new route and add it to the main menu options.pluginHelpers.addRoute({ scope: 'main', route: { // Relative path, prefixed with "/plugins//" path: 'demopluginmodels', // Load frontend pages in iframe component: () => options.pluginHelpers.iframeComponent({ // Relative path to "/static/plugins//" => load "index.html" from the plugin's static directory src: 'index.html#/demopluginmodels', }), }, menu: { title: 'Demo Plugin', } }); // Register a sub-page options.pluginHelpers.addRoute({ scope: 'main', route: { // Add a path parameter "demopluginmodelId" to the route path: 'demopluginmodels/:demopluginmodelId()', // and pass it to the iframe URL component: () => options.pluginHelpers.iframeComponent(({ route }) => ({ src: `index.html#/demopluginmodels/${route.params.demopluginmodelId}` })), }, menu: undefined, // Do not add this route to the main menu }); // Register a per-project route and add it to the project menu options.pluginHelpers.addRoute({ scope: 'project', route: { // Prefixed with /projects//plugins// path: '', component: () => options.pluginHelpers.iframeComponent(({ route }) => ({ src: `index.html#/projects/${route.params.projectId}/`, })) }, menu: { title: 'Demo Plugin', }, }); } ``` Plugins can register new pages in the SysReptor web UI via `options.pluginHelpers.addRoute()`. Pages are loaded in `iframes` to provide the most flexibility for loaded content. HTML files loaded as `iframes` as well as any other assets (e.g. JS, CSS, images) should be placed in the `static/` directory. The SysReptor web application uses session cookies for authentication, so you are able to access the SysReptor API from within plugin `iframes`. #### Vue/Nuxt Pages SysReptor provides some Vue/Nuxt UI components to be reused in plugins to ensure a consistent look and feel. For that, you need to introduce an additional build step to compile your Vue/Nuxt pages into static assets that can be loaded in `iframes`. We recommend to place your Vue/Nuxt code in the `frontend/` directory of your plugin and write output files to the `static/` directory. SysReptor provides the [Nuxt Layer](https://nuxt.com/docs/getting-started/layers) `plugin-base-layer`. This layer contains basic plugin configurations and UI components that can be used in plugins. The source code of this layer is located in the main SysReptor repository and needs to be included during the build step (e.g. via git submodule). See https://github.com/Syslifters/sysreptor-plugin-example/tree/main/custom\_plugins/myplugin1/frontend for an example setup. To build the frontend assets, you need to run the following commands: ```shell cd demoplugin/frontend # Install JS dependencies npm install # Build the frontend assets npm run generate ``` Here are some notes to get you started: * See the [Nuxt documentation](https://nuxt.com/) for the basic setup and configuration * URLs to other SysReptor pages (also from the same plugin): * use full paths with plugin ID * e.g. `/plugins/${pluginId}/...` or `/projects/${projectId}/plugins/${pluginId}/...` * navigate to other SysReptor pages: * from inside plugin `iframes` you need to perform a top-level navigation to not load the page inside the `iframe` * set `` or use `await navigateTo(..., { open: { target: "_top" } })` * fetch data from plugin API: * use full URLs with plugin ID * e.g. `/api/plugins/${pluginId}/api/...` * importing components: * components (from nuxt-base-layer and local component) are auto-imported * if you want to import them explicitely use `import { ... } from '#components'` * composables, utilities, etc. (from nuxt-base-layer and local) can be imported via `import { ... } from '#imports'` ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/demo-reports.md --- # Reports created with SysReptor ❤️ ## Company Demo Reports ## Certifications ## Demo Reports [Download Demo designs](/assets/demo-designs.tar.gz) ::: info Post your report design (PDF and/or exported design) and we'll add it to our page (if desired).\ We'll happily provide a backlink to your website. [Show & Tell](https://github.com/Syslifters/sysreptor/discussions/20) ::: --- --- url: https://docs.sysreptor.com/get-involved.md --- # Contribute to SysReptor We're glad you're here to contribute and to make pentest reporting even easier. Thank you for investing your time. ❤️ We've created a some suggestions how you could help us improving SysReptor and everything around it. ::: info Share your knowledge by creating videos, writing tutorials and guides to help others. We'll help you spreading the word. [Show & Tell](https://github.com/Syslifters/sysreptor/discussions/categories/show-and-tell#discussions-list) ::: ::: info Design beautiful and professional report templates for the SysReptor community. [Show & Tell](https://github.com/Syslifters/sysreptor/discussions/20) ::: ::: info Build integrations and connectors to bridge SysReptor with your existing security tools. [Check out the Python integration](/python-library/tutorial/part-1/projects) ::: ::: info Extend SysReptor's functionality by developing plugins that add new features and capabilities. [Create a plugin](/setup/plugins) ::: ::: info Help fellow users by sharing your expertise and answering questions in the community. [Join discussions](https://github.com/Syslifters/sysreptor/discussions#discussions-list) ::: ::: info Fix bugs, implement new features, or improve existing functionality by contributing directly to SysReptor. [Contributing guidelines](https://github.com/Syslifters/sysreptor/blob/main/CONTRIBUTING.md) ::: We'll try to help you spreading your contributions. Please [contact us](/contact-us#get-support-report-issues) if you have questions. --- --- url: https://docs.sysreptor.com/faq/exam-reports.md --- # FAQs for students writing exam reports These FAQs are for students who write Hack The Box, OffSec, and other certification exam reports in the free SysReptor Labs at [labs.sysre.pt](https://labs.sysre.pt). If you run SysReptor on your own server, see the [self-hosted FAQs](/faq/self-hosted). For SysReptor Cloud, see the [cloud FAQs](/faq/cloud). ::: details What is SysReptor Labs at labs.sysre.pt? [labs.sysre.pt](https://labs.sysre.pt) is SysReptor’s free cloud for writing certification exam reports. You write the report in Markdown and render it as PDF. It includes pro features and no self-hosted setup is required. It is not the same as [SysReptor Cloud](/faq/cloud) or a [self-hosted](/faq/self-hosted) SysReptor instance. Even though the functionality largely corresponds to SysReptor Professional, some functionalities are limited: You don't receive superuser permissions, collaboration with other users is restricted, you cannot edit global designs. ::: ::: details Where do I register for HTB, OffSec, or other certification reporting in SysReptor? Register for the free SysReptor Labs with the signup page for your certification provider: * Hack The Box: [htb.sysreptor.com/htb/signup/](https://htb.sysreptor.com/htb/signup/) * OffSec (including OSCP+): [offsec.sysreptor.com/offsec/signup/](https://offsec.sysreptor.com/offsec/signup/) For other certifications or projects, sign up at any of the two links. You can create or import SysReptor designs as private designs in your user account. Depending on the registration link, your user will receive HTB or Offsec demo reports imported by default. The platform and user capabilities are the same for both links. After signup, log in at [labs.sysre.pt](https://labs.sysre.pt). ::: ::: details Where do I log in to write HTB or OffSec exam reports in SysReptor? Log in to SysReptor Labs at [labs.sysre.pt](https://labs.sysre.pt). Signup is separate from login: * HTB signup: [htb.sysreptor.com/htb/signup/](https://htb.sysreptor.com/htb/signup/) * OffSec signup: [offsec.sysreptor.com/offsec/signup/](https://offsec.sysreptor.com/offsec/signup/) ::: ::: details Which certifications does the free SysReptor Labs support? We currently provide the following report designs: * **Hack The Box:** CPTS, CWES, CDSA, CWEE, CAPE, CJCA, CWPE, COAE * **OffSec:** OSCP+, OSEP, OSWP, OSWA, OSWE, OSED, OSMR, OSEE, OSDA, OSIR, OSTH, OSAI Demo PDFs and designs are listed on [HTB reporting](/htb-reporting-with-sysreptor), [OffSec reporting](/offsec-reporting-with-sysreptor), and [demo reports](/demo-reports). You can import any other design as private design. ::: ::: details Is SysReptor Labs free? Yes. SysReptor Labs at [labs.sysre.pt](https://labs.sysre.pt) is free for writing certification exam reports. It includes Pro features and does not require a SysReptor Professional license.\ There is no limit in the number of reports or projects you can create. We don't recommend using SysReptor Labs for commercial pentesting reports. We don't guarantee the same level of confidentiality and availability as in SysReptor Cloud, and there is no legal basis for data processing. ::: ::: details I signed up for writing exam reports at labs.sysre.pt. When will you delete my data? SysReptor Labs accounts and exam report data at [labs.sysre.pt](https://labs.sysre.pt) are **deleted after three months without login**. Export your reports before that (PDF and/or project export) if you need to keep a copy. We'll send you a warning a few days before account deletion. ::: ::: details Can I create a backup of my SysReptor exam reports on labs.sysre.pt? You can keep copies of your work: 1. **Download the PDF** from the project’s publish page (the rendered exam report). 2. **Export the project** from the projects list (`.tar.gz` archive). That archive can be imported into other SysReptor installations later. Do this before the account is deleted after three months without login. ::: ::: details I cannot log into my labs.sysre.pt account. What should I do? If you cannot log into SysReptor at [labs.sysre.pt](https://labs.sysre.pt): * Confirm you are on [labs.sysre.pt](https://labs.sysre.pt). * Use [Forgot Password](https://labs.sysre.pt/login/forgot-password/) function and check the email address of your labs account (including spam). If you had an account previously, your account might have been deleted if you haven't logged in for more than 3 months. ::: ::: details Can I self-host SysReptor instead of using SysReptor Labs for exam reports? Yes. You can [install SysReptor](/setup/installation) on your own server and import the official HTB or OffSec designs. See [how to import HTB or OffSec designs](#import-cert-designs). ::: ::: details How do I get HTB or OffSec report designs into a self-hosted SysReptor? Import Hack The Box designs and demo projects: ```shell cd sysreptor/deploy curl -s "https://docs.sysreptor.com/assets/htb-designs.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=design curl -s "https://docs.sysreptor.com/assets/htb-demo-projects.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=project ``` Import OffSec designs and demo projects: ```shell cd sysreptor/deploy curl -s "https://docs.sysreptor.com/assets/offsec-designs.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=design curl -s "https://docs.sysreptor.com/assets/offsec-demo-projects.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=project ``` Find more details at [HTB reporting](/htb-reporting-with-sysreptor) and [OffSec reporting](/offsec-reporting-with-sysreptor). ::: ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/faq/self-hosted.md --- # FAQs for self-hosted SysReptor These FAQs are for operators who install SysReptor with Docker on their own server. Students writing HTB or OffSec exam reports on [labs.sysre.pt](https://labs.sysre.pt) should use the [exam report FAQs](/faq/exam-reports). SysReptor Cloud is covered in the [cloud FAQs](/faq/cloud). ::: details Can I install SysReptor on macOS or Linux distributions like Kali, Fedora, RHEL? Even though we officially support **Ubuntu** only, installation is technically possible on most UNIX-based target systems including Kali, Fedora, macOS or RHEL. The installation of dependencies (like docker, sed, curl, openssl, uuid-runtime, coreutils, cron; some of them are optional) might vary from system to system. Follow the steps for [manual installations](/setup/installation#manual-installation) and adapt the commands according to your system. If all dependencies are installed and are ready to use, [easy script installation](/setup/installation#easy-script-installation) might also work. ::: ::: details Can I install SysReptor on Windows? The easiest approach on Windows is to install SysReptor in [Windows Subsystem for Linux 2](https://learn.microsoft.com/en-us/windows/wsl/install) (WSL 2) with an Ubuntu distribution. Make sure to install Docker Desktop with WSL 2 and to enable integration of Docker with WSL (in Docker Desktop go to **Settings → Resources → WSL Integration → Enable integration with my default WSL distro**). ::: ::: details What are the SysReptor system requirements for a self-hosted install? For a self-hosted SysReptor server, the requirements are Ubuntu and 8 GB RAM. The application runs in Docker. Details and client browser requirements are in [Installation](/setup/installation). ::: ::: details What is the SysReptor default password? SysReptor has **no fixed default password**. * The [install script](/setup/installation) creates a superuser named `reptor` and prints a **random password once**. Store it when it is shown; it is not saved in the docs or in a default config file. * A [manual install](/setup/installation) uses `createsuperuser`, so you choose the username and password yourself. If you lost the password, reset it from the CLI. From `sysreptor/deploy` run: ```shell docker compose exec app python3 manage.py changepassword "" ``` Use the username from install (`reptor` if you used the install script). The command prompts twice for a new password, then updates that user. You can log in with the new password immediately. If no user was created yet, create a superuser from the same directory: ```shell docker compose exec app python3 manage.py createsuperuser --username "" ``` The command prompts twice for a password. You can log in with that username and password immediately. ::: ::: details How do I cleanly uninstall SysReptor and delete all data? To uninstall a self-hosted SysReptor and delete all data (database and uploaded files), remove the Docker containers, named volumes, and the install directory. From the `sysreptor/deploy` directory, stop the stack, then delete containers and volumes: ```shell cd sysreptor/deploy docker compose down docker rm -f sysreptor-app sysreptor-db docker volume rm -f sysreptor-app-data sysreptor-db-data ``` If you used Caddy from the bundled compose file, also remove `sysreptor-caddy-data`. Then delete the `sysreptor` directory on disk. This cannot be undone. Create a [backup](/setup/backups) first if you might need the data. To stop SysReptor **without** deleting data, see [How do I stop SysReptor without deleting data?](#stop-without-deleting). ::: ::: details How do I stop SysReptor without deleting data? To stop a self-hosted SysReptor without deleting volumes or files, go to `sysreptor/deploy` and run: ```shell docker compose stop ``` Your database and uploaded files stay in the Docker volumes.\ To start again: `docker compose up -d`. ::: ::: details How do I verify the integrity of a SysReptor installation? Verify Docker images or the release archive (`setup.tar.gz`) with [cosign](https://docs.sigstore.dev/cosign/system_config/installation/). The SysReptor public key is . ```shell SYSREPTOR_VERSION=$(cat sysreptor/deploy/.env | grep 'SYSREPTOR_VERSION=' | cut -d'=' -f2-) # SYSREPTOR_VERSION=$(docker exec -it sysreptor-app bash -c 'echo "$VERSION"') # Verify docker images cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor:${SYSREPTOR_VERSION}" cosign verify --key https://docs.sysreptor.com/cosign.pub "syslifters/sysreptor-languagetool:${SYSREPTOR_VERSION}" # Pro only # Verify setup.tar.gz curl -s -L --output sysreptor.tar.gz.sigstore.json https://github.com/Syslifters/sysreptor/releases/download/${SYSREPTOR_VERSION}/setup.tar.gz.sigstore.json cosign verify-blob sysreptor.tar.gz --key https://docs.sysreptor.com/cosign.pub --bundle sysreptor.tar.gz.sigstore.json ``` `verify-blob` needs the local `sysreptor.tar.gz` you downloaded from GitHub Releases. The same steps are in [Installation](/setup/installation) and [Updates](/setup/updates). ::: ::: details How do I update a self-hosted SysReptor? Update a self-hosted SysReptor with the bundled script (recommended): ```shell bash sysreptor/update.sh ``` Professional installations can add `--backup` to create a backup before the update. Full steps, manual updates, and image verification are in [Updates](/setup/updates). Create a [backup](/setup/backups) before updating. ::: ::: details How do I back up and restore a self-hosted SysReptor instance? On a self-hosted SysReptor you can back up via CLI, and (with Professional, a superuser, and [`BACKUP_KEY`](/setup/configuration#backup-key)) via the web UI or API. The archive contains all data from your installation, including users, projects, templates, designs, assets, settings, the database export and uploaded files. CLI example from `sysreptor/deploy`: ```shell docker compose run --rm app python3 manage.py backup > backup.zip ``` Restore deletes existing data in the database and file storage. Use the same SysReptor version. Full commands: [Backups](/setup/backups#restore-backups). ::: ::: details How do I add a SysReptor Professional license to a self-hosted install? Add your license key to `deploy/app.env` as `LICENSE='your_license_key'`, include the LanguageTool compose file if needed, and run `docker compose up -d` from `deploy`. You do not need to reinstall. No data is lost during the transition from Community to Professional or vice versa. See [Upgrade to Professional](/setup/upgrade-to-professional) for more details. ::: ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/faq/cloud.md --- # FAQs for SysReptor Cloud These FAQs are for **SysReptor Cloud** (hosted by Syslifters for organizations). If you write **HTB, OffSec, or other exam reports** on [labs.sysre.pt](https://labs.sysre.pt), use the [exam report FAQs](/faq/exam-reports) instead. Self-hosted Docker installs are covered in the [self-hosted FAQs](/faq/self-hosted). ::: details What is SysReptor Cloud compared to self-hosted SysReptor and labs.sysre.pt? There are three common ways to use SysReptor: * **Self-hosted:** you install SysReptor with Docker on your own server. Self-hosted can be SysReptor Community (free) or SysReptor Professional (paid). See [Installation](/setup/installation), [pricing](https://sysreptor.com/pricing) and [self-hosted FAQs](/faq/self-hosted). * **SysReptor Cloud:** Syslifters hosts SysReptor Professional for your organization (paid). See [pricing](https://sysreptor.com/pricing). * **SysReptor Labs:** the free exam-reporting service at [labs.sysre.pt](https://labs.sysre.pt) hosted in the SysReptor Cloud for students writing certification and exam reports. See the [exam report FAQs](/faq/exam-reports). The [public playground](https://sysreptor.com/demo) is a demo installation hosted in the SysReptor Cloud. ::: ::: details Is SysReptor Cloud free? SysReptor Cloud is a paid hosted offering. See [pricing](https://sysreptor.com/pricing). **SysReptor Labs** at [labs.sysre.pt](https://labs.sysre.pt) for HTB/OffSec students is free; that is a non-commercial service. ::: ::: details Where is SysReptor Cloud hosted? SysReptor Cloud currently runs in **Germany** on physical servers at [Hetzner Online GmbH](https://www.hetzner.com/). We operate a self-managed Kubernetes cluster there on physical servers.\ We guarantee that if new sites are added in the future, their location will be within the European Union (EU). ::: ::: details What data privacy laws apply? Personal data in Cloud is processed under the **GDPR**. The Cloud contract is governed by Austrian law. ::: ::: details Can I have a signed DPA (AVV)? Yes. Please [contact us](/contact-us#contact-information). ::: ::: details Does any Cloud customer data leave the EU/EEA? No. ::: ::: details Is data encrypted in transit and at rest? Yes. Data in transit is encrypted with **HTTPS**. At rest, all data is stored on an encrypted **ZFS** partition. In addition, every Cloud installation has its own encryption key for database and file/asset encryption. See [Data Encryption at Rest](/setup/configuration#data-encryption-at-rest). ::: ::: details Are Cloud tenants isolated from each other? Yes. Each customer runs in a dedicated Kubernetes namespace with network separation. Each installation uses its own encryption keys. PDF rendering pods are shared, but each pod is disposed after one use so rendering jobs cannot interfere with another customer. See [Architecture](/insights/architecture). ::: ::: details Does SysReptor send report contents to third parties, e.g., for spell check or AI? No. Spell check runs inside your Cloud installation ([LanguageTool](/reporting/spell-check)). Report content is sent to an LLM only if you [configure an AI provider](/reporting/ai-agent) in settings. ::: ::: details Do you use my reports to train AI models? No. ::: ::: details Can I use my own domain name for hosting? Yes. Please [contact us](/contact-us#contact-information). ::: ::: details Can I require SSO (OIDC) and disable password login? Yes. Superusers can enable [OIDC SSO](/users/oidc-setup) and disable username/password login in **Settings → Authentication Settings** (`LOCAL_USER_AUTH_ENABLED=false`). See [SSO configuration](/setup/configuration#single-sign-on-sso).\ You can disable local user authentication for the entire installation, or on a per-user basis. ::: ::: details Can I install plugins on SysReptor Cloud? Yes. [Official plugins](/setup/plugins#official-plugins) that ship with SysReptor can be enabled in settings. **Custom plugins** are only supported in self-hosted SysReptor, not in the cloud version. ::: ::: details Can Cloud users use the reptor CLI? Yes. Create an API token in your user profile and configure `reptor` with your Cloud URL. See the [`reptor` CLI documentation](/cli/getting-started). ::: ::: details How do I reset my password on SysReptor Cloud? Administrators with superuser or user manager permissions can reset user passwords in the Users UI. See the [full steps](/users/forgot-password#reset-password-via-user-admin-interface). If your cloud installation has the **Forgot Password** functionality enabled, you can use it to receive an email for setting a new password. You will still need your second authentication factor, if configured for your user account to successfully authenticate. Students on SysReptor Labs can [reset their password](https://labs.sysre.pt/login/forgot-password/) online. ::: ::: details Can I create backups of a SysReptor Cloud instance? Yes. You can [create a backup via web interface](/setup/backups#create-backups-via-web-interface) with your SysReptor installation's [`BACKUP_KEY`](/setup/configuration#backup-key) and you must have **superuser** permissions. Please [contact us](/contact-us#contact-information) to receive your `BACKUP_KEY`. You can always **export individual projects** as `.tar.gz` from the projects list. This is not a full instance backup. ::: ::: details Where are backups stored? On our own servers in Austria. Each backup is encrypted with a dedicated symmetric key. That key is encrypted with an asymmetric key. Private keys for recovering the symmetric encryption keys are stored on hardware tokens with PIN protection. ::: ::: details How long are backups stored? * **Daily backups:** 21 days * **Weekly backups:** 35 days * **Monthly backups:** 365 days ::: ::: details Can you delete my instance and confirm it? Yes. Please [contact us](/contact-us#contact-information). We can delete your Cloud instance and confirm the deletion. ::: ::: details Can I migrate from SysReptor Cloud to a self-hosted SysReptor? Yes, you can [create a backup](/setup/backups#create-backups-via-web-interface) and restore it on a self-hosted SysReptor installation. You can also move project data by **exporting projects** from Cloud (projects list → export `.tar.gz`) and **importing** them on a [self-hosted](/setup/installation) instance. ::: ::: details Can I migrate from a self-hosted SysReptor to SysReptor Cloud? Yes, you can [create a backup](/setup/backups) and [contact us](/contact-us#contact-information) to restore it on a SysReptor Cloud installation. You can also move project data by **exporting projects** from self-hosted (projects list → export `.tar.gz`) and **importing** them on Cloud. ::: ::: details Is there a track record for SysReptor Cloud's availability? Yes. See the [SysReptor Cloud status page](https://status.sysreptor.com/). ::: ::: details What is the maintenance window? Wednesdays and Saturdays, 08:00–11:00 GMT. Planned maintenance is also announced on the [SysReptor Cloud status page](https://status.sysreptor.com/). You can subscribe there for updates. ::: ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/faq/application.md --- # FAQs for using SysReptor These FAQs cover the SysReptor application itself: writing reports, designs, API, MFA, and licensing. They apply to self-hosted, Cloud, and SysReptor Labs. Designer HTML/CSS snippets are in the [report design FAQs](/designer/faqs). Install and ops questions are in [self-hosted](/faq/self-hosted) or [cloud](/faq/cloud). Exam students: [exam report FAQs](/faq/exam-reports). ::: details What is your release cycle? We aim to release **every two weeks**, usually on **Wednesdays**. Releases include new features, improvements, and bug fixes. The schedule is not fixed. We ship sooner for urgent bugs or security issues, and later when a change needs more testing. Releases can also land on another weekday. ::: ::: details Where can I find the SysReptor changelog? Find out changelog on [GitHub](https://github.com/syslifters/sysreptor/releases).\ SysReptor installations with outbound connection to the Internet also receive update notifications with links to the latest release and changelog. ::: ::: details Do you have a vulnerability disclosure process? Yes. See the [Syslifters vulnerability disclosure policy](https://handbook.syslifters.com/vulnerability-disclosure). ::: ::: details Can I export a SysReptor report as DOCX? No. SysReptor does **not** export Microsoft Word (`.docx`) files. SysReptor renders pentest reports as **PDF** from the project’s publish page. You can also: * **Export a project** as a SysReptor `.tar.gz` archive (for backup or import into another instance) * On **self-hosted** SysReptor, enable the [markdownexport](https://github.com/Syslifters/sysreptor/tree/main/plugins/markdownexport) plugin to export Markdown in a ZIP ::: ::: details Where can I find the SysReptor API documentation? SysReptor’s HTTP API is documented in the [**Swagger UI**](https://demo.sysre.pt/api/public/utils/swagger-ui/) on each instance. For scripting and automation, we recommend the [`reptor` Python library](/python-library/) or the [`reptor` CLI](/cli/getting-started) instead of calling the HTTP API directly. ::: ::: details Why do I have no permissions in the SysReptor report designer? Editing **global** report designs requires the **Designer** permission. Users without it cannot change shared designs used by others. Without Designer permission you still have read access to non-private designs. If [private designs](/setup/configuration#private-designs) are enabled, you can create private designs that other users cannot see by default. To change how **one project's** design, use **Customize Design** on the **Publish** page of that project. This does not require **Designer** permissions. See [Designs](/designer/designer) and [User permissions](/users/user-permissions#template-editor). ::: ::: details I updated the report design but in my project I don't see the changes. Why? A SysReptor pentest project does **not** keep a live link to the global design you picked at creation time. Creating a project **copies** the design into a project-specific snapshot. Later edits to the original design under **Designs** are not applied automatically to existing projects. You edited the **global** design, but the project still uses its **snapshot**? To apply the newest global design, go to **Settings** in your project, use the **Design** drop-down to select your global design and save. If field definitions differ, SysReptor warns that converting might lose data. You can force-change the design or duplicate the project first. ::: ::: details Why do I have no permissions in SysReptor finding templates? Creating and editing **finding templates** requires the **Template Editor** permission. Users without it cannot change templates used by others. Without Template Editor permission you still have **read access** and can apply templates when writing findings. See [Templates](/finding-templates/overview) and [User permissions](/users/user-permissions#template-editor). ::: ::: details Is SysReptor free or paid only? Large parts of SysReptor are free to use (SysReptor Community). We aim for a free and fully functional reporting tool for freelancers and small teams. We don't add restrictions that prevent commercial usage (such as watermarks, lack of customizations, etc.). * **SysReptor Community** is free to [self-host](/setup/installation). Some [features and multi-user roles require Professional](https://sysreptor.com/pricing). * **SysReptor Professional** is [paid](https://sysreptor.com/pricing) (self-hosted license or Cloud). * **SysReptor Labs** at [labs.sysre.pt](https://labs.sysre.pt) for [HTB](https://htb.sysreptor.com/htb/signup/)/[OffSec](https://offsec.sysreptor.com/offsec/signup/) students is **free** and includes Pro features. See [exam report FAQs](/faq/exam-reports). ::: ::: details How do I add 2FA/MFA for a SysReptor user? On any SysReptor instance, open **your user profile → Security** (`/users/self/security/`) and add a method: * **Security key (FIDO2 / WebAuthn)** * **Authenticator app (TOTP)** * **Backup codes** (store them offline) You can set a primary method. Superusers or user managers can remove all MFA devices for a user who is locked out (`/users//mfa/`). On **self-hosted** SysReptor, FIDO2 requires `MFA_FIDO2_RP_ID` set to your hostname. See [Configuration](/setup/configuration#fido2webauthn). We highly recommend adding MFA for every user account. ::: ::: details How do I write re-test reports in SysReptor? You can write your retest notes directly to your existing project.\ To keep the original report unchanged, **duplicate** the project and add re-test notes in the copy. We recommend adding the predefined report field **`is_retest`** and finding fields **`retest_status`** and **`retest_notes`** to the design. 1. Add those fields to the design if they are not already there. 2. Set **Is Retest** to true on the project you use for the re-test. 3. Update each finding’s re-test status (Open, Resolved, Partially Resolved, Changed, Accepted, New). Status colors appear in the report sidebar when the design includes `retest_status`. 4. In the PDF design, show retest-only blocks with Vue, for example `v-if="report.is_retest"`. See [Report designer](/designer/designer). ::: ::: details How do I export a SysReptor report as PDF? Open the pentest project’s **publish** page, preview the PDF, then use **Download**. You can set a filename and an optional PDF password. ::: ::: details How do I export or import a SysReptor pentest project? On the **Projects** list, select one or more projects and export a `.tar.gz` archive (with or without notes). Import uses the import button on the same list. Project export does **not** include the [version history](/reporting/version-history) and [comments](/reporting/comments-and-review#comments). ::: ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/contact-us.md --- # Contact us ## Get Support & Report Issues ::: info Found an issue? Help us improve SysReptor by reporting bugs and providing detailed reproduction steps. [Report a bug](https://github.com/Syslifters/sysreptor/issues/new?labels=bug){.doc-card\_\_link} ::: ::: info Have ideas for new features? Share your suggestions to help us improving SysReptor even more. [Request feature](https://github.com/Syslifters/sysreptor/issues/new?labels=enhancement){.doc-card\_\_link} ::: ::: info Looking for answers about labs.sysre.pt, self-hosted installs, SysReptor Cloud, or using the application? [Read the FAQs](/faq/){.doc-card\_\_link} ::: ::: info Need help or have questions? Get support and connect with us and the SysReptor community. [Get help](https://github.com/Syslifters/sysreptor/discussions/categories/q-a){.doc-card\_\_link} ::: ::: info Discovered a security vulnerability? Report it responsibly through our vulnerability disclosure process. [Disclose responsibly](https://github.com/Syslifters/sysreptor/security){.doc-card\_\_link} ::: ::: info Need to reach us privately? Send confidential messages about sensitive topics or business inquiries. [Signal: syslifters.01](https://signal.me/#eu/69wmqfeZfGeyV9dq5pY8u6wRiCNEzyWyAR3VBNZEYDpRQCqhZyhKZLAHUUCj_rsJ){.doc-card\_\_link} ::: ::: info You are a Professional customer and need support via a private channel? E-mail us at: team@syslifters.com ::: ::: info Interested in SysReptor Professional? Book a Teams call with us and get your questions answered. [Choose your time slot](https://cloud.syslifters.com/apps/appointments/pub/tBtAMcEwczA5CDMv/form){.doc-card\_\_link} ::: ## Contact Information --- --- url: https://docs.sysreptor.com/d/ad/privileged-access-strategy.md --- # AD Privileged Access Strategy ## Description The Privileged Access strategy is part of an overall strategy for access control in an enterprise. The Enterprise Access Model shows how privileged access can be securely managed in an enterprise. ![Enterprise Access Model](/images/user-app-control-management-data-workload-planes.png) Source: https://learn.microsoft.com/en-us/security/compass/media/privileged-access-strategy/user-app-control-management-data-workload-planes.png The applications and data of an organisation usually store a large part of the company's value. This information, which requires special protection, is held in the **Data/Workload Plane** in the Enterprise Access Model. The **Management Plane** comprises the infrastructure that provides the applications and data of the Data/Workload Plane. Management is the responsibility of the corporate IT organisation, whether hosted on-premise, in Azure or with a third-party cloud provider. Providing consistent access control for these systems across the enterprise requires a **Control Plane**. This is based on centralised identity management systems, complemented by network access controls. For these systems to add operational value, they must be accessible to internal users, suppliers and customers, e.g. via their workstations or other devices (access via **User Access**). Application programming interfaces (APIs) are also often necessary for process automation, creating access paths through applications (**App Access**). Finally, these systems need to be managed by IT staff, developers or other company employees. This leads to privileged access paths (**Privileged Access**). These access paths are particularly critical and should be strictly protected against compromise. ## Recommendation We recommend implementing a privileged access strategy as part of an overall access control strategy in an organization based on the enterprise access model. --- --- url: https://docs.sysreptor.com/s/alternative-to-attackforge-reporting-tool.md --- # Alternatives to AttackForge Pentesting Reporting Tool Similar projects and and alternatives to [AttackForge](https://attackforge.com/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-canopy-reporting-tool.md --- # Alternatives to Canopy Pentesting Reporting Tool Similar projects and and alternatives to [Canopy](https://www.checksec.com/canopy.html) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-dradis-reporting-tool.md --- # Alternatives to Dradis Pentesting Reporting Tool Similar projects and and alternatives to [Dradis](https://dradisframework.com/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-faraday-reporting-tool.md --- # Alternatives to Faraday Pentesting Reporting Tool Similar projects and and alternatives to [Faraday](https://faradaysec.com/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-ghostwriter-reporting-tool.md --- # Alternatives to Ghostwriter Pentesting Reporting Tool Similar projects and and alternatives to [Ghostwriter](https://github.com/GhostManager/Ghostwriter) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-hexway-hive-reporting-tool.md --- # Alternatives to Hexway Hive Pentesting Reporting Tool Similar projects and and alternatives to [Hexway Hive](https://hexway.io/hive/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-pentestws-reporting-tool.md --- # Alternatives to PenTest.WS Pentesting Reporting Tool Similar projects and and alternatives to [PenTest.WS](https://pentest.ws/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-petereport-reporting-tool.md --- # Alternatives to PeTeReport Pentesting Reporting Tool Similar projects and and alternatives to [PeTeReport](https://github.com/1modm/petereport) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-plextrac-reporting-tool.md --- # Alternatives to PlexTrac Pentesting Reporting Tool Similar projects and and alternatives to [PlexTrac](https://plextrac.com/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-pwndoc-reporting-tool.md --- # Alternatives to Pwndoc Pentesting Reporting Tool Similar projects and and alternatives to [Pwndoc](https://github.com/pwndoc/pwndoc) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-reconmap-reporting-tool.md --- # Alternatives to Reconmap Pentesting Reporting Tool Similar projects and and alternatives to [Reconmap](https://github.com/reconmap/reconmap) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: >- https://docs.sysreptor.com/s/alternative-to-security-reporter-reporting-tool.md --- # Alternatives to Security Reporter Pentesting Reporting Tool Similar projects and and alternatives to [Security Reporter](https://securityreporter.app/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-serpico-reporting-tool.md --- # Alternatives to Serpico Pentesting Reporting Tool Similar projects and and alternatives to [Serpico](https://github.com/SerpicoProject/Serpico) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-vulnrepo-reporting-tool.md --- # Alternatives to vulnrepo Pentesting Reporting Tool Similar projects and and alternatives to [vulnrepo](https://vulnrepo.com/) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-vulnreport-reporting-tool.md --- # Alternatives to Vulnreport Pentesting Reporting Tool Similar projects and and alternatives to [Vulnreport](https://github.com/salesforce/vulnreport) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/s/alternative-to-writehat-reporting-tool.md --- # Alternatives to WriteHat Pentesting Reporting Tool Similar projects and and alternatives to [WriteHat](https://github.com/blacklanternsecurity/writehat) Penetration Test Reporting Tool. SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/d/web/cross-site-request-forgery.md --- # Cross-Site Request Forgery (CSRF) ## Description Cross-site request forgery (CSRF) is a web security vulnerability in which an attacker can unknowingly trick an authenticated user into sending a state-changing HTTP request to the vulnerable web application. In CSRF, an attacker assumes the victim's identity and access privileges to perform unwanted actions (e.g., change email address) on their behalf. Without appropriate CSRF protection, the web application cannot distinguish between a request prepared by the attacker and a legitimate request from the victim. Several prerequisites must be in place for a CSRF attack to take place. First, there must be an action in the web application that is relevant to an attacker and makes sense to exploit. For example, this could be a privileged action, such as changing a user's access permissions or a password. Another requirement is that no mechanism exists besides cookie-based authentication to distinguish HTTP requests from different users. Suppose the user is authenticated and thus has a valid session cookie. In that case, the web application cannot differentiate between a malicious, subverted request from the attacker and a legitimate request from the victim. Last, ensure that actions do not require specific parameters whose values an attacker cannot determine or predict. For example, if a user is asked to change his password, the function is not vulnerable if an attacker needs to know the value of the existing password. A common way to exploit CSRF vulnerabilities is through phishing emails. An attacker does this by preparing malicious links to impose a state-changing request on the victim. The attacker then distributes the malicious links to victims via email. If an authenticated user opens the link in a web browser, the malicious website sends a cross-site request to the vulnerable web application. If successful, the attack causes an action with the victim's identity and privilege level. ## Recommendations * Check if the framework has built-in CSRF protection and use it. If not, ensure that all state-changing requests contain a randomly generated CSRF token with high entropy. Also, validate CSRF tokens properly in the backend. * Consider various additional security measures: * Use Custom Request Headers. By default, the browser's same-origin policy restricts JavaScript from submitting cross-site requests with custom HTTP request headers. * Set the `SameSite` attribute for session cookies to `strict`. Based on this attribute, web browsers decide whether to include cookies in cross-site requests. * User interactions such as CAPTCHAs, one-time tokens, re-authentication, etc., can also be considered as additional CSRF protection for highly sensitive actions. * Find detailed information and assistance on preventing CSRF vulnerabilities in the [Cross-Site Request Forgery Cheat Sheet from OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html). --- --- url: https://docs.sysreptor.com/d/web/cross-site-scripting.md --- # Cross-site scripting (XSS) ## Description Cross-site scripting (XSS) is a web security vulnerability where an attacker can inject malicious scripts into the HTML structure of a website due to insufficient validation or encoding of data. In XSS attacks, attackers embed JavaScript code in the content delivered by the vulnerable web application. There are three different types of XSS: ### Stored XSS Stored XSS is usually the most critical XSS vector. Attackers thereby place JavaScript code on pages visited by other users. The injected scripts execute in the users' web browsers when they visit the website. ### Reflected XSS The goal of reflected XSS is to lure legitimate users to manipulated links and thus execute injected scripts. The most common method for this is a phishing email. When the victim opens the crafted link in a web browser, the HTTP request sends the malicious script to the web application. Due to insufficient validation and encoding, the web application accepts the injected script and embeds it as content in the subsequent response to the client. The malicious script executes in the victim's web browser and can potentially access cookies, session tokens, or other sensitive information. Attackers can exploit reflected XSS on a larger scale, for example, by combining the attack with cache poisoning or HTTP request smuggling. ### DOM-based XSS DOM-based XSS occurs when a web application contains client-side JavaScript code that insecurely processes data from untrusted sources (for example, when data is dynamically written back to the DOM of the web browser at runtime). It differs from reflected or stored XSS by how attackers inject malicious scripts into the HTML code. For reflected XSS and stored XSS attacks, server-side processes include the malicious scripts in the HTML code, but the web browser does so in DOM-based XSS. Sometimes, the browser does not even send the malicious script to the web server. Such an attack will bypass all server-side filtering measures to protect users. The victim's web browser executes malicious XSS scripts that can potentially access cookies, session tokens, or other sensitive information or trigger actions on behalf of the attacked user. An attacker gains control over web application functions and data in the victim's context. If the affected user has privileged access, an attacker may be able to gain complete control over the web application. ## Recommendation * Filter untrusted user inputs as strictly as possible. Filtering and validation should happen based on expected and valid inputs. * Encode data before including it in HTTP responses. * Use a Content Security Policy (CSP) to control which client-side scripts are allowed and which are forbidden. * Set the `HttpOnly` flag for sensitive cookies to prevent JavaScript access. * Find detailed information on preventing XSS in the OWASP [Cross-Site Scripting Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html). --- --- url: https://docs.sysreptor.com/cli/tools/customize-pushed-findings.md --- # Customize Pushed Findings ::: warning Deprecated CLI importers are deprecated. Import scan results from the SysReptor web UI using the [scanimport](https://github.com/Syslifters/sysreptor/tree/main/plugins/scanimport) plugin instead. ::: When using `reptor --push-findings`, reptor aggregates all findings by scan plugin (so that, e.g., "SQL Injection" is only added once for multiple affected systems). It uses descriptions from the scanning tools. But sometimes, you want to customize the finding descriptions or ratings. Here's how you do it. *This description might not apply to all reptor tool plugins. It is, however, applicable at least to Nessus, OpenVAS, and Burp.* Let's say we want to replace the title and the CVSS score of the SQL injection finding in a Burp report. ## Copy default templates to your home directory The first step is to copy the templates shipped with reptor to your home directory. Use the following command: ```shell reptor plugins --copy burp ``` This command copies the templates (usually in TOML format) to ~/.sysreptor/plugins/Burp/findings. Templates in this location override the default templates shipped with reptor. Changes in those templates are effective immediately. ## Customize templates with static text The `global.toml` template holds the information populated to SysReptor when pushing findings. ![Contents of global.toml](/cli/assets/burp_global_toml.png) The variables use the Django template language but with [different markers](/cli/writing-plugins/tools#formatting-tool-output) (enclosed in HTML comments). Changes in this file will affect all findings pushed from the command line to your SysReptor report. If we want to customize the Burp SQL injection finding, we first need to find out the plugin ID (Burp calls it "type") of the plugin. We find the ID 1049088 in the [Portswigger Knowledge Base](https://portswigger.net/kb/issues/00100200_sql-injection) or in the notes if we upload Burp findings as notes (using `reptor burp -i burp.xml --upload`). We now copy `global.toml` and name it `1049088.toml`. We can now change the title and the CVSS score to static values: ![Customized template](/cli/assets/burp_customized_sqli.png) If we now push the finding (e.g., using `reptor burp -i burp.xml --push-findings --include 1049088`), reptor uses our custom title. ## Customize templates with dynamic text Burp includes lots of information in its reports that we do not use when pushing findings. You can check what variables exist using `reptor burp -i burp.xml --template-vars`. You'll find, for example, the variable "confidence": ```shell $ reptor burp -i burp.xml --template-vars [ { "severity": "high", "confidence": "Firm", ``` You can easily use this variable in your templates: ![Customized template with "confidence"](/cli/assets/burp_customized_sqli_1.png) ## Populate your changes to your colleagues Wouldn't it be nice if your colleagues could reuse your changes? That's easy. Push your findings to your finding templates using `reptor burp --upload-finding-templates` (your user needs permission to edit finding templates). ![Pushed Burp SQLi template](/cli/assets/burp_pushed_finding_template.png) Finding templates having the tag "\:\" override local templates (shipped with reptor or in your home directory). The template is now effective for all SysReptor users using `reptor` to push Burp reports. --- --- url: https://docs.sysreptor.com/d/ad/direct-memory-access.md --- # Direct Memory Access ## Description Direct Memory Access (DMA) enables hardware devices such as network cards or USB controllers to access the system's main memory directly without involving the CPU. This allows faster data transfers. In a DMA attack, an attacker uses physical or remote access to a target system and takes advantage of the DMA capabilities to access the RAM directly. This access allows the attacker to bypass traditional security measures such as operating system permissions or encryption and potentially gain unauthorized access to sensitive data or compromise the system's integrity. There are two main types of DMA attacks: 1. DMA read attacks: The attacker gains access to the system's memory and can read sensitive information from memory, such as encryption keys, passwords, or confidential data. The attacker can then use this information for unauthorized purposes. 2 DMA write attacks: The attacker injects malicious data or code into the system's memory and overwrites potentially critical data or alters the system's behavior. This can lead to privilege escalation, malware injection, or changes to system settings. DMA attacks can be carried out in various ways, including physical access to the target system, compromised peripherals, or exploiting vulnerabilities in the system firmware or drivers. Some examples of DMA attack vectors are FireWire, Thunderbolt, PCI Express, or PCMCIA interfaces. ## Recommendation Activate the Windows function "Kernel DMA Protection" to protect against DMA attacks. --- --- url: https://docs.sysreptor.com/setup/downgrades.md --- # Downgrades ::: info Downgrading requires a backup from the version that you want downgrade to. ::: 1. Create a backup Create a [backup](/setup/backups) before downgrading. 2. Change directory to your previous version The update script creates a backup of your prior version's configuration. The directory is usually named `sysreptor-backup-`.\ Enter the `deploy` directory within that folder. ```shell cd sysreptor-backup-/deploy ``` 3. Restore the backup ```shell cat .zip | docker compose run --rm --no-TTY app python3 manage.py restorebackup ``` ::: warning This command deletes all present data and restores data from the backup. Do not run without having made a backup. ::: 4. Launch the old SysReptor version ```shell docker compose up -d ``` --- --- url: https://docs.sysreptor.com/faq.md --- # Frequently Asked Questions Find answers for your SysReptor setup: * [Exam reports](/faq/exam-reports) — writing HTB, OffSec, and other certification reports on [labs.sysre.pt](https://labs.sysre.pt) * [Self-hosted](/faq/self-hosted) — installing, updating, backing up, and uninstalling SysReptor on your own server * [Cloud](/faq/cloud) — SysReptor Cloud hosted by Syslifters * [Application](/faq/application) — using SysReptor: reports, designs, API, MFA, and more * [Report design](/designer/faqs) — CSS and HTML for PDF report templates ::: info Need help or have questions? Get support and [connect with us and the SysReptor community](https://github.com/Syslifters/sysreptor/discussions/). ::: --- --- url: https://docs.sysreptor.com/htb-reporting-with-sysreptor.md --- # Hack The Box Reporting Our free cloud service to write your Hack The Box CPTS, CWES, CDSA, CWEE, CAPE, CJCA, CWPE or COAE reports. 💲 Free.\ 💎 Including Pro features.\ ✍️ Write it in Markdown.\ 📄 Render the report for your certifiation.\ 👌 Zero setup required. [🚀 Sign Up (it's free)](https://htb.sysreptor.com/htb/signup/){ .md-button } Already have an account? [Login here.](https://labs.sysre.pt) Questions about labs.sysre.pt, account recovery, or data retention? See the [exam report FAQs](/faq/exam-reports). ## Prefer self-hosting? 1. [Install](/setup/installation) SysReptor 2. Import all HTB Designs and Reports: ```shell cd sysreptor/deploy curl -s "https://docs.sysreptor.com/assets/htb-designs.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=design curl -s "https://docs.sysreptor.com/assets/htb-demo-projects.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=project ``` ## Hack The Box Reports ## Creating HTB Report --- --- url: https://docs.sysreptor.com/d/ad/insecure-adidns.md --- # Insecure ADIDNS ## Description Domain controller DNS can store its zone data in Active Directory Domain Services (AD DS). There is no need for a separate DNS replication topology like DNS zone transfers. Any domain controller in a domain running the DNS server service can update the DNS zones built into Active Directory. All zone data is automatically replicated by Active Directory replication with domain controllers. ADIDNS zones can be modified remotely via dynamic updates or by using LDAP. DNS Dynamic Update Protocol is a DNS-specific protocol designed for updating DNS zones. In Active Directory, dynamic updates are mainly used by computer accounts to add and update their own DNS records. New records can be added to the zone if they do not already exist. Accounts that create new records are given full control over them. User accounts cannot edit existing records or add another record with the same name by default, even if the record type is different (A, AAAA, CNAME, MX, etc.). By default, ADIDNS zone access permissions allow regular domain users to create new DNS records that do not yet exist. If zones are configured for insecure dynamic updates, unauthenticated users can modify all existing DNS records. Attackers can exploit both circumstances to get into a MitM position. For example, an attacker could add a new record to a DNS zone when a client on the network resolves a name via Link-Local Multicast Name Resolution (LLMNR) or NetBIOS Name Service (NBT-NS). A name that is resolved via LLMNR or NBT-NS typically does not exist in DNS. Alternatively, if DNS zones are configured for insecure dynamic updates, an attacker can modify existing DNS records. This allows an attacker to ensure that clients resolve a specific name using DNS with an arbitrary IP address. If an attacker is in this position, network traffic between two systems can be routed through a system controlled by the attacker, as in any other spoofing attack. In a successful attack, an attacker could obtain credentials to remotely execute code on a Windows machine or move laterally on the network. ## Recommendation * Restrict DNS zone access permissions to prevent authenticated users from creating new DNS records. * Ensure that only secure dynamic DNS updates are allowed. * Use a dedicated user account for dynamic DNS updates via DHCP. * Create a wildcard (`*`), as well as a `wpad` record (e.g. as a TXT record) in all zones. * Mail clients should not load images by default, at least from external senders. --- --- url: https://docs.sysreptor.com/d/web/insecure-http-cookies.md --- # Insecure HTTP cookies ## Description HTTP is a stateless protocol, meaning it cannot distinguish requests from different users without an additional mechanism. Addressing this problem requires a session mechanism. The most commonly used mechanism for managing HTTP sessions in browsers is cookie storage. An HTTP cookie is a small record that a server sends to a user's web browser. The browser can store the cookie and send it back to the same server for subsequent requests. Web applications can thus implement sessions for the stateless HTTP protocol. The server can use the HTTP cookie to distinguish requests from different users and to keep users logged in. Cookies thus represent a frequent target for attackers. A web application should, therefore, harden the configuration of all sensitive cookies by setting the `Secure` and `HttpOnly` cookie attributes and the `SameSite` attribute to `strict`: * A cookie with the `Secure` attribute will only be sent to the server over HTTPS connections and never over an unsecured HTTP connection. * A cookie with the `HttpOnly` attribute set is inaccessible to JavaScript and thus helps mitigate cross-site scripting (XSS) attacks. * A cookie with `SameSite=strict` attribute will not be sent in cross-site requests from third-party websites (in contrast to the weaker `Lax` and the insecure `None`). If an attacker can tap sensitive cookies such as session cookies, the attacker could take over user accounts and perform actions in the context of affected users. An attacker may also gain complete control over all web application functions and data if they take over a user account with privileged access. ## Recommendation Set the cookie attributes `HttpOnly`, `Secure`, and `SameSite=Strict`. --- --- url: https://docs.sysreptor.com/d/ad/insecure-name-resolution-protocols.md --- # Insecure name resolution protocols ## Description An attacker gets into a MitM position if, for example, he is able to manipulate the name resolution in a network. This is the case if an attacker has direct access to the network. The Link-Local Multicast Name Resolution (LLMNR), NetBIOS Name Service (NBT-NS) or Multicast DNS (mDNS) protocols are, in addition to Domain Name System (DNS), three alternative ways of resolving host names in a network. Name resolutions via such broadcast protocols can be very easily manipulated by an attacker. An attacker responds to all requests in the network with the address of a system under his control, forcing communication with this system. If the requested host requires authentication, the user name and the Net-NTLMv2 hash are sent to the system controlled by the attacker. Net-NTLMv2 hashes can thus be intercepted and used in the course of relaying attacks. An attacker may then be able to access the target system and execute code there. Furthermore, Net-NTLM hashes are susceptible to offline brute force attacks. Attackers can try out password combinations at very high speeds and obtain the plain text password in the event of a successful attack. ## Recommendation Disable LLMNR, NBT-NS, and mDNS name resolutions in the local computer security settings or via Group Policy. --- --- url: https://docs.sysreptor.com/d/web/insecure-storage-of-session-tokens.md --- # Insecure storage of session tokens ## Description Web browsers have security mechanims for protecting session tokens. Those mechanisms prevent access to the session token via JavaScript and ensuring that the session token is always sent via encrypted channels. They are however only applicable to Cookies. Web applications storing session tokens in the browser's session session storage, local storage or IndexDB make the session tokens readable via JavaScript. If tokens are stored in the local storage or IndexDB (instead of the session storage), the data is retained after the browser is closed. This further increases the risk because the tokens are retained even after the browser is closed. Single-page apps (SPAs) require access tokens to call APIs. They often also have a refresh token that allows offline access to the users' resources. This refresh token can request new access tokens without user interaction and are a particularly interesting target in cross-site scripting (XSS) attacks. If tokens with wide scopes are issued to the SPA, this can potentially give an attacker access to functionality not normally accessible through the user interface. In the event of theft, an attacker can at least take over the identity of the victim and perform actions. ## Recommendation We advise against storing sensitive data such as session tokens in the session storage, local storage, or the IndexDB of the web browser. * Prefer cookies with `Secure` and `HttpOnly` flags over other storage mechanisms. * If this is not possible, consider setting the refresh token as a cookie. * Prefer session storage over local storage and IndexDB. * Consider a Backend-for-Frontend architecture. [^1] [^2] [^3] [^1]: https://learn.microsoft.com/en-us/azure/architecture/guide/web/secure-single-page-application-authorization [^2]: https://curity.io/resources/learn/the-token-handler-pattern/ [^3]: https://damienbod.com/2022/01/10/comparing-the-backend-for-frontend-bff-security-architecture-with-an-spa-ui-using-a-public-api/ --- --- url: https://docs.sysreptor.com/d/ad/lsass-protection.md --- # LSASS protection ## Description The Local Security Authority Subsystem Service is a process in Microsoft Windows operating systems that is responsible for enforcing security policy on the system. For this purpose, among other things, it temporarily stores the credentials of logged-in users in order to perform authentications against other systems (e.g. when opening a file share). Depending on the operating system version, either plain-text passwords or only NT hashes are stored by default. However, NT hashes are similarly critical as passwords, since they can be used for authentication via pass-the-hash. To protect this critical process, the vendor provides several methods, including "Credential Guard" and "LSA Protection" (RunAsPPL). Credential Guard is a virtualization-based isolation technology for LSASS in which credentials are stored in a memory area protected by the processor. Access to credentials protected in this way is not possible. However, you should note that this only protects credentials that are already cached. An attacker could still intercept the credentials of new authentication processes. LSA Protection (RunAsPPL) is a protection mechanism in the Windows kernel that protects the memory of the LSASS process from access. However, since this is a kernel feature, it can be bypassed by kernel modules. It should still be enabled along with Credential Guard. Loading a malicious kernel module provides versatile opportunities for AV/EDR/HIDS systems to detect the attack, making the attack more difficult. ## Recommendation Credential Guard and LSA Protection should be enabled on all systems. --- --- url: https://docs.sysreptor.com/d/ad/network-access-control.md --- # Network Access Control ## Description Network Access Control (NAC) allows you to define and enforce policies for access into a corporate network. For example, when a computer connects to a network, it is only allowed to access resources if it meets the policy set by the company (e.g., virus protection, current system version, specific configuration, etc.). Once the policy is met, the computer can access network resources and the Internet within the policy set by the NAC solution. The basic form of NAC is the 802.1X standard. 802.1X is an authentication standard for devices that want to connect to a protected LAN or WIFI. Only authenticated and authorized devices can gain access to protected networks. Three components are involved in 802.1X authentication: a supplicant, an authenticator, and an authentication server. The supplicant is a device (e.g. a laptop) that wants to connect to the LAN or WIFI. The Authenticator is a network device (e.g. a switch or access point) that establishes the connection between the client and the network. The Authentication Server is a server that authenticates supplicants (i.e., client devices) and decides whether to allow a supplicant access to a protected network. The Authentication Server is connected to an identity store (such as LDAP) for this purpose. The Extensible Authentication Protocol (EAP) is used for authentication, which provides a secure method of transmitting credentials for network authentication. 802.1X is the standard used to transmit EAP messages over wired or wireless networks. Using an encrypted EAP tunnel, 802.1X prevents information from being read by third parties. The EAP protocol offers various authentication options such as via username/password (EAP-TTLS/PAP and PEAP-MSCHAPv2) or via client certificates (EAP-TLS). ## Recommendation * Implement a NAC solution based on 802.1X to securely authenticate and authorize devices on your network. * Use EAP-TLS to authenticate devices via certificates. * Enforce MAC Authentication Bypass (MAB) for devices that do not support 802.1X. Ensures that these devices are compartmentalized using appropriate network segmentation. * Block network access for unknown devices by default. * Asset management solutions can help detect unknown devices on the network. --- --- url: https://docs.sysreptor.com/offsec-reporting-with-sysreptor.md --- # OffSec Reporting Our free cloud service to write your OffSec OSCP+, OSEP, OSWP, OSWA, OSWE, OSED, OSMR, OSEE, OSDA, OSIR, OSTH, OSAI reports. 💲 Free.\ 💎 Including Pro features.\ ✍️ Write it in Markdown.\ 📄 Render the report for your certifiation.\ 👌 Zero setup required. [🚀 Sign Up (it's free)](https://offsec.sysreptor.com/offsec/signup/){ .md-button } Already have an account? [Login here.](https://labs.sysre.pt) Questions about labs.sysre.pt, account recovery, or data retention? See the [exam report FAQs](/faq/exam-reports). ## Prefer self-hosting? 1. [Install](/setup/installation) SysReptor 2. Import OffSec Designs and demo projects: ```shell cd sysreptor/deploy curl -s "https://docs.sysreptor.com/assets/offsec-designs.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=design curl -s "https://docs.sysreptor.com/assets/offsec-demo-projects.tar.gz" | docker compose exec --no-TTY app python3 manage.py importdemodata --type=project ``` ## OffSec Reports ### Penetration Testing ### Web Application Security ### Exploit Development ### Artificial Intelligence ### Defensive Security The structure follows the official OffSec reports (with kind permission by OffSec). ## Creating an OSCP Exam Report ![OSCP Reporting Procedure](/images/oscp-reporting.gif) Not happy with our solution? { .md-button } --- --- url: https://docs.sysreptor.com/d/web/path-traversal.md --- # Path traversal / Directory traversal ## Description Path Traversal is a web security vulnerability that allows an attacker to access files and directories on the underlying web server of a web application. Access to files and directories in a path traversal attack is restricted solely by the existing access controls of the underlying operating system. Web servers usually limit access to a specific part of the file system: the "web root". This directory contains all files required for the functionality of the web application. Attackers use special strings in path specifications to break out of the web root folder using a path traversal attack. In the simplest form, an attacker uses the string "../" to change the location of the resource requested in the parameter. This string is a relative path specification. It refers specifically to the parent directory of the current working directory. Attackers also often use alternative encodings of the "../" sequence to bypass any security filters that may be in place. These methods include valid and invalid Unicode-encoded ("..%u2216" or "..%c0%af"), URL-encoded ("%2e%2e%2f"), and duplicate URL-encoded characters ("..%255c") of the backslash character. Advanced techniques also often use additional special characters such as the period "." to refer to the current working directory or the "%00" NULL character to bypass rudimentary end-of-file checks. In a successful attack, an attacker can use path traversal to access arbitrary files and directories on the vulnerable system. This may include sensitive operating system files, application code, or configuration files. Path Traversal may also provide write access to files and directories, sometimes allowing attackers to gain code execution and, thus, complete control over the web server. ## Recommendation * Avoid using custom filenames and path specifications in the web application and use indexes instead (e.g., index: 5 corresponds to "images/img.png"). * Ensure that only valid and expected client input is accepted. Discard all other inputs. * If you have to normalize paths, consider that characters may be single or multiple encoded (such as URL encoded, e.g., `%20` or `%2520` instead of a space). --- --- url: https://docs.sysreptor.com/s/pentest-reporting-tools.md --- # Pentest Reporting Tools - A List of the most popular tools SysReptor is a Pentest Reporting Tool written by pentesters, for pentesters. It is built with security in mind, best usability and strongest focus on the needs of pentesters. However, if it does not fit your needs, here is a list of alternative tools. | Name | Report Customization | Deployment | Costs/User/Month | | - | - | - | - | | 🔥 [SysReptor](https://docs.sysreptor.com) | 📄 HTML with VueJS | 🖥️ Cloud/OnPrem | 🏷️ Free or € 50 | | [AttackForge](https://attackforge.com/) | 📄 docx with customized template tags | 🖥️ Cloud or OnPrem (Enterprise only) | 🏷️ Free or $ 30 to $ 50 | | [Canopy](https://www.checksec.com/canopy.html) | 📄 docx with custom Word plugin | 🖥️ Cloud/OnPrem | 🏷️ Unknown | | [Dradis](https://dradisframework.com/) | 📄 docx (Dradis optionally customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 79 or $ 149 | | [Faraday](https://faradaysec.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Free or from $ 120 | | [Ghostwriter](https://github.com/GhostManager/Ghostwriter) | 📄 docx/Jinja2 | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Hexway Hive](https://hexway.io/hive/) | 📄 docx with jinja-like syntax (Hexway customizes for you) | 🖥️ Cloud/OnPrem | 🏷️ Free or $ 78 | | [PenTest.WS](https://pentest.ws/) | 📄 docx with custom syntax and HTML | 🖥️ Cloud | 🏷️ From $ 4.95 | | [PlexTrac](https://plextrac.com/) | 📄 docx/Jinja2 | 🖥️ Cloud/OnPrem | 🏷️ Top secret | | [Pwndoc](https://github.com/pwndoc/pwndoc) | 📄 docx via docxtemplater | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Reconmap](https://github.com/reconmap/reconmap) | 📄 docx via PHPWord | 🖥️ OnPrem | 🏷️ Free and Open Source | | [Security Reporter](https://securityreporter.app/) | 📄 Theme editor | 🖥️ OnPrem | 🏷️ From $ 150 | | [vulnrepo](https://vulnrepo.com/) | 📄 Not provided | 🖥️ OnPrem | 🏷️ Free and Open Source | | [WriteHat](https://github.com/blacklanternsecurity/writehat) | 📄 HTML/Django Templating Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [PeTeReport](https://github.com/1modm/petereport) | 📄 LaTeX/Eisvogel | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Serpico](https://github.com/SerpicoProject/Serpico) | 📄 docx with custom Meta Language | 🖥️ OnPrem | 🏷️ Free and Open Source | | ❌ [Vulnreport](https://github.com/salesforce/vulnreport) | 📄 Unknown | 🖥️ OnPrem | 🏷️ Free and Open Source | [🚀 Sign Up to SysReptor](https://sysreptor.com){ .md-button } This overview of penetration testing reporting tools has been compiled to the best of our knowledge and belief. We do not guarantee that the information is correct or up-to-date. ❌ We regard software projects without updates for one year, with missing security patches or major dependencies without support as discontinued. We welcome tips on other pentest reporting tools. For inquiries and tips write us a short message to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/d/ad/preboot-execution-environment.md --- # Preboot Execution Environment ## Description Preboot Execution Environment (PXE boot) is a network protocol that allows starting a computer via the network and providing an operating system or software without needing a local hard disk or optical drive. If misconfigured, PXE boot can be misused to open a shell with system authorizations when a new computer is started to create a local user with administrator authorizations. This allows the (often later domain-joined) device to be used with local administration authorizations. To use PXE boot effectively and to automate the process of operating system provisioning, software tools like System Center Configuration Manager (SCCM) from Microsoft are often used. SCCM is a comprehensive management and deployment tool for IT infrastructures. It enables the central administration of operating systems, applications, and settings in a network. With SCCM, administrators can set up PXE boot environments to configure computers on the network via network startup and automatically install operating systems or software. SCCM offers functions such as creating images, deploying software packages, collecting inventory data, and managing updates. It simplifies the process of operating system provisioning and enables centralized management and configuration of the network computers. ## Recommendation * Disable the debug mode in boot images. * If possible, only perform PXE deployments in isolated networks. * Ensure that the password for starting the installation process is sufficiently secure. --- --- url: https://docs.sysreptor.com/d/ad/resource-based-constrained-delegation.md --- # Resource-based Constrained Delegation (RBCD) ## Description Resource-based Constrained Delegation (RBCD) is a particular type of Kerberos delegation configured in-depth for computer accounts. A computer account uses it to decide which other computers to trust for Kerberos delegations. This differs from the other types of delegation (Unconstrained and Constrained Delegation), configured on the computer accounts that want to access the resource (outbound). The attribute `msDS-AllowedToActOnBehalfOfOtherIdentity` controls RBCD by storing a security descriptor of the computer object that can access the resource. To abuse Resource-based Constrained Delegation, attackers define the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute using the privileges of computer accounts over which they have control. RBCD could, therefore, be exploited in this situation as follows: 1. Take over an account that is allowed to configure RBCD. 2. Add a new computer account to the domain 3. Set the `msDS-AllowedToActOnBehalfOfOtherIdentity` on the computer to be taken over. * To do this, define the Security Descriptor of the computer account from step 2 as the value. 4. Issue a service tick using resource-based constrained delegation. 5. Use the issued service ticket to compromise the computer. ## Recommendation * Owners of a computer object should be Tier-0 user accounts. * Domain users should not be allowed to add computers to the domain (`MachineAccountQuota` = 0). * Instead, a dedicated user account should be used, which should be considered as requiring special protection (cf. Domain Administrator). * Add all sensitive user accounts to the Protected Users group. * The option "Account is sensitive and cannot be delegated" should be activated for all computer accounts, if possible, and for all sensitive user accounts. --- --- url: https://docs.sysreptor.com/d/web/sql-injection.md --- # SQL injection (SQLi) ## Description SQL Injection is a server-side vulnerability in web applications. It occurs when software developers create dynamic database queries that contain user input. To exploit this vulnerability, an attacker can craft user input so that the originally intended action of an SQL statement is changed. SQL injection vulnerabilities result from an application's failure to dynamically create database queries insecurely and to validate user input properly. The SQL language does not distinguish between control characters and data characters. Control characters in the data part of SQL statements must be encoded or escaped appropriately beforehand. Attackers often detect SQL injection vulnerabilities by inserting a control character (like a single apostrophe) into the user input to place new commands not present in the original SQL statement. A simple example demonstrates this process. The following SELECT statement contains a variable userId. This statement aims to get a user's data with a specific user ID from the Users table. `sqlStmnt = 'SELECT * FROM Users WHERE UserId = ' + userId;` An attacker could now use special user input to change the original intent of the SQL statement. For example, he could use the string `' or 1=1` as user input. In this case, the application would construct the following SQL statement: `sqlStmnt = 'SELECT * FROM Users WHERE UserId = ' + ' or 1=1;` Instead of a user's data with a specific user ID, the database returns data of all users in the table. This allows an attacker to control the SQL statement in his favor. Several variants of SQL injection vulnerabilities, attacks, and techniques occur in different situations depending on the database system used. However, they all share that the database interprets user input as SQL commands (as in the example above). Successful SQL injection attacks can have far-reaching consequences. One would be the loss of confidentiality and integrity of the stored data. Attackers could gain read and possibly write access to sensitive data in the database. SQL injection could also compromise the authentication and authorization of the web application, allowing attackers to bypass existing access controls. In some cases, SQL injection can also be used to execute operating system commands, allowing an attacker to gain complete control over the vulnerable server. ## Recommendation * Use prepared statements or stored procedures wherever possible. Prepared statements are parameterized statements and prevent attackers from manipulating SQL statements. * Validate all user input. Ensure that only expected and valid input is accepted. Do not sanitize potentially malicious input. * Reduce the potential damage of SQLi attacks. Minimize the database user's privileges using the principle of least privilege. * For detailed information and assistance on how to prevent SQL Injection vulnerabilities, see the [OWASP SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html). --- --- url: https://docs.sysreptor.com/license.md --- # SysReptor Community License 1.1 (SysReptorL) ## Acceptance In order to get any Permissions to Use the Software under the SysReptorL, you must agree to it as both strict obligations and conditions to all your Licenses. ## Copyright License The licensor grants you a non-exclusive copyright Permission to Use the Software for everything you might do with the Software that would otherwise infringe the licensor's copyright in it for any permitted purpose, other than distributing the software or making changes or new works based on the Software. Attempts to circumvent technical License restrictions are prohibited (e.g. to unlock or extend functionalities), even if they result from errors in the Software. ## Patent License The licensor grants you a non-exclusive patent License for the Software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the Software after its Intended Use. ## Internal Business Use Use of the Software for the internal business operations of you and your Company is use for a permitted purpose. ## Personal Uses Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose. ## Fair Use You may have "**Fair Use**" rights for the Software under the law. The SysReptorL does not limit them unless otherwise agreed. Pursuant to Section 40d of the Act on Copyright and Related Rights (Urheberrechtsgesetz, UrhG), computer programs may be edited and reproduced within the framework of the Fair Use of works to the extent that this is necessary for the Intended Use of the Software by the person entitled to use it. The **Intended Use** is limited to the permitted purpose of the Software in accordance with the SysReptorL. ## Plugin Development and Usage The licensor grants you permission to develop and use plugins that use official plugin interfaces for the Software, provided that these plugins do not bypass any license restrictions. Use of non-official plugins that bypass or attempt to bypass license restrictions is a violation of these terms. This includes the usage of any plugins that unlock or extend functionalities in ways not permitted by the SysReptorL. The licensor reserves the right to revoke or modify interfaces from and to the Software without prior notice. This may affect the functionality of plugins and other integrations. ## No Other Rights The SysReptorL does not allow you to sublicense or transfer any of your Licenses to anyone else or prevent the licensor from granting Licenses to anyone else. The SysReptorL does not imply any other Licenses than those mentioned therein. ## Patent Defense If you make any written claim that the Software infringes or contributes to infringement of any patent, your patent License for the Software granted under this SysReptorL ends immediately. If your Company makes such a claim, your patent License ends immediately for work on behalf of your Company. Irrespective of the withdrawal of Permission to Use the Software, we reserve the right to assert claims for damages. ## Violations In case of license violations, all your licenses end immediately. ## No Liability ***As far as the law allows, the Software comes “as is”, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of this SysReptorL or the use or nature of the Software, under any kind of legal claim.*** ## Definitions The SysReptor Community License 1.0 (**SysReptorL**) is granted by Syslifters GmbH, FN 578505v, registered office Göllersdorf (**Syslifters**; **we**; **licensor**) to **you**. **License**: Is the overall term for the authorization to use the Software. The term "License" says nothing about the copyright classification. **Software**: is the software the licensor makes available under these terms. **Permission to Use the Software** (*Werknutzungsbewilligung*): Non-exclusive copyright Permission to Use the Software. **Use** means anything you do with the software requiring one of your licenses. **Your Company**: Is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. **Your licenses** are all the licenses granted to you for the software under these terms. *** **Last Updated:** 11 November 2024 --- --- url: https://docs.sysreptor.com/faq/ai.md --- # SysReptor FAQ context for AI assistants This page is for AI assistants answering SysReptor questions. It disambiguates products, URLs, core objects (template vs design vs project vs report), and similar-sounding features so answers stay specific. Prefer the public FAQ pages for user-facing procedures: [exam reports](/faq/exam-reports), [self-hosted](/faq/self-hosted), [cloud](/faq/cloud), [application](/faq/application), [report design](/designer/faqs). ## Error: `The command 'docker' could not be found in this WSL 2 distro.` This is a **self-hosted Windows/WSL** Docker Desktop problem, not a SysReptor app bug. Docker Desktop is installed, but it has not injected the `docker` CLI into that WSL 2 distro. SysReptor is **not** installed natively on Windows. Use **WSL 2 + Ubuntu + Docker Desktop**, then enable integration for **that** distro: Docker Desktop **Settings → Resources → WSL Integration** (default distro and the distro they opened). Docker Desktop must be running. Confirm the distro is version 2 (`wsl -l -v`). Restart WSL after changing settings (`wsl --shutdown`, then reopen the distro) and retry `docker info`. Public FAQ: [self-hosted](/faq/self-hosted#docker-wsl). Do not invent a native Windows installer. ## Error: `permission denied while trying to connect to the docker API at unix:///var/run/docker.sock` This is a **self-hosted Docker permission** problem, not a SysReptor application bug. The current Linux user cannot talk to the Docker daemon socket, so `docker` / `docker compose` (and the [install script](/setup/installation)) fail. Add the user to the `docker` group and apply it in the current shell (same commands as in [Installation](/setup/installation)): ```shell sudo groupadd docker 2>/dev/null sudo usermod -aG docker $USER newgrp docker ``` Then confirm with `docker info`. If it still fails, log out and back in (or reconnect SSH) so group membership applies. The Docker daemon must be running. Official Docker Engine is required; **Podman is not supported**. On Windows, use WSL 2 + Docker Desktop with WSL integration. Public FAQ: [self-hosted](/faq/self-hosted#docker-sock). Do not tell exam students on labs.sysre.pt to SSH or run Docker commands. ## When a user says SysReptor Cloud, labs, demo, or docs, which URL do they mean? Do not mix these SysReptor URLs: * **SysReptor Labs ([labs.sysre.pt](https://labs.sysre.pt))** — free student exam-reporting service (HTB, OffSec). Login for existing exam accounts. Data is deleted after three months without login. Public FAQ: [exam reports](/faq/exam-reports). * **[htb.sysreptor.com/htb/signup/](https://htb.sysreptor.com/htb/signup/)** — HTB exam **signup** (not the daily login URL). * **[offsec.sysreptor.com/offsec/signup/](https://offsec.sysreptor.com/offsec/signup/)** — OffSec exam **signup**. OSCP-specific: [offsec.sysreptor.com/offsec/signup/](https://offsec.sysreptor.com/offsec/signup/). * **SysReptor Cloud** — paid hosted instance for organizations, not SysReptor Labs. Pricing: [sysreptor.com/pricing](https://sysreptor.com/pricing). Public FAQ: [cloud](/faq/cloud). * **Self-hosted** — Docker on the user’s server, often `https://sysreptor.example.com` or `http://127.0.0.1:8000/`. Public FAQ: [self-hosted](/faq/self-hosted). * **[demo.sysre.pt](https://demo.sysre.pt)** / **[sysreptor.com/demo](https://sysreptor.com/demo)** — public playground. Not the user’s exam account, Cloud tenant, or production data. * **[docs.sysreptor.com](https://docs.sysreptor.com)** — this documentation site, not the application. If the user is writing an exam report and mentions HTB or OffSec, use labs.sysre.pt and the exam FAQ. If they mention Docker, `app.env`, or Ubuntu, use self-hosted. If they mention a company-hosted tenant without labs/HTB/OffSec, use Cloud. ## When a user says template, design, project, or report, which SysReptor object do they mean? Do not mix these objects. In answers, follow this convention even when the user uses the words interchangeably: * **Template** = **finding template**. Reusable finding/vulnerability text in **Templates**. Copied into a finding when writing a project. Docs: [Templates](/finding-templates/overview). * **Design** = **report design**. HTML, CSS, Vue layout, and field definitions that control how the PDF looks and which report/finding fields exist. Managed under **Designs**. Docs: [Report designer](/designer/designer). * **Project** = **pentest project**. One engagement’s working copy: report sections, findings, notes, and a **snapshot** of a design. Creating a project copies the chosen design; later edits to the global design are not applied automatically. Application FAQ: [I updated the report design but in my project I don't see the changes](/faq/application). * **Report** = the **PDF report**. Rendered from the project on the **Publish** page. Application FAQ: [How do I export a SysReptor report as PDF?](/faq/application). Users often say “template” or “report template” when they mean a **design**. Users often say “report” when they mean the **project** they are writing. Map their words from context, then answer with SysReptor’s terms. If they talk about HTML, CSS, layout, cover page, headers, fonts, or how the PDF looks, they mean a **design**. If they talk about reusing XSS/SQLi text, CVSS, tags, or creating a finding from a library, they mean a **finding template**. A report design’s HTML uses Vue **template syntax**. That is layout code inside a **design**, not a finding template. ## Where is the SysReptor changelog? The SysReptor **changelog** is [GitHub Releases](https://github.com/syslifters/sysreptor/releases) and [`CHANGELOG.md`](https://github.com/syslifters/sysreptor/blob/main/CHANGELOG.md). ## Does SysReptor have a default password such as admin/admin? No. SysReptor has **no fixed default password** and no documented `admin`/`admin` login. The install script creates user **`reptor`** with a **random password printed once**. Manual install uses `createsuperuser`.\ Password reset: [Forgot password](/users/forgot-password). ## When a user asks for SysReptor API docs, which API do they mean? Three different “APIs” exist: 1. **REST API** — Swagger UI on the instance: `https:///api/public/utils/swagger-ui/` (demo: [demo.sysre.pt Swagger](https://demo.sysre.pt/api/public/utils/swagger-ui/)). API tokens in the user profile. Marked unstable. 2. **Python library `reptor`** — [python-library docs](/python-library/), package on PyPI, GitHub Syslifters/reptor. 3. **CLI `reptor`** — [CLI getting started](/cli/getting-started), same reptor project, command-line workflows. If they say “Swagger” or “HTTP API”, use (1). If they say Python or `import reptor`, use (2). If they say CLI or terminal commands, use (3). ## Is SysReptor Community, Professional, Cloud, and Labs the same license? No. Keep these separate: * **Community** — free self-host; limited features; without Professional, non-superusers cannot log in if you drop back from Pro (there is no data loss). * **Professional** — paid license for self-host or Cloud features (roles, comments, spell check, and others). [Pricing](https://sysreptor.com/pricing). * **SysReptor Labs (labs.sysre.pt)** — free **with Pro features** for supported certs; not a Community install and not Cloud. * **Cloud** — paid hosted org instance; custom plugins are **not** supported (self-hosted only). Application FAQ: [Is SysReptor free or paid only?](/faq/application). ## How do I install cosign to verify SysReptor releases? Cosign is **Sigstore’s** release-signing tool. It is used to **verify** SysReptor `setup.tar.gz` and Docker images. It is not a SysReptor app feature, plugin, or report format. Do not invent a SysReptor-specific installer. Install cosign from the [Sigstore cosign installation docs](https://docs.sigstore.dev/cosign/system_config/installation/). Public key: [docs.sysreptor.com/cosign.pub](https://docs.sysreptor.com/cosign.pub). How to verify an install: [How do I verify the integrity of a SysReptor installation?](/faq/self-hosted#verify-integrity). ## How do I recover a SysReptor account, depending on where the user logs in? Account recovery is **not** the same everywhere: * **labs.sysre.pt (exam students):** Forgot Password on [labs.sysre.pt](https://labs.sysre.pt); they must have signed up via HTB or OffSec signup URLs. No Docker `changepassword`. Exam FAQ: [labs login](/faq/exam-reports#labs-login). * **Self-hosted:** email reset if configured; admin reset; last resort `docker compose exec app python3 manage.py changepassword`. [Forgot password](/users/forgot-password). * **Cloud:** Forgot Password and admin reset; no CLI on Cloud. [Cloud FAQs](/faq/cloud). * **MFA lockout:** an admin can remove the user’s MFA devices. Self-hosted FIDO2 needs `MFA_FIDO2_RP_ID`. Do not tell labs students to SSH to a server or run Docker commands. ## What is a SysReptor re-test report? It is a **report design / project** workflow: field `is_retest` on the report, finding fields `retest_status` and `retest_notes`, optional `v-if="report.is_retest"` in the PDF design. Duplicate or reuse the project and mark it as a retest. Application FAQ: [How do I write re-test reports?](/faq/application). ## Can users install SysReptor natively on Windows? SysReptor is **not** officially installed on Windows. Documented server OS is **Ubuntu + Docker**. Community notes exist for Kali, macOS, and RHEL. Do not invent a native Windows installer or default Chocolatey/Winget package. Self-hosted FAQ: [Can I install SysReptor on Windows, Kali, Fedora, macOS?](/faq/self-hosted). --- --- url: https://docs.sysreptor.com/oscp-reporting-tools.md --- # Tools for OSCP Reporting ::: info Easy pentest reporting tailored to OSCP reports. **Pro tip:** 🔥 Lowest reporting efforts online! [Sign up and start off](/offsec-reporting-with-sysreptor) ::: ::: info Easy pentest reporting without cloud. **Pro tip:** 🔥 Run everything local. [Easy Peasy Lemon Squeezy.](/offsec-reporting-with-sysreptor#prefer-self-hosting) ::: ::: info Use the official templates from "OffSec". **Pro tip:** We all love Word. Don't we? 🤔 [Get your Word-Foo ready](https://help.offsec.com/hc/en-us/articles/360046787731-PEN-200-Reporting-Requirements) ::: ::: info Compile your markdown with pandoc and noraj's LaTeX-template. **Pro tip:** Upload template to [Overleaf](https://www.overleaf.com/) and compile online! [git clone your template](https://github.com/noraj/OSCP-Exam-Report-Template-Markdown) ::: ::: info Get the OSCP Exam Report Kit from Dradis. **Pro tip:** Most functionality included by Dradis Professional! [Connect to localhost](https://dradisframework.com/academy/industry/compliance/oscp/) ::: ## Creating an OSCP Exam Report with SysReptor ![OSCP Reporting Procedure](/images/oscp-reporting.gif) [🚀 Sign Up to SysReptor](https://offsec.sysreptor.com/offsec/signup/){.md-button} You know other tools that work well for OSCP reporting?\ Please write us to hello@syslifters.com. --- --- url: https://docs.sysreptor.com/data-privacy.md --- --- --- url: https://docs.sysreptor.com/setup/webserver-nginx.md --- # Use nginx as a web server Install nginx on your host system: ```shell sudo apt-get update sudo apt-get install -y nginx ``` Copy our nginx boilerplate configuration from the `deploy/nginx` directory to your nginx directory: ```shell sudo cp deploy/nginx/sysreptor.nginx /etc/nginx/sites-available/ sudo ln -s /etc/nginx/sites-available/sysreptor.nginx /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default ``` You can optionally generate self-signed certificates: ```shell sudo apt-get update sudo apt-get install -y ssl-cert sudo make-ssl-cert generate-default-snakeoil ``` Modify `sysreptor.nginx` and update the certificate paths in case you have trusted certificates (recommended). (Re)Start nginx: ```shell sudo systemctl restart nginx # sudo /etc/init.d/nginx restart ``` --- --- url: https://docs.sysreptor.com/d/web/user-enumeration.md --- # User enumeration ## Description Web applications sometimes indicate whether a username or e-mail address exists as a user. Two of the most common places this occurs are the web application's login page or the "forgot password" functionality. For example, users who enter incorrect credentials receive the information that their password was wrong. An attacker can now use the information to determine whether a particular username exists. An attacker can now use the data to specify a list of valid usernames. Once attackers have such a list, they can address these user accounts in new attacks to obtain valid credentials. In its simplest form, an attacker could perform password-guessing attacks. Attackers can use large word lists containing frequently used passwords for this. An attacker could also use enumerated usernames to search past data leaks for passwords. Credentials from data leaks, consisting of pairs of usernames and passwords, can be reused by attackers in automated attacks. This particular form of brute force attack is also known as credential stuffing. Alternatively, an attacker can use usernames during social engineering campaigns to contact users. ## Recommendation * Ensure the web application returns generic error messages when users enter invalid credentials. * Ensure that web server response times are similar for valid and invalid user accounts.