Security
Fixing Frame Protection without guessing
Stop toggling random security headers from a screenshot. Reproduce the framing gap on the cited public URL, set the real controls, and verify on the same host before you close the ticket.
· by Sam Ortega

Guessing a fix from a red security row is how you ship X-Frame-Options on the wrong host. Frame protection on SlaySlop means the scanner "Looks for controls that prevent unwanted framing and clickjacking." The repair loop should observe the same kind of signal: a page, a response, controls you can name.
Handoff realism matters here. Clients re-run the URL you claimed to fix. If you fixed preview only, the call goes badly.
Outcome after a real fix
The cited public URL shows framing controls that match intent, and a follow-up scan does not revive the same Frame protection finding on that route. Related CSP content-restriction work is either done or filed separately with its own owner.
Boundaries before you edit
Read-only scanner. Permission required. Not a pentest. SlaySlop will not patch your CDN. Frame protection ≠ CSP script policy. Content Security Policy "Checks whether browser content sources are restricted by a CSP header." You may touch both in one change window; keep the acceptance criteria separate.
Do not invent claims about authenticated-only apps the public scan never opened.
Loading diagram.
Step 1: Reproduce on the cited page
Open the exact public URL from the finding. Dump headers. Confirm what is missing or weak.
curl -sI "https://www.example.com/login" | rg -i 'HTTP/|x-frame-options|content-security-policy'If production differs from the CDN project you edited, stop. Fix the path traffic actually hits.
Step 2: Choose controls that match intent
Common durable patterns:
x-frame-options: DENYcontent-security-policy: frame-ancestors 'none'Or SAMEORIGIN / frame-ancestors 'self' when same-origin embedding is intentional. Document the intent in the portal note. Guessing DENY on a product that legitimately embeds itself across sibling hosts creates a new outage ticket.
Step 3: Deploy where the edge actually serves
Origin-only changes fail when the CDN overrides headers. CDN-only changes fail when a second edge path bypasses that config. Verify with the public hostname clients use.
Verify checklist
[ ] Cited URL still correct
[ ] Framing controls visible on public response
[ ] Intent documented (deny / same-origin / allowlist)
[ ] CSP sibling reviewed if you touched CSP
[ ] Follow-up scan does not revive the rowStep 4: Verify the same way the check observes
Rescan the same public URL. Confirm the Frame protection finding clears. Spot-check one more sensitive path that shares the edge config. Do not close from a staging-only dump.
Pitfalls that look like progress
Setting headers only on / while /login is a separate app. Shipping Report-Only CSP and calling framing "enforced." Fixing www while apex still serves bare. Merging CSP script work and framing work into one vague "security headers" PR with no acceptance tests.
Coordinating CDN and app owners
Most framing bugs I see are ownership bugs. App repo assumes CDN injects headers. CDN assumes origin sends them. Nobody dumps the public response. Pick one source of truth per host, document it in the portal, and test the public hostname—not the origin IP you curl from a bastion.
If you need temporary embedding for a single partner, prefer an explicit frame-ancestors allowlist over disabling controls globally "for a week." Temporary global disables become permanent. I have watched that week survive two quarters.
After deploy, I ask one more ops question: which alert fires if someone clears the header rule during a firewall tidy-up? If the answer is nobody, add a scheduled SlaySlop rescan cadence so the regression is not discovered on a client call.
Rollback plan before you tighten
Tightening framing controls can break legitimate admin embeds, CMS preview iframes, or partner portals. Before you ship DENY or frame-ancestors 'none', list known iframes that load your origin. If one is required, encode it in frame-ancestors deliberately. Then verify that path still works after deploy. A framing fix that bricks preview is still a production incident—just a different flavor.
After the rescan is clean, paste before-and-after header snippets into the ticket. Future you will thank present you during the next CDN migration.
Guessing feels fast until the partner iframe breaks on Friday night. Named controls and a rescan are slower once and faster forever.
Ship the header change with a one-line intent comment in the CDN config so the next editor knows why DENY was chosen.
Related next step
When the ticket needs a durable definition, keep Frame protection beside the change request and refuse to merge on screenshots alone.