diff --git a/docs/content/psirt/advisories.md b/docs/content/psirt/advisories.md index 2d197a5b82..d4e45066a4 100644 --- a/docs/content/psirt/advisories.md +++ b/docs/content/psirt/advisories.md @@ -2,7 +2,7 @@ title: "Advisories" description: "Write, review, publish and revise your own security advisories" draft: false -weight: 8 +weight: 9 pro-feature: true --- diff --git a/docs/content/psirt/cases.md b/docs/content/psirt/cases.md index 829ad390c6..da395d5e6c 100644 --- a/docs/content/psirt/cases.md +++ b/docs/content/psirt/cases.md @@ -2,7 +2,7 @@ title: "Cases and SLA" description: "Group matches into work items, and track the triage obligation on them" draft: false -weight: 7 +weight: 8 pro-feature: true --- diff --git a/docs/content/psirt/dashboard.md b/docs/content/psirt/dashboard.md index ec56feddf4..98456b2aee 100644 --- a/docs/content/psirt/dashboard.md +++ b/docs/content/psirt/dashboard.md @@ -2,7 +2,7 @@ title: "PSIRT dashboard" description: "A shared dashboard template that answers \"am I affected?\" first" draft: false -weight: 9 +weight: 10 pro-feature: true --- diff --git a/docs/content/psirt/feed-findings.md b/docs/content/psirt/feed-findings.md index f43ff4a13b..85a33730a5 100644 --- a/docs/content/psirt/feed-findings.md +++ b/docs/content/psirt/feed-findings.md @@ -2,7 +2,7 @@ title: "Feed Findings" description: "Triage incoming advisories and read the tri-state answer to 'am I affected?'" draft: false -weight: 6 +weight: 7 pro-feature: true --- @@ -48,6 +48,16 @@ Advisories still moving through the pipeline show it: an advisory waiting on enrichment has not yet been matched, because enrichment is what supplies the version ranges matching needs. +### The Feed Rules column + +Where [Feed Rules](../feed-rules/) are configured, the queue carries their verdict: +the score a rule gave the advisory, a star where one marked it a favourite, and any +tags. The column sorts, and the queue filters on minimum score, favourites and tag. + +On a queue where nothing has matched yet, this is the only column carrying a +judgement — which is what makes tens of thousands of advisories sortable rather +than merely searchable. + ## Verified and unverified matches A match tells you a component and an advisory correspond. **Verified** tells you @@ -86,6 +96,11 @@ changes it. matters outlasts the rule that disagreed. - **Re-match** queues the advisory for another matching pass. Useful after an SBOM import or after correcting a component's version. +- **Add to case** opens a case on the advisory, or attaches it to one already open. + This does **not** require the advisory to have matched anything: an advisory your + inventory could not answer for — no SBOM imported, a component the publisher + spells differently, or one that arrived an hour ago — is frequently the one most + worth investigating. Matches come along where they exist. - On a match: **confirm**, mark **false positive**, or leave notes. Everything else on a match is the engine's record of why it exists and is read-only. diff --git a/docs/content/psirt/feed-rules.md b/docs/content/psirt/feed-rules.md new file mode 100644 index 0000000000..34542e714d --- /dev/null +++ b/docs/content/psirt/feed-rules.md @@ -0,0 +1,117 @@ +--- +title: "Feed Rules" +description: "Score, tag, star and mute advisories from their own text, before anything touches your inventory" +draft: false +weight: 5 +pro-feature: true +--- + +A busy set of feeds produces tens of thousands of advisories, and on a new +instance none of them have matched anything yet. Column filters sort what you can +already describe; they cannot say *"from now on, anything claiming active +exploitation goes to the top"*. Feed Rules is where you say that once. + +A feed rule reads the advisory's own text as it arrives — before any comparison +against your inventory — and does one or more of four things: + +- **adds points**, which raises the advisory in the triage queue's ranking; +- **adds a tag**, which you can then filter the queue by; +- **marks it a favourite**, which stars the row; +- **suppresses it**, which keeps it out of the active queue entirely. + +Because they read only the advisory, feed rules work with no SBOM and no matching +rules. They are usually the first thing worth configuring. + +## Start from a starter + +The **Starters** button installs a ready-made rule. Each becomes an ordinary rule +afterwards — editable, stoppable, deletable. + +| Starter | What it does | +|---|---| +| Exploited in the wild | Scores and stars advisories whose text says exploitation is *happening*, not that it is possible. The highest-signal thing available from text alone. | +| Named in ransomware activity | Tags advisories tying the vulnerability to ransomware operators. | +| Exploit code is public | Scores public proof-of-concept or exploit code — lower than in-the-wild, because they are different claims. | +| A vendor you run | Scores and tags every advisory naming one vendor. Install one per vendor that matters to you. | +| Mute newsletters and event announcements | Suppresses the items a broad feed carries that are not advisories at all. | + +Starters are offered, never installed for you. The muting rule in particular is an +editorial decision about what you do not want to see, and that is not a decision to +make on somebody's behalf. + +## Writing a rule + +A rule is conditions plus actions. + +**Conditions** read one advisory field — the title and description together +(*content*), the title alone, the CVE list, or the source URL — with one of four +tests: contains any of, contains all of, contains none of, or matches a regular +expression. Terms are comma-separated. + +**Whole word** is on by default and matters more than it looks. Without it, a term +like `SSL` matches inside "assembly" and a scoring rule quietly stops meaning +anything. It does not apply to a regular expression, which can anchor itself. + +**Actions** are the four above. A rule that matches and does nothing cannot be +turned on, and neither can a rule with no conditions — both are rules that look +configured and have no effect. + +Two settings control how rules interact: + +- **Order** — lower numbers run first. +- **Stops after matching** — normally every rule gets a turn, so points from + several rules add up. A rule that stops the pass ends it, which is how a + suppressing rule can pre-empt everything after it. + +### Preview before you turn it on + +**Preview against recent advisories** runs the rule over a window of real +advisories and reports how many it would have caught, listing a sample. + +Use it every time. A feed rule is written against a corpus nobody can read, and +the two ways it goes wrong look nothing alike from the form: + +- a rule that catches **nothing** is indistinguishable from a rule that is switched + off; +- a rule that catches **most of the queue** sorts nothing, while looking like it is + working. + +The preview names both cases rather than only reporting a number. + +## Scope + +A rule applies to **every feed** by default, or to one feed. Per-feed scope is for +rules that only make sense for one publisher — a vendor's own PSIRT feed where +every item is about that vendor, say. + +Pre-filtering can also be turned off per feed, on the feed's own settings. + +## Re-score recent advisories + +Feed rules run as advisories arrive, so a rule written today does not touch +anything already in the queue — while the backlog in front of you is usually the +reason you wrote it. **Re-score Recent** applies the current rules to the most +recent advisories. + +Re-scoring recomputes everything from the current rules: scores, tags and stars +are replaced rather than added to, and rule-driven suppression is applied or +lifted to match. Two things it will not touch: + +- an advisory **you** suppressed by hand; +- an advisory you **unsuppressed** by hand, which is permanently exempt from rules + suppressing it again. + +## Reading the results in the queue + +Feed Findings carries a **Feed Rules** column showing the score, a star where a +rule marked one, and any tags. The column sorts, and the queue filters on minimum +score, favourites, and tag. + +That is the payoff: after a few rules, "what should I open next" is answerable by +sorting a column instead of reading titles. + +## Deleting a rule + +Scores and tags a rule applied stay on advisories already scored until the next +re-score. Deleting a **suppressing** rule lifts its suppression on the next +scoring pass, so advisories it was hiding come back into the queue. diff --git a/docs/content/psirt/matching-rules.md b/docs/content/psirt/matching-rules.md index 976ec6d2ff..f7919c2b65 100644 --- a/docs/content/psirt/matching-rules.md +++ b/docs/content/psirt/matching-rules.md @@ -2,7 +2,7 @@ title: "Matching Rules" description: "Write your own matching rules, and understand why some of them are refused" draft: false -weight: 5 +weight: 6 pro-feature: true --- @@ -97,6 +97,47 @@ avoid colliding with the template, its loose conditions are paired automatically and it starts out applying to every product so it is never born silently inert — narrow it from the scope control afterwards. +### Start From a Template + +**Start From a Template** is the shortest route to a rule that works, and on a new +instance it is the recommended one. The blank rule form invites the shape the trust +layer refuses: "match anything called django" reads like the obvious rule and is +exactly the one-sided keyword that cannot be enabled. + +Every template is labelled with what it needs: + +- **No SBOM needed** — the rule matches an asset directly from the advisory text. + These work on any instance, including one that has never imported an SBOM. +- **Needs SBOM** — the rule matches a component in your dependency inventory. With + no SBOM imported it will not match anything, however well written. + +Templates that need no SBOM are listed first, because most instances have no +inventory yet and a dependency rule there is silent rather than wrong. + +Each template asks for one term — a vendor, a piece of software, a component, or a +package URL — and fills it in throughout the copy. **A template's rules ship +switched off**, and the copy is only enabled when the term you supplied produces a +rule that clears the same grading a hand-written rule has to clear. Supply a term +too broad to enable (say, a vendor called "linux") and the copy is created stopped, +with the usual explanation of why. + +## What to do when you have no SBOM + +A dependency-target rule matches a component in your inventory. With no inventory, +it matches nothing — which looks identical to a rule that is simply not working, +and is the most common reason people conclude matching is broken. + +Rules targeting an **asset** need no inventory at all. They compare the advisory +text against the asset directly, so "any advisory mentioning Siemens" is expressible +without importing anything. When your instance has no components loaded, the rule +editor starts new rules on the asset target for that reason and says so beneath the +selector. + +The three no-SBOM templates cover the usual shapes: an advisory naming a vendor you +run, one naming a piece of software you run, and one carrying a CPE you publish. +The CPE shape is the most precise of the three, because it compares identifiers +rather than prose. + ## Deleting a group Deleting a group does not delete its rules; they survive as standalone rules. A diff --git a/docs/content/psirt/settings.md b/docs/content/psirt/settings.md index 0a45b08d1f..33bb539354 100644 --- a/docs/content/psirt/settings.md +++ b/docs/content/psirt/settings.md @@ -2,7 +2,7 @@ title: "PSIRT Settings" description: "Case-worthiness calibration, the \"new\" item window, and what counts as a material change" draft: false -weight: 11 +weight: 12 pro-feature: true --- diff --git a/docs/content/psirt/sla-policies.md b/docs/content/psirt/sla-policies.md index 655a3ed954..c8ce8e849e 100644 --- a/docs/content/psirt/sla-policies.md +++ b/docs/content/psirt/sla-policies.md @@ -2,7 +2,7 @@ title: "SLA Policies" description: "Tune how long each severity tier gets before a PSIRT clock warns and breaches" draft: false -weight: 10 +weight: 11 pro-feature: true ---