<!-- SAMPLE: generated for illustration on 2026-10-30 from an offline FIXTURE site (fictional business, fictional DNS). -->
# Website audit: acme-bakery.example

Prepared by Acme Digital · 2026-10-30 · https://acme-bakery.example/

> Passive, point-in-time assessment of public pages and public DNS. This report is not a penetration test, security certification, legal or compliance opinion, and does not promise rankings, traffic or security. Absence of a finding does not prove absence of a problem.

## Executive summary

We read 4 pages of acme-bakery.example and checked SEO, Security (passive), Links, Email authentication, AI readiness on 2026-10-30, using passive, read-only requests. We found 31 issues: 5 high, 13 medium, 11 low, 2 info. Start with: No /llms.txt; No DMARC record; Missing strict-transport-security. By area: SEO poor (38/100), Security (passive) poor (48/100), Links good (88/100), Email authentication needs work (78/100), AI readiness good (88/100). 1 check could not run or was skipped; they are listed under coverage and nothing was assumed for them. This is a point-in-time, passive assessment, not a penetration test.

| Area | Health | Score | Findings |
|---|---|---|---|
| SEO | Poor (partial) | 38 | 12 |
| Security (passive) | Poor | 48 | 10 |
| Links | Good | 88 | 2 |
| Email authentication | Needs work | 78 | 4 |
| AI readiness | Good | 88 | 3 |

### Top priorities

1. **P1** No /llms.txt. (AI readiness, high, effort S) [F01]
2. **P1** No DMARC record. (Email authentication, high, effort S) [F02]
3. **P1** Missing strict-transport-security. (Security (passive), high, effort S) [F03]
4. **P1** Plain HTTP does not redirect to HTTPS. (Security (passive), high, effort S) [F04]
5. **P1** No meta description (3 of 4 pages checked). (SEO, high, effort S) [F05]

## Findings

### F01 · No /llms.txt.

- **Area:** AI readiness · **Severity:** high · **Priority:** P1 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** AI assistants have no short summary of the site and its key pages.
- **Evidence:**
  - No /llms.txt for AI assistants. <https://acme-bakery.example/llms.txt> · file, seo-page, observed 2026-10-30T06:38:14.413Z
  - No /llms.txt. <https://acme-bakery.example/llms.txt> · value: `{"present":false,"links":0}` · file, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Publish /llms.txt (llmstxt.org): an H1 with the site name, a one-paragraph summary and Markdown links to the key pages.
- **Where:** Files at the web root of the site.

```
https://acme-bakery.example/llms.txt:
# Site name
> One-paragraph summary of what the business offers.

## Key pages
- [Services](https://acme-bakery.example/services): what we do
- [Contact](https://acme-bakery.example/contact): how to reach us
```

**Verify:** `curl -s https://acme-bakery.example/llms.txt   (starts with "# ")`

### F02 · No DMARC record.

- **Area:** Email authentication · **Severity:** high · **Priority:** P1 · **Effort:** S (0.5-2 h) · **Owner:** DNS admin
- **Basis:** observed
- **Impact:** Anyone can send email that claims to be from this domain and receivers have no policy to reject it.
- **Evidence:**
  - No DMARC record. · value: `{"name":"_dmarc.acme-bakery.example","record":null}` · dns, security-scan-lite, observed 2026-10-30T06:38:14.449Z
  - No DMARC record. · value: `{"name":"_dmarc.acme-bakery.example","record":null}` · dns, email-auth, observed 2026-10-30T06:38:14.427Z
- **Fix:** Publish TXT \_dmarc.acme-bakery.example: "v=DMARC1; p=none; rua=mailto:dmarc@acme-bakery.example" then move to quarantine/reject.
- **Where:** DNS zone of acme-bakery.example (at the DNS host).

```
_dmarc.acme-bakery.example.  TXT "v=DMARC1; p=none; rua=mailto:dmarc@acme-bakery.example"   (then p=quarantine, then p=reject)
```

**Verify:** `dig TXT _dmarc.acme-bakery.example +short`

### F03 · Missing strict-transport-security.

- **Area:** Security (passive) · **Severity:** high · **Priority:** P1 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** The first visit (or a typed http:// link) can be downgraded to plain HTTP by an attacker on the network.
- **Evidence:**
  - The response from https://acme-bakery.example/ (HTTP 200) had no strict-transport-security header. <https://acme-bakery.example/> (HTTP 200) · value: `none` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - The response from https://acme-bakery.example/ had no strict-transport-security header. <https://acme-bakery.example/> · value: `none` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add Strict-Transport-Security: max-age=31536000; includeSubDomains
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Strict-Transport-Security: max-age=31536000; includeSubDomains
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -i strict-transport-security`

### F04 · Plain HTTP does not redirect to HTTPS.

- **Area:** Security (passive) · **Severity:** high · **Priority:** P1 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - Plain HTTP does not redirect to HTTPS. <http://acme-bakery.example/> · value: `no redirect (HTTP 200)` · http, security-headers, observed 2026-10-30T06:38:14.449Z
  - Plain HTTP does not redirect to HTTPS. <http://acme-bakery.example/> · value: `no redirect (HTTP 200)` · http, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Send a 301 from http:// to https:// for every path.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
http://acme-bakery.example/* -> 301 -> https://acme-bakery.example/*
```

**Verify:** `curl -sI http://acme-bakery.example/   (expect 301 and Location: https://...)`

### F05 · No meta description (3 of 4 pages checked).

- **Area:** SEO · **Severity:** high · **Priority:** P1 · **Effort:** S (0.5-2 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Search engines and AI tools write their own snippet; click-through usually drops.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/about>, <https://acme-bakery.example/contact>
- **Evidence:**
  - No meta description. <https://acme-bakery.example/> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.413Z
  - No meta description. <https://acme-bakery.example/about> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.415Z
  - No meta description. <https://acme-bakery.example/contact> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.422Z
  - No meta description. <https://acme-bakery.example/> · html, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Add a 70-160 character meta description that summarises the page.
- **Where:** Page templates / CMS page settings.

```
<meta name="description" content="One or two sentences (70-160 characters) that say what this page offers and for whom.">
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F06 · No X-Frame-Options or CSP frame-ancestors (clickjacking).

- **Area:** Security (passive) · **Severity:** medium · **Priority:** P3 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Other sites can frame these pages and trick visitors into clicks.
- **Evidence:**
  - No X-Frame-Options header and no frame-ancestors directive in the response from https://acme-bakery.example/. <https://acme-bakery.example/> · value: `{"x-frame-options":null,"content-security-policy":null}` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - No X-Frame-Options header and no frame-ancestors directive in the response from https://acme-bakery.example/. <https://acme-bakery.example/> · value: `{"x-frame-options":null,"content-security-policy":null}` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add X-Frame-Options: SAMEORIGIN or CSP frame-ancestors 'self'.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Content-Security-Policy: frame-ancestors 'self'   (or X-Frame-Options: SAMEORIGIN)
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -iE "x-frame-options|frame-ancestors"`

### F07 · Missing x-content-type-options.

- **Area:** Security (passive) · **Severity:** medium · **Priority:** P3 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - The response from https://acme-bakery.example/ (HTTP 200) had no x-content-type-options header. <https://acme-bakery.example/> (HTTP 200) · value: `none` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - The response from https://acme-bakery.example/ had no x-content-type-options header. <https://acme-bakery.example/> · value: `none` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add X-Content-Type-Options: nosniff
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
X-Content-Type-Options: nosniff
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -i x-content-type-options`

### F08 · 1 JSON-LD block(s) do not parse as JSON.

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/contact>
- **Evidence:**
  - JSON-LD parse errors. <https://acme-bakery.example/contact> · value: `["Expected double-quoted property name in JSON at position 78 (line 1 column 79)"]` · html, structured-data, observed 2026-10-30T06:38:14.422Z
- **Fix:** Fix the JSON syntax of the ld+json block (validate with validator.schema.org).
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the structured-data check) after the change and confirm this finding is gone.`

### F09 · No canonical link (3 of 4 pages checked).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/about>, <https://acme-bakery.example/contact>
- **Evidence:**
  - No canonical link. <https://acme-bakery.example/> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.413Z
  - No canonical link. <https://acme-bakery.example/about> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.415Z
  - No canonical link. <https://acme-bakery.example/contact> (HTTP 200) · value: `none` · html, seo-page, observed 2026-10-30T06:38:14.422Z
  - No canonical link. <https://acme-bakery.example/> · html, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Add \<link rel="canonical"\> pointing to the preferred URL.
- **Where:** Page templates / CMS page settings.

```
<link rel="canonical" href="https://acme-bakery.example/this-page/">
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F10 · Page titles are too short or too long (2 of 4 pages checked).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** S (0.5-2 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/about>
- **Evidence:**
  - Title is 11 characters. <https://acme-bakery.example/> (HTTP 200) · value: `Acme Bakery` · html, seo-page, observed 2026-10-30T06:38:14.413Z
  - Title is 77 characters. <https://acme-bakery.example/about> (HTTP 200) · value: `About Acme Bakery - family bakers since 1987 in George Town, Penang, Malaysia` · html, seo-page, observed 2026-10-30T06:38:14.415Z
- **Fix:** Aim for roughly 30-60 characters with the main topic first.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F11 · No DKIM key found at 30 common selectors (it may use a custom selector).

- **Area:** Email authentication · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** DNS admin
- **Basis:** inferred (Only 30 common DKIM selectors were queried; a custom selector would not be seen, so DKIM may exist.)
- **Impact:** Affects whether others can send email that looks like it comes from this domain, and whether real mail is delivered.
- **Evidence:**
  - No DKIM key found at 30 common selectors (it may use a custom selector). · value: `{"name":"<selector>._domainkey.acme-bakery.example","selectors_checked":30,"selectors_found":[]}` · dns, security-scan-lite, observed 2026-10-30T06:38:14.449Z
  - No DKIM key found at 30 common selectors (it may use a custom selector). · value: `{"name":"<selector>._domainkey.acme-bakery.example","selectors_checked":30,"selectors_found":[]}` · dns, email-auth, observed 2026-10-30T06:38:14.427Z
- **Fix:** Enable DKIM signing at your mail provider and publish its key.
- **Where:** DNS zone of acme-bakery.example (at the DNS host).

**Verify:** `dig TXT <selector>._domainkey.acme-bakery.example +short   (selector from your mail provider)`

### F12 · 2 of 8 links checked on the home page are broken.

- **Area:** Links · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Visitors and crawlers hit dead ends; link value is wasted.
- **Evidence:**
  - Linked from https://acme-bakery.example/; answered HTTP 404. <https://acme-bakery.example/old-page> (HTTP 404) · http_status, broken-links, observed 2026-10-30T06:38:14.462Z
  - Linked from https://acme-bakery.example/; failed (dns\_not\_found). <https://dead-supplier.example/catalog> · http_status, broken-links, observed 2026-10-30T06:38:14.462Z
- **Fix:** Fix each target or 301-redirect it, and update the links.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the broken-links check) after the change and confirm this finding is gone.`

### F13 · A page linked from the home page answers HTTP 404.

- **Area:** Links · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Visitors and crawlers hit dead ends; link value is wasted.
- **Pages:** <https://acme-bakery.example/old-page>
- **Evidence:**
  - https://acme-bakery.example/old-page answered HTTP 404. <https://acme-bakery.example/old-page> (HTTP 404) · http_status, page-fetch, observed 2026-10-30T06:38:14.465Z
- **Fix:** Fix the page or 301-redirect it, and update the links that point to it.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the page-fetch check) after the change and confirm this finding is gone.`

### F14 · No XML sitemap found (robots.txt or /sitemap.xml).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** New and deep pages are discovered more slowly.
- **Evidence:**
  - No XML sitemap found (robots.txt or /sitemap.xml). <https://acme-bakery.example/sitemap.xml> · file, seo-page, observed 2026-10-30T06:38:14.413Z
  - No XML sitemap found (robots.txt Sitemap: line or /sitemap.xml). <https://acme-bakery.example/> · value: `{"found":false,"url":null,"urls":null,"in_robots_txt":false}` · file, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Publish /sitemap.xml and reference it in robots.txt.
- **Where:** Page templates / CMS page settings.

```
https://acme-bakery.example/sitemap.xml  +  robots.txt line: Sitemap: https://acme-bakery.example/sitemap.xml
```

**Verify:** `curl -sI https://acme-bakery.example/sitemap.xml   (200, XML)`

### F15 · No JSON-LD structured data (2 of 4 pages checked).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** No eligibility for rich results; machines get less certain facts about the business.
- **Pages:** <https://acme-bakery.example/about>, <https://acme-bakery.example/menu>
- **Evidence:**
  - No JSON-LD structured data. <https://acme-bakery.example/about> (HTTP 200) · value: `[]` · html, seo-page, observed 2026-10-30T06:38:14.415Z
  - No JSON-LD structured data. <https://acme-bakery.example/menu> (HTTP 200) · value: `[]` · html, seo-page, observed 2026-10-30T06:38:14.421Z
- **Fix:** Add schema.org JSON-LD (Organization/LocalBusiness/Article/Product as fits).
- **Where:** Page templates / CMS page settings.

```
<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"...","url":"https://acme-bakery.example/","logo":"https://acme-bakery.example/logo.png"}</script>
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F16 · JSON-LD missing required properties: LocalBusiness (address).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** M (2-8 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>
- **Evidence:**
  - JSON-LD items with missing required properties. <https://acme-bakery.example/> · value: `[{"type":["LocalBusiness"],"missing_required":["address"]}]` · html, structured-data, observed 2026-10-30T06:38:14.413Z
- **Fix:** Add the required properties so the markup is eligible for rich results (validate with validator.schema.org or Google's Rich Results Test).
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the structured-data check) after the change and confirm this finding is gone.`

### F17 · Missing content-security-policy.

- **Area:** Security (passive) · **Severity:** medium · **Priority:** P3 · **Effort:** L (1-3 days) · **Owner:** Developer
- **Basis:** observed
- **Impact:** No browser-enforced limit on which scripts may run if an injection bug exists.
- **Evidence:**
  - The response from https://acme-bakery.example/ (HTTP 200) had no content-security-policy header. <https://acme-bakery.example/> (HTTP 200) · value: `none` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - The response from https://acme-bakery.example/ had no content-security-policy header. <https://acme-bakery.example/> · value: `none` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add a Content-Security-Policy (start with default-src 'self' and loosen as needed; report-only first).
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Content-Security-Policy-Report-Only: default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'
(start in Report-Only, then switch to Content-Security-Policy)
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -i content-security-policy`

### F18 · Thin content: few words of visible text (2 of 4 pages checked).

- **Area:** SEO · **Severity:** medium · **Priority:** P3 · **Effort:** L (1-3 days) · **Owner:** Content
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/contact>
- **Evidence:**
  - Only about 120 words of visible text. <https://acme-bakery.example/> (HTTP 200) · value: `120` · html, seo-page, observed 2026-10-30T06:38:14.413Z
  - Only about 90 words of visible text. <https://acme-bakery.example/contact> (HTTP 200) · value: `90` · html, seo-page, observed 2026-10-30T06:38:14.422Z
  - Only about 120 words of text on the page. <https://acme-bakery.example/> · value: `{"word_count":120,"markdown_chars":671,"scripts":1}` · measurement, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Add useful content that answers the visitor's question.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F19 · No TLS-RPT.

- **Area:** Email authentication · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** DNS admin
- **Basis:** observed
- **Impact:** Affects whether others can send email that looks like it comes from this domain, and whether real mail is delivered.
- **Evidence:**
  - No TLS-RPT. · value: `{"name":"acme-bakery.example"}` · dns, email-auth, observed 2026-10-30T06:38:14.427Z
- **Fix:** Optional: publish \_smtp.\_tls TXT "v=TLSRPTv1; rua=mailto:..."
- **Where:** DNS zone of acme-bakery.example (at the DNS host).

```
_smtp._tls.acme-bakery.example.  TXT "v=TLSRPTv1; rua=mailto:tls-reports@acme-bakery.example"
```

**Verify:** `dig TXT _smtp._tls.acme-bakery.example +short`

### F20 · Cookie PHPSESSID is missing Secure, HttpOnly, SameSite.

- **Area:** Security (passive) · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - Cookie PHPSESSID is missing Secure, HttpOnly, SameSite. <https://acme-bakery.example/> · value: `[{"name":"PHPSESSID","secure":false,"httponly":false,"samesite":null}]` · header, security-headers, observed 2026-10-30T06:38:14.449Z
- **Fix:** Set Secure; HttpOnly (unless JS needs it); SameSite=Lax on cookies.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax
```

**Verify:** `Re-run this report (or the security-headers check) after the change and confirm this finding is gone.`

### F21 · Missing permissions-policy.

- **Area:** Security (passive) · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - The response from https://acme-bakery.example/ (HTTP 200) had no permissions-policy header. <https://acme-bakery.example/> (HTTP 200) · value: `none` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - The response from https://acme-bakery.example/ had no permissions-policy header. <https://acme-bakery.example/> · value: `none` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add a Permissions-Policy that disables unused features (camera=(), microphone=(), geolocation=()).
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Permissions-Policy: camera=(), microphone=(), geolocation=()
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -i permissions-policy`

### F22 · Missing referrer-policy.

- **Area:** Security (passive) · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - The response from https://acme-bakery.example/ (HTTP 200) had no referrer-policy header. <https://acme-bakery.example/> (HTTP 200) · value: `none` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - The response from https://acme-bakery.example/ had no referrer-policy header. <https://acme-bakery.example/> · value: `none` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Add Referrer-Policy: strict-origin-when-cross-origin
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
Referrer-Policy: strict-origin-when-cross-origin
```

**Verify:** `curl -sI https://acme-bakery.example/ | grep -i referrer-policy`

### F23 · server discloses a version (Apache/2.4.41 (Ubuntu)).

- **Area:** Security (passive) · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - server discloses a version (Apache/2.4.41 (Ubuntu)). <https://acme-bakery.example/> · value: `Apache/2.4.41 (Ubuntu)` · header, security-headers, observed 2026-10-30T06:38:14.449Z
  - server discloses a version (Apache/2.4.41 (Ubuntu)). <https://acme-bakery.example/> · value: `Apache/2.4.41 (Ubuntu)` · header, security-scan-lite, observed 2026-10-30T06:38:14.449Z
- **Fix:** Remove the version from the server header.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

**Verify:** `Re-run this report (or the security-headers check) after the change and confirm this finding is gone.`

### F24 · x-powered-by discloses a version (PHP/7.4.3).

- **Area:** Security (passive) · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how well visitors and their browsers are protected against common web attacks.
- **Evidence:**
  - x-powered-by discloses a version (PHP/7.4.3). <https://acme-bakery.example/> · value: `PHP/7.4.3` · header, security-headers, observed 2026-10-30T06:38:14.449Z
- **Fix:** Remove the version from the x-powered-by header.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

**Verify:** `Re-run this report (or the security-headers check) after the change and confirm this finding is gone.`

### F25 · Meta description is 47 characters.

- **Area:** SEO · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/menu>
- **Evidence:**
  - Meta description is 47 characters. <https://acme-bakery.example/menu> (HTTP 200) · value: `Breads, cakes and pastries baked every morning.` · html, seo-page, observed 2026-10-30T06:38:14.421Z
- **Fix:** Aim for roughly 70-160 characters.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F26 · HTML is not compressed (4 of 4 pages checked).

- **Area:** SEO · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/about>, <https://acme-bakery.example/menu>, <https://acme-bakery.example/contact>
- **Evidence:**
  - The HTML of https://acme-bakery.example/ was sent without Content-Encoding (gzip/br). <https://acme-bakery.example/> · value: `none` · header, seo-page, observed 2026-10-30T06:38:14.413Z
  - The HTML of https://acme-bakery.example/about was sent without Content-Encoding (gzip/br). <https://acme-bakery.example/about> · value: `none` · header, seo-page, observed 2026-10-30T06:38:14.415Z
  - The HTML of https://acme-bakery.example/menu was sent without Content-Encoding (gzip/br). <https://acme-bakery.example/menu> · value: `none` · header, seo-page, observed 2026-10-30T06:38:14.421Z
  - The HTML of https://acme-bakery.example/contact was sent without Content-Encoding (gzip/br). <https://acme-bakery.example/contact> · value: `none` · header, seo-page, observed 2026-10-30T06:38:14.422Z
- **Fix:** Enable gzip or brotli.
- **Where:** Response headers: Apache config or .htaccess (Header always set ...).

```
nginx: gzip on; (or brotli)  /  Apache: AddOutputFilterByType DEFLATE text/html
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F27 · No Open Graph tags (4 of 4 pages checked).

- **Area:** SEO · **Severity:** low · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>, <https://acme-bakery.example/about>, <https://acme-bakery.example/menu>, <https://acme-bakery.example/contact>
- **Evidence:**
  - No Open Graph tags. <https://acme-bakery.example/> (HTTP 200) · html, seo-page, observed 2026-10-30T06:38:14.413Z
  - No Open Graph tags. <https://acme-bakery.example/about> (HTTP 200) · html, seo-page, observed 2026-10-30T06:38:14.415Z
  - No Open Graph tags. <https://acme-bakery.example/menu> (HTTP 200) · html, seo-page, observed 2026-10-30T06:38:14.421Z
  - No Open Graph tags. <https://acme-bakery.example/contact> (HTTP 200) · html, seo-page, observed 2026-10-30T06:38:14.422Z
  - Open Graph is missing (title, description, image missing). <https://acme-bakery.example/> · html, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Add og:title, og:description, og:image for link previews.
- **Where:** Page templates / CMS page settings.

```
<meta property="og:title" content="..."><meta property="og:description" content="..."><meta property="og:image" content="https://acme-bakery.example/og.png">
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F28 · No MTA-STS.

- **Area:** Email authentication · **Severity:** low · **Priority:** P4 · **Effort:** M (2-8 h) · **Owner:** DNS admin
- **Basis:** observed
- **Impact:** Affects whether others can send email that looks like it comes from this domain, and whether real mail is delivered.
- **Evidence:**
  - No MTA-STS. · value: `{"name":"acme-bakery.example"}` · dns, email-auth, observed 2026-10-30T06:38:14.427Z
- **Fix:** Optional hardening: publish MTA-STS to enforce TLS for inbound mail.
- **Where:** DNS zone of acme-bakery.example (at the DNS host).

**Verify:** `dig TXT _mta-sts.acme-bakery.example +short`

### F29 · 2 of 2 images have no alt attribute.

- **Area:** SEO · **Severity:** low · **Priority:** P4 · **Effort:** M (2-8 h) · **Owner:** Content
- **Basis:** observed
- **Impact:** Affects how search engines crawl, understand and show these pages.
- **Pages:** <https://acme-bakery.example/>
- **Evidence:**
  - 2 of 2 images have no alt attribute. <https://acme-bakery.example/> (HTTP 200) · html, seo-page, observed 2026-10-30T06:38:14.413Z
- **Fix:** Add short descriptive alt text (empty alt="" only for decorative images).
- **Where:** Page templates / CMS page settings.

```
<img src="team.jpg" alt="Our team at the Penang office">   (alt="" only for decorative images)
```

**Verify:** `Re-run this report (or the seo-page check) after the change and confirm this finding is gone.`

### F30 · robots.txt blocks AI training crawlers: GPTBot.

- **Area:** AI readiness · **Severity:** info · **Priority:** P4 · **Effort:** S (0.5-2 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects whether AI assistants and answer engines can read, understand and cite the site.
- **Evidence:**
  - robots.txt blocks AI training crawlers: GPTBot. <https://acme-bakery.example/robots.txt> · value: `{"GPTBot":false,"ClaudeBot":true,"Google-Extended":true,"Applebot-Extended":true,"CCBot":true,"Meta-ExternalAgent":true,"Bytespider":true,"Amazonbot":true}` · robots, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Fine if intended: this only opts out of model training, not AI search answers.
- **Where:** Page templates / CMS page settings.

**Verify:** `Re-run this report (or the agent-readiness check) after the change and confirm this finding is gone.`

### F31 · No agent discovery files (/.well-known/x402, /.well-known/mcp.json, /.well-known/agent-card.json, /openapi.json).

- **Area:** AI readiness · **Severity:** info · **Priority:** P4 · **Effort:** M (2-8 h) · **Owner:** Developer
- **Basis:** observed
- **Impact:** Affects whether AI assistants and answer engines can read, understand and cite the site.
- **Evidence:**
  - No agent discovery files (/.well-known/x402, /.well-known/mcp.json, /.well-known/agent-card.json, /openapi.json). <https://acme-bakery.example/> · value: `{"x402":false,"mcp":false,"agent_card":false,"openapi":false}` · file, agent-readiness, observed 2026-10-30T06:38:14.460Z
- **Fix:** Only needed if you offer an API or agent service: publish the matching discovery file so agents can find and pay for it.
- **Where:** Files at the web root of the site.

**Verify:** `Re-run this report (or the agent-readiness check) after the change and confirm this finding is gone.`

## Implementation plan

Order within a phase: priority, then effort. "depends_on" lists findings to fix first.

### Quick wins (this week)

| Finding | What | Owner | Effort | Depends on |
|---|---|---|---|---|
| F01 | No /llms.txt. | Developer | S (0.5-2 h) | - |
| F02 | No DMARC record. | DNS admin | S (0.5-2 h) | - |
| F03 | Missing strict-transport-security. | Developer | S (0.5-2 h) | F04 |
| F04 | Plain HTTP does not redirect to HTTPS. | Developer | S (0.5-2 h) | - |
| F05 | No meta description (3 of 4 pages checked). | Content | S (0.5-2 h) | - |
| F06 | No X-Frame-Options or CSP frame-ancestors (clickjacking). | Developer | S (0.5-2 h) | - |
| F07 | Missing x-content-type-options. | Developer | S (0.5-2 h) | - |

### Next 30 days

| Finding | What | Owner | Effort | Depends on |
|---|---|---|---|---|
| F08 | 1 JSON-LD block(s) do not parse as JSON. | Developer | S (0.5-2 h) | - |
| F09 | No canonical link (3 of 4 pages checked). | Developer | S (0.5-2 h) | - |
| F10 | Page titles are too short or too long (2 of 4 pages checked). | Content | S (0.5-2 h) | - |
| F11 | No DKIM key found at 30 common selectors (it may use a custom selector). | DNS admin | M (2-8 h) | - |
| F12 | 2 of 8 links checked on the home page are broken. | Content | M (2-8 h) | - |
| F13 | A page linked from the home page answers HTTP 404. | Content | M (2-8 h) | - |
| F14 | No XML sitemap found (robots.txt or /sitemap.xml). | Developer | M (2-8 h) | - |
| F15 | No JSON-LD structured data (2 of 4 pages checked). | Developer | M (2-8 h) | - |
| F16 | JSON-LD missing required properties: LocalBusiness (address). | Developer | M (2-8 h) | - |

### Later

| Finding | What | Owner | Effort | Depends on |
|---|---|---|---|---|
| F17 | Missing content-security-policy. | Developer | L (1-3 days) | - |
| F18 | Thin content: few words of visible text (2 of 4 pages checked). | Content | L (1-3 days) | - |
| F19 | No TLS-RPT. | DNS admin | S (0.5-2 h) | F28 |
| F20 | Cookie PHPSESSID is missing Secure, HttpOnly, SameSite. | Developer | S (0.5-2 h) | - |
| F21 | Missing permissions-policy. | Developer | S (0.5-2 h) | - |
| F22 | Missing referrer-policy. | Developer | S (0.5-2 h) | - |
| F23 | server discloses a version (Apache/2.4.41 (Ubuntu)). | Developer | S (0.5-2 h) | - |
| F24 | x-powered-by discloses a version (PHP/7.4.3). | Developer | S (0.5-2 h) | - |
| F25 | Meta description is 47 characters. | Content | S (0.5-2 h) | - |
| F26 | HTML is not compressed (4 of 4 pages checked). | Developer | S (0.5-2 h) | - |
| F27 | No Open Graph tags (4 of 4 pages checked). | Content | S (0.5-2 h) | - |
| F28 | No MTA-STS. | DNS admin | M (2-8 h) | - |
| F29 | 2 of 2 images have no alt attribute. | Content | M (2-8 h) | - |

## Needs human review

- **Links not checked (robots.txt)**: 1 link(s) on the home page were not requested because robots.txt disallows them for our crawler.
- **No DKIM key found at 30 common selectors (it may use a custom selector).** [F11]: Inferred, not directly measured: Only 30 common DKIM selectors were queried; a custom selector would not be seen, so DKIM may exist.
- **robots.txt blocks AI training crawlers: GPTBot.** [F30]: Blocking AI training crawlers is a legitimate business choice; confirm the policy with the site owner before changing it.
- **Page not crawled: https://acme-bakery.example/private/admin**: robots.txt disallows it for our crawler (not requested). If it should be assessed, allow the audit crawler for it in robots.txt, or check it by hand.
- **Check failed: page-fetch (https://acme-bakery.example/old-page)**: target\_http\_error: https://acme-bakery.example/old-page answered HTTP 404.. Nothing was assumed for it.

## Coverage

- Pages read: 4 (max 10; found from internal links on the home page (same host, robots.txt checked before any request))
  - <https://acme-bakery.example/> HTTP 200, 2 ms
  - <https://acme-bakery.example/about> HTTP 200, 3 ms
  - <https://acme-bakery.example/menu> HTTP 200, 2 ms
  - <https://acme-bakery.example/contact> HTTP 200, 1 ms
- Not crawled (robots.txt): 1
  - <https://acme-bakery.example/private/admin>
- Pages that failed: 1
  - <https://acme-bakery.example/old-page> (target\_http\_error)
- Areas checked: SEO, Security (passive), Links, Email authentication, AI readiness

| Check | Area | Target | Result | Time |
|---|---|---|---|---|
| canonical-check | SEO | https://acme-bakery.example/ | ok | 1 ms |
| canonical-check | SEO | https://acme-bakery.example/about | ok | 0 ms |
| canonical-check | SEO | https://acme-bakery.example/menu | ok | 1 ms |
| canonical-check | SEO | https://acme-bakery.example/contact | ok | 0 ms |
| page-fetch | SEO | https://acme-bakery.example/ | ok | 22 ms |
| page-fetch | SEO | https://acme-bakery.example/about | ok | 5 ms |
| page-fetch | SEO | https://acme-bakery.example/menu | ok | 3 ms |
| page-fetch | SEO | https://acme-bakery.example/contact | ok | 3 ms |
| page-fetch | SEO | https://acme-bakery.example/old-page | failed (target\_http\_error) | 2 ms |
| seo-page | SEO | https://acme-bakery.example/ | ok | 10 ms |
| seo-page | SEO | https://acme-bakery.example/about | ok | 9 ms |
| seo-page | SEO | https://acme-bakery.example/menu | ok | 4 ms |
| seo-page | SEO | https://acme-bakery.example/contact | ok | 4 ms |
| structured-data | SEO | https://acme-bakery.example/ | ok | 1 ms |
| structured-data | SEO | https://acme-bakery.example/about | ok | 0 ms |
| structured-data | SEO | https://acme-bakery.example/menu | ok | 0 ms |
| structured-data | SEO | https://acme-bakery.example/contact | ok | 0 ms |
| security-headers | Security (passive) | https://acme-bakery.example/ | ok | 26 ms |
| security-scan-lite | Security (passive) | https://acme-bakery.example/ | ok | 26 ms |
| broken-links | Links | https://acme-bakery.example/ | ok | 39 ms |
| email-auth | Email authentication | acme-bakery.example | ok | 4 ms |
| agent-readiness | AI readiness | https://acme-bakery.example/ | ok | 37 ms |
| tech-stack | context | https://acme-bakery.example/ | ok | 20 ms |

### Limitations

- Passive and read-only: plain GET/HEAD requests and public DNS lookups, as a browser or crawler would make. No login, no form submission, no active or intrusive testing.
- Point-in-time: results describe what the site served when observed\_at says; sites change.
- Up to 10 page(s), found from the home page's internal links; pages behind JavaScript navigation, logins or not linked from the home page are not seen.
- robots.txt is obeyed: disallowed pages are listed, not fetched.
- Security headers and TLS are read from our server; a CDN or firewall may answer differently in other regions.
- DKIM is looked up at 30 common selectors only.
- Response times are single measurements from one location.

**Not a guarantee.** This report is not a penetration test, security certification, legal or compliance opinion, and does not promise rankings, traffic or security. Absence of a finding does not prove absence of a problem.

Detected stack (context, from public signatures): Apache 2.4.41, PHP 7.4.3.
