Skip to content
All templates

Operations 3 steps · 13 fields

Security vulnerability report

Responsible disclosure intake: affected asset, type, impact, reproduction steps and credit.

Get a hosted link and a responses inbox in a minute. No backend, no credit card.

Or set it up yourself

Live preview

Form definition JSON · 134 lines
{  "id": "security-report",  "title": "Report a vulnerability",  "submit": { "label": "Send report" },  "steps": [    {      "id": "issue",      "title": "The vulnerability",      "fields": [        {          "key": "asset",          "type": "text",          "label": "Affected URL, app or component",          "validation": { "required": true }        },        {          "key": "type",          "type": "select",          "label": "Vulnerability type",          "options": [            { "value": "xss", "label": "Cross-site scripting" },            { "value": "rce", "label": "Remote code execution" },            {              "value": "injection",              "label": "SQL or command injection"            },            { "value": "csrf", "label": "Cross-site request forgery" },            { "value": "auth", "label": "Authentication or session" },            { "value": "access", "label": "Broken access control" },            { "value": "exposure", "label": "Sensitive data exposure" },            { "value": "ssrf", "label": "Server-side request forgery" },            { "value": "other", "label": "Other" }          ],          "validation": { "required": true }        },        {          "key": "typeOther",          "type": "text",          "label": "What kind of issue?",          "show": [{ "field": "type", "eq": "other" }],          "validation": { "required": true }        },        {          "key": "severity",          "type": "radio",          "label": "Your severity estimate",          "layout": "inline",          "options": [            { "value": "critical", "label": "Critical" },            { "value": "high", "label": "High" },            { "value": "medium", "label": "Medium" },            { "value": "low", "label": "Low" },            { "value": "unsure", "label": "Not sure" }          ],          "validation": { "required": true }        }      ]    },    {      "id": "details",      "title": "Details",      "fields": [        {          "key": "steps",          "type": "textarea",          "label": "Steps to reproduce",          "rows": 5,          "validation": { "required": true }        },        {          "key": "impact",          "type": "textarea",          "label": "What could an attacker do with it?",          "rows": 3,          "validation": { "required": true }        },        {          "key": "poc",          "type": "text",          "label": "Link to a proof of concept",          "placeholder": "https://",          "helperText": "Use a private link. Don’t publish details yet."        },        {          "key": "cvss",          "type": "text",          "label": "CVSS score or vector",          "placeholder": "CVSS:3.1/AV:N/AC:L/…"        },        {          "key": "discoveredAt",          "type": "date",          "label": "When did you find it?"        }      ]    },    {      "id": "researcher",      "title": "About you",      "fields": [        {          "key": "name",          "type": "text",          "label": "Name or handle",          "validation": { "required": true }        },        {          "key": "email",          "type": "email",          "label": "Email",          "inputMode": "email",          "validation": { "required": true }        },        {          "key": "credit",          "type": "radio",          "label": "Do you want public credit once it’s fixed?",          "layout": "inline",          "options": [            { "value": "yes", "label": "Yes" },            { "value": "no", "label": "No, keep me anonymous" }          ],          "validation": { "required": true }        },        {          "key": "policy",          "type": "checkbox",          "label": "I won’t access other users’ data and will keep this private until it’s fixed",          "validation": { "required": true }        }      ]    }  ]}

Use it with the npm packages ​

Copy the JSON into a file in your app, install the renderer and pass the definition to it. The same JSON works with @formhaus/vue.

sh
npm i @formhaus/core @formhaus/react
tsx
import { FormRenderer } from '@formhaus/react';
import '@formhaus/core/style.css';
import definition from './form.json';

export function Form() {
  return (
    <FormRenderer
      definition={definition}
      onSubmit={(values) => console.log(values)}
    />
  );
}

See Getting started for validation, steps and custom components.

Formhaus is MIT licensed. Legal