Every Magento Open Source fix we catalog
SEOLZ catalogs 74 fixes for Magento Open Source across 5 areas — SEO, answer-engine readiness, accessibility, security and site-health. Each lists the exact steps for Magento Open Source, with a link to the official docs.
SEO · 18 fixes
Faceted url indexableModerate effort
Point every faceted/filter URL's canonical tag to the clean, unfiltered category URL (or add noindex) so Google treats filtered pages as one authoritative page instead of thousands of duplicates.
On Magento Open Source
- Same steps as Adobe Commerce (Magento) above — go to Stores → Configuration → Catalog → Catalog → Search Engine Optimization and set 'Use Canonical Link Meta Tag for Categories' to 'Yes'.
- For community extensions that add faceted/layered navigation, check the extension's configuration for SEO options including canonical and noindex settings.
- After configuration, flush the cache via System → Cache Management and verify by inspecting a filtered URL's page source.
Images missing altModerate effort
Add descriptive alt text to every image on your store so search engines can understand them and all shoppers can access your content.
On Magento Open Source
- FOR PRODUCT IMAGES: Admin > Catalog > Products > open product > Images and Videos section > hover over image > gear icon > fill 'Alt Text' field > Save.
- FOR CMS CONTENT: Admin > Content > Pages or Blocks > open item > WYSIWYG editor > click image > Insert Image icon > fill 'Image Description' (alt) field.
- FOR BULK IMPORT: System > Data Transfer > Import > select Products entity type > prepare CSV with additional_image_labels column populated > upload and import.
Meta description too longQuick win
Shorten your meta description to 150–160 characters so Google displays your full message in search results instead of cutting it off with "…".
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento): Catalog → Products → select product → Search Engine Optimization section → edit Meta Description → Save.
- For CMS pages: Content → Pages → select page → Search Engine Optimization → Meta Description → Save.
- For bulk updates across many products, use the built-in CSV import (System → Data Transfer → Import) with updated meta_description values in the import file.
Meta description too shortModerate effort
Expand every meta description to 120–160 characters so Google shows your custom summary in search results instead of auto-generating one.
On Magento Open Source
- Steps are identical to Adobe Commerce (Magento) above.
- For theme-level default meta descriptions, edit app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout/default_head_blocks.xml and set a fallback description, though per-page/product descriptions set in the Admin always take priority.
Missing meta descriptionQuick win
Write a unique meta description of 120–160 characters for every page so Google has compelling snippet text to show in search results.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — the admin paths are identical in Magento Open Source.
- For bulk updates on large catalogues, use a product import CSV (Admin → System → Import) with the 'meta_description' column filled in, or use a third-party extension such as 'SEO Suite' by Mirasvit.
Missing og imageModerate effort
Add an og:image meta tag to every page so social media platforms and messaging apps display a rich preview image when someone shares your store's link.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the admin path, layout XML approach, and recommended extensions are identical for Magento Open Source.
Missing titleQuick win
Add a unique, descriptive title tag (30–60 characters) to every page that is missing one.
On Magento Open Source
- Same as Adobe Commerce — go to Catalog → Products (or Categories) or Content → Pages → select the item → expand 'Search Engine Optimization' → fill in 'Meta Title'.
- Flush the cache after saving: System → Cache Management → Flush Magento Cache.
Search results indexableModerate effort
Add a noindex robots meta tag to all internal search results pages and block the search path in robots.txt to prevent thin, duplicate, near-infinite pages from polluting Google's index.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the layout XML approach and robots.txt editor are identical in Magento Open Source.
- The search results layout handle is catalogsearch_result_index.xml in the Magento_CatalogSearch module.
- Flush caches after saving: php bin/magento cache:flush from the server CLI.
Seo category description missingQuick win
Write a unique 100–200 word description for every product category page explaining what it contains and who it's for.
On Magento Open Source
- Follow the same steps as Adobe Commerce: Catalog → Categories → select category → Content → Description field.
- Clear the cache after saving: System → Cache Management → Flush Magento Cache.
Seo facet url not canonicalizedModerate effort
Add a canonical tag pointing filtered and sorted category URLs back to the clean (unfiltered) category page URL to prevent duplicate content and crawl waste.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento): Admin → Stores → Configuration → Catalog → Catalog → Search Engine Optimization → set 'Use Canonical Link Meta Tag for Categories' to Yes.
- Clear caches under System → Cache Management.
- For layered navigation filter URLs, confirm the canonical appears by inspecting source on a filtered page.
Seo product description thinModerate effort
Expand thin product descriptions to at least 300 words of unique, keyword-rich content that answers real shopper questions and gives Google enough text to understand what you sell.
On Magento Open Source
- Same as Adobe Commerce: Admin → Catalog → Products → Edit product → expand 'Content' section.
- Write expanded copy in the 'Description' WYSIWYG field (not just 'Short Description').
- Save and reindex if needed (System → Index Management → Reindex All) to ensure frontend reflects changes.
Seo product image alt filenameModerate effort
Replace filename-based alt text on product images with short, descriptive phrases that accurately describe each image's content.
On Magento Open Source
- Follow the same steps as Adobe Commerce above.
- Navigate to Catalog → Products → open a product → Images and Videos tab.
- Click each image thumbnail and fill in the 'Alt Text' field.
- Save the product.
- For bulk operations, use a data-patch script or a community extension to update image labels (alt text) across multiple products efficiently.
Seo product missing gtinModerate effort
Add a valid GTIN (and/or MPN) to your Product structured data so Google can match your listings to its product catalog and show them in Shopping results and AI-powered product features.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the product attribute creation and template override process is identical in Magento Open Source.
- After creating the 'gtin' attribute, populate it via Catalog → Products or via bulk CSV import (System → Data Transfer → Import, entity type 'Products').
- Override or extend the structured data template as described and flush caches.
- Verify with Google's Rich Results Test.
Seo product missing stock statusModerate effort
Add visible stock availability text to each product page and set the correct `availability` property (InStock, OutOfStock, or PreOrder) in your Product structured data (JSON-LD schema).
On Magento Open Source
- Follow the same steps as Adobe Commerce above — the stock status configuration path and template override approach are identical in Magento Open Source.
- Go to Catalog → Products → edit a product → Inventory tab → set 'Stock Availability' to 'In Stock' or 'Out of Stock'.
- To customise schema output, override `app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/view/` template files in your custom theme.
- Verify the output with Google's Rich Results Test.
Seo product single imageModerate effort
Add at least 4 high-quality product images (multiple angles, detail shots, and lifestyle/in-use photos) to every product listing to increase click-through rates and conversions.
On Magento Open Source
- Same workflow as Adobe Commerce: Admin → Catalog → Products → select product → 'Images and Videos' panel → upload, assign roles, add alt text, save.
Seo product title genericQuick win
Rewrite generic product page titles to include the product name plus at least one differentiating attribute (material, colour, size, pack size, or brand) in a natural, keyword-rich format.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the product Meta Title field and Cache Management paths are identical in the open-source edition.
- For programmatic bulk updates, use a data patch or the Magento 2 import/export CSV with the 'meta_title' column populated for each SKU.
Seo variant urls in sitemapModerate effort
Remove product variant URLs (e.g. ?variant=, ?sku=) from your XML sitemap so only the canonical product page URL is submitted to Google.
On Magento Open Source
- Go to Admin → Marketing → SEO & Search → Site Map to review your sitemap configurations.
- Go to Stores → Configuration → Catalog → XML Sitemap. Under 'Product Options', verify that configurable product option URLs are not being included.
- Set Stores → Configuration → Catalog → Search Engine Optimization → 'Use Canonical Link Meta Tag for Products' to Yes — this ensures all product variant/child URLs declare the parent as canonical.
- If a third-party sitemap extension is installed, open its admin configuration and disable 'Include product variations' or equivalent setting.
- Regenerate the sitemap via Marketing → SEO & Search → Site Map, then resubmit in Google Search Console.
Seo variant urls not canonicalizedModerate effort
Add a canonical tag to every product variant URL pointing back to the base product page, so Google consolidates ranking signals onto one authoritative URL instead of splitting them across hundreds of near-duplicate pages.
On Magento Open Source
- Follow the identical steps as Adobe Commerce above — the 'Use Canonical Link Meta Tag For Products' setting exists in Magento Open Source at Stores → Configuration → Catalog → Catalog → Search Engine Optimization.
- Set it to 'Yes', save, and flush the cache via System → Cache Management → Flush Magento Cache.
Answer Engine Optimization · 1 fixes
Missing schema localbusinessQuick win
Add a LocalBusiness JSON-LD schema block to your store so search engines and AI assistants can surface your business name, address, phone number, and hours in rich results and answer boxes.
On Magento Open Source
- Same approach as Adobe Commerce: Content → Design → Configuration → Edit your store view → HTML Head → Scripts and Style Sheets field.
- Paste the <script type='application/ld+json'>…</script> block and save, then flush caches via System → Cache Management.
- For version-controlled deployments, add the script via app/design/frontend/<Vendor>/<theme>/Magento_Theme/layout/default_head_blocks.xml or a custom module.
Accessibility (WCAG) · 28 fixes
Aria allowed roleModerate effort
Remove or replace the invalid `role="presentation"` (or other disallowed ARIA role) on HTML elements where that role is not permitted, so assistive technologies can correctly interpret your page.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — the theming and template structure is identical.
- After editing, run `bin/magento cache:flush` and redeploy static content as needed.
Aria command nameModerate effort
Add a discernible, screen-reader-accessible name to every button, link, and menuitem that uses an ARIA command role so assistive technology can announce what it does.
On Magento Open Source
- Follow the same theme-override and template-editing steps as Adobe Commerce (Magento) above.
- Locate the relevant .phtml or Knockout .html template, copy it to your custom theme, add `aria-label` (and `aria-hidden="true"` on decorative SVGs), flush cache, and re-deploy static content.
Aria hidden focusModerate effort
Remove `aria-hidden="true"` from any element that contains focusable children (links, buttons, inputs), or remove the focusable elements from inside the hidden container.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — template paths and the override mechanism are identical in Magento Open Source.
- Use `bin/magento cache:flush` after making template changes, and verify with axe DevTools or NVDA + Chrome.
Aria input field nameModerate effort
Add a meaningful accessible name (label) to every ARIA input field so screen readers can identify and announce it to users.
On Magento Open Source
- Follow the same template override and XML layout approach as Adobe Commerce (Magento) above.
- For JavaScript-rendered components (e.g., minicart, checkout), create a RequireJS mixin in your module or theme to add aria-label after the component renders.
- Run bin/magento cache:clean and deploy static content, then retest with axe DevTools.
Aria required childrenModerate effort
Ensure every ARIA parent role contains only its required, permitted child roles — and remove focusable elements (e.g. tabindex on img or a) that are not allowed inside that ARIA context.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — the template override mechanism is identical in Magento Open Source.
- Use bin/magento cache:flush after any template change.
- Verify with axe DevTools browser extension.
Aria required parentModerate effort
Wrap every ARIA child role (such as `tab`, `option`, `listitem`, `row`, etc.) in the correct required ARIA parent container role (such as `tablist`, `listbox`, `list`, `rowgroup`, or `grid`) so assistive technologies can correctly interpret the widget's structure.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — locate the relevant PHTML or Knockout template in your custom theme, add the required ARIA parent role wrapper, flush cache, and redeploy static content.
Button nameModerate effort
Add a visible or programmatically accessible name to every button so screen readers can announce what it does.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — template paths and cache-clearing commands are identical for Magento Open Source.
Document titleQuick win
Add a unique, descriptive <title> element to every page so browsers, screen readers, and search engines can identify it.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the admin paths are identical in Magento Open Source.
- For theme-level title tag: edit app/design/frontend/[Vendor]/[theme]/Magento_Theme/layout/default_head_blocks.xml and ensure <title> uses a layout variable, not a hardcoded string.
- Clear the cache after any changes: System → Cache Management → Flush Magento Cache.
Empty headingModerate effort
Find every empty heading tag on your store and add meaningful, visible text to it — or remove the tag entirely if it serves no structural purpose.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template structure, CLI commands, and admin panel paths are identical for the open-source edition.
Heading orderModerate effort
Fix heading tags so they follow a logical, sequential order (H1 → H2 → H3…) without skipping levels anywhere on the page.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template override process and CMS editor are identical in Magento Open Source.
Html has langQuick win
Add a valid `lang` attribute to the `<html>` element so browsers and assistive technologies know what language your page is written in.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — override `root.phtml` in your custom theme and ensure the `lang` attribute reflects the configured locale from Stores → Configuration → General → Locale Options.
Html lang validQuick win
Set a valid BCP 47 language code on the `lang` attribute of your page's `<html>` element (e.g., `lang="en"`) so browsers, screen readers, and search engines correctly identify the page language.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template structure and locale configuration paths are identical in Magento Open Source.
Image altModerate effort
Add a descriptive `alt` attribute to every `<img>` element on your store so screen readers and search engines can understand what each image shows.
On Magento Open Source
- **Product images:** Admin → Catalog → Products → select a product → Images and Videos section → hover an image → gear icon → fill 'Alt Text' → Save.
- **Bulk via CSV import:** Admin → System → Import → Products → ensure `image_label` column is populated for each row → import.
- **Template files:** Edit `app/design/frontend/<Vendor>/<theme>/Magento_Catalog/templates/product/image.phtml` and confirm the `alt` attribute outputs the product's image label or name.
Image redundant altModerate effort
Remove or empty the alt attribute on images whose caption or surrounding text already describes them, so screen readers don't announce the same information twice.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above; the admin panel paths and template locations are identical in the open-source edition.
- After editing theme .phtml files, run: php bin/magento cache:flush and php bin/magento setup:static-content:deploy to apply changes.
Label title onlyModerate effort
Add a visible, persistent label to every form field so it is never labeled only by a tooltip (title) or hidden description (aria-describedby).
On Magento Open Source
- Follow the same process as Adobe Commerce (Magento) above — override the relevant PHTML template in your custom theme directory.
- After adding visible `<label>` elements or `aria-label` attributes, clear the Magento cache: Admin → System → Cache Management → Flush Magento Cache.
- Test on staging before deploying to production.
Landmark banner is top levelModerate effort
Ensure your site's banner landmark (<header> or role="banner") sits at the top level of the page, not nested inside another landmark region.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the theme file locations and layout XML approach are identical for Magento Open Source.
- Key files: `app/design/frontend/<Vendor>/<Theme>/Magento_Theme/templates/root.phtml` and `header.phtml`.
- Ensure the `<header>` element in `header.phtml` is positioned as a direct child of `<body>` in the rendered HTML, not wrapped inside a landmark-carrying element.
- Flush cache with `bin/magento cache:flush` and verify with axe DevTools.
Landmark contentinfo is top levelModerate effort
Move your footer element (or any element with role="contentinfo") to the top level of the page so it is not nested inside another landmark region.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template and layout XML file locations and approach are identical for Magento Open Source.
Landmark no duplicate bannerModerate effort
Ensure your page has only one banner landmark (a single `<header>` element or `role="banner"`) so assistive technologies can navigate your site correctly.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — template paths and CLI commands are identical for Magento Open Source.
- If using a third-party theme from Marketplace, create a theme override in app/design/frontend/<YourVendor>/<YourTheme>/ rather than editing the vendor files directly, then apply the same <header>-to-<div> change in your override template.
Landmark no duplicate mainModerate effort
Ensure each page contains exactly one `<main>` landmark element (or one element with `role="main"`) so screen-reader users can navigate directly to the page's primary content.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — the theme file paths and layout XML structure are identical for Magento Open Source.
Landmark one mainQuick win
Add a single `<main>` landmark element (or `role="main"`) to every page so that screen-reader users and assistive technologies can skip directly to the primary content.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template path and process are identical for Magento Open Source 2.x.
- If you are on Magento 1.x, edit `app/design/frontend/<package>/<theme>/template/page/html/wrapper.phtml` and wrap the main content `<div>` with `<main role="main" id="main-content">` … `</main>`.
- Clear the Magento cache after saving.
Link nameModerate effort
Add a descriptive, screen-reader-accessible label to every link on your store so assistive technologies can announce where each link leads.
On Magento Open Source
- Follow the same template-override approach as Adobe Commerce above.
- Locate templates under app/design/frontend/<Vendor>/<theme>/ and add aria-label or alt attributes to the relevant <a> or <img> tags.
- Flush the Magento cache with bin/magento cache:flush after changes.
- Verify with axe DevTools.
Meta viewportQuick win
Remove `user-scalable=no` (and any `maximum-scale` value below 5) from your site's `<meta name="viewport">` tag so visitors can pinch-to-zoom on mobile devices.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the theme file structure is identical.
- Edit `default_head_blocks.xml` or `root.phtml` within your custom theme, flush the cache with `bin/magento cache:flush`, and verify on a mobile device.
Meta viewport largeQuick win
Remove or raise the `maximum-scale` value in your site's `<meta name="viewport">` tag so mobile users can pinch-to-zoom freely.
On Magento Open Source
- Follow the same steps as Adobe Commerce: locate the viewport meta tag in your theme's default_head_blocks.xml or head.phtml, remove the `maximum-scale` restriction, flush caches, and redeploy static content.
Nested interactiveModerate effort
Remove or restructure focusable elements nested inside interactive controls so that no interactive element contains another focusable child.
On Magento Open Source
- Follow the same template-override process as Adobe Commerce: copy the relevant .phtml file (e.g. vendor/magento/module-catalog/view/frontend/templates/product/list.phtml) into your theme at app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/list.phtml.
- Edit the copied template to replace any wrapping interactive element (e.g. <a> around the whole card) with a <div>, and ensure product title links and action buttons are siblings.
- Clear the Magento cache: bin/magento cache:clean.
- Test keyboard tab order on the frontend.
Select nameModerate effort
Add a descriptive, programmatically associated label to every `<select>` dropdown element on the site so assistive technologies can announce its purpose to users.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template structure and cache-clearing commands are identical.
Skip linkQuick win
Add a valid, matching target ID to every skip-navigation link so keyboard and assistive-technology users can bypass repeated header content and jump directly to the main content area.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template structure is identical.
- Luma's default skip link already targets `#contentarea`; confirm that id is present on the <div class='page-main'> wrapper and is not being removed by a third-party extension or custom theme override.
TabindexModerate effort
Remove all positive tabindex values (tabindex="1" or higher) from your store's HTML elements, replacing them with tabindex="0" or relying on natural document order to control keyboard focus.
On Magento Open Source
- Follow the same template-override approach as Adobe Commerce: locate the .phtml or UI-component .html file, create an override in app/design/frontend/<Vendor>/<theme>/, and correct all positive tabindex values.
- Flush the Magento cache and redeploy static content after saving changes.
- Verify with keyboard-only navigation through the storefront.
Valid langModerate effort
Add a valid BCP 47 language code to every `lang` attribute on your pages so assistive technologies can read content in the correct language.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the template path and locale configuration are identical in Magento Open Source.
Security (OWASP) · 20 fixes
Dmarc policy noneModerate effort
Strengthen your DMARC policy from p=none (monitor-only) to p=quarantine, then p=reject, to actively block email spoofing of your domain.
On Magento Open Source
- Magento Open Source is self-hosted; DNS is at your registrar or hosting control panel (cPanel, Plesk, Cloudflare, etc.).
- Navigate to DNS management and find the _dmarc TXT record.
- Edit the value to set p=quarantine, save, and monitor DMARC reports.
- In the Magento admin go to Stores > Configuration > Advanced > System > Mail Sending Settings to confirm the SMTP relay and From domain. Ensure the relay's SPF include and DKIM selector are present in your DNS.
- After reports confirm only spoofed mail fails, edit the record to p=reject.
Hsts disabledQuick win
Enable HTTP Strict-Transport-Security (HSTS) by setting a max-age of at least 31536000 seconds (one year) so browsers always use HTTPS when visiting your store.
On Magento Open Source
- Follow the same Nginx or Apache server-level steps as Adobe Commerce above — add `add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;` in your Nginx server block or `Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"` in Apache.
- In Magento Admin, confirm Stores → Configuration → General → Web → Secure → Use Secure URLs = Yes for both storefront and admin.
- If using a shared hosting control panel (cPanel), look for an 'HSTS' toggle under Security → SSL/TLS Status or use the .htaccess method.
Hsts max age too shortQuick win
Increase your HSTS max-age to at least 31536000 (one year) so browsers enforce HTTPS-only connections for a meaningful period.
On Magento Open Source
- Same web-server steps as Adobe Commerce above apply — edit your Apache or Nginx virtual-host config to set Header always set / add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
- If using a CDN such as Cloudflare in front of Magento Open Source, configure the HSTS header in Cloudflare's dashboard: SSL/TLS → Edge Certificates → HTTP Strict Transport Security → Max Age 12 months.
- Reload your web server after any config change and verify with securityheaders.com.
Https not availableQuick win
Enable HTTPS by installing a valid SSL/TLS certificate and redirecting all HTTP traffic to the secure HTTPS version of your store.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the Admin configuration paths and web-server changes are identical.
- Install your SSL certificate via Let's Encrypt/Certbot or your hosting panel, then configure secure base URLs under Stores → Configuration → General → Web.
- Add HTTP-to-HTTPS redirect rules in .htaccess (Apache) or your server block (Nginx) and flush all caches after saving.
Info disclosure serverQuick win
Remove or obscure the Server HTTP response header so your web server software name and version are no longer exposed to the public internet.
On Magento Open Source
- Same web-server-level fix as Adobe Commerce: for nginx add `server_tokens off;`, for Apache add `ServerTokens Prod` and `ServerSignature Off` to the server config.
- If hosted on a shared host with cPanel: log in to cPanel → File Manager → edit `.htaccess` in the site root → add `Header unset Server` (requires `mod_headers` to be enabled by your host).
- Alternatively, install a WAF or reverse proxy (e.g., Cloudflare free tier) in front of your Magento store and configure it to strip the `Server` header.
- Verify with `curl -I https://yourstore.com`.
Info disclosure x powered byQuick win
Remove or mask the X-Powered-By HTTP response header to stop advertising your server technology stack to attackers.
On Magento Open Source
- Follow the same Nginx/Apache/.htaccess and PHP expose_php steps as Adobe Commerce above.
- For shared hosting with cPanel: Go to cPanel → Software → MultiPHP INI Editor, select your PHP version, and set expose_php to Off.
Insecure cookieModerate effort
Set the HttpOnly, Secure, and SameSite=Strict flags on every session and CSRF cookie your store sets so they cannot be stolen by malicious scripts or sent over unencrypted connections.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — Magento Open Source shares the same admin configuration paths.
- Navigate to Stores → Configuration → General → Web → Session Cookie Management and set 'Use Secure Cookie' = Yes, 'HTTP Only' = Yes.
- For SameSite on Magento Open Source 2.3.5+, set Cookie SameSite to 'Strict' in Stores → Configuration → General → Web → Default Cookie Settings.
- Run `bin/magento cache:flush` after saving configuration.
- Verify PHPSESSID and form_key cookies in DevTools show HttpOnly ✓, Secure ✓, SameSite = Strict.
Missing content security policyModerate effort
Add a Content-Security-Policy (CSP) response header to every page so browsers block unauthorized scripts, styles, and resources from loading.
On Magento Open Source
- Same as Adobe Commerce above — CSP configuration is in Admin → Stores → Configuration → Security → Content Security Policy (available from Magento 2.3.5+).
- Edit `csp_whitelist.xml` in your custom theme or module under `etc/` to add trusted external origins.
- Set `restrict_mode` to `0` initially (report-only) then to `1` (enforce) in your XML or admin config once violations are resolved.
- Flush cache: `bin/magento cache:flush` after changes.
Missing dmarcQuick win
Add a DMARC DNS TXT record at _dmarc.yourdomain.com to protect your domain from email spoofing and phishing.
On Magento Open Source
- Same DNS and mail-authentication process as Adobe Commerce above — DMARC is purely a DNS TXT record managed at your registrar or DNS host.
- Add TXT record at _dmarc.yourdomain.com with value: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com
- Configure SMTP authentication in Magento Open Source via Stores → Configuration → Advanced → System → Mail Sending Settings, pointing to an SPF/DKIM-enabled relay.
- Use a community SMTP extension from the Magento Marketplace to enable authenticated outbound mail if the default server configuration does not support it.
Missing permissions policyQuick win
Add a Permissions-Policy HTTP response header to explicitly restrict which browser features (camera, microphone, geolocation, etc.) your store's pages are allowed to use.
On Magento Open Source
- For Apache: add to .htaccess in Magento root: `Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"` (requires mod_headers).
- For Nginx: add to your server {} block: `add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;` and reload Nginx.
- Alternatively, build a small custom module that adds the header via an event observer or plugin on the HTTP response object.
- Clear caches: php bin/magento cache:flush
- Verify via Chrome DevTools Network tab or securityheaders.com.
Missing referrer policyQuick win
Add a `Referrer-Policy: strict-origin-when-cross-origin` HTTP response header to every page so browsers control what referrer information is sent with requests.
On Magento Open Source
- Follow the same server-level (Nginx or Apache) steps as Adobe Commerce above.
- For the programmatic approach, create a custom module with a plugin on the HTTP response object to set the header on every response.
- Flush cache: `php bin/magento cache:flush` and verify with browser DevTools.
Missing spfQuick win
Add a DNS TXT record containing a valid SPF policy to your domain so email servers can verify that messages sent from your domain are legitimate.
On Magento Open Source
- DNS is managed at your registrar or hosting provider — not inside Magento.
- Log in to your DNS provider and add a TXT record at '@' with your full SPF value.
- In Magento admin, go to Stores → Configuration → Advanced → System → Mail Sending Settings to confirm the SMTP host in use, then add that provider's SPF include: directive to your record.
- Common setups include a server-local sendmail (add your server's IP as 'ip4:x.x.x.x') or a third-party SMTP relay like SendGrid or Mailgun (use their published include: tag).
- Verify propagation with a free SPF lookup tool.
Missing strict transport securityQuick win
Add an HTTP Strict-Transport-Security (HSTS) response header with at least `max-age=31536000; includeSubDomains` to every HTTPS response your store sends.
On Magento Open Source
- Follow the same Apache/Nginx server-config steps as Adobe Commerce above — they share the same codebase and hosting model.
- Add `add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;` (Nginx) or the equivalent Apache `Header always set` directive in your SSL VirtualHost.
- Alternatively, use a PHP-based approach in Magento's index.php or a custom plugin that calls `header()` before output — but the server-config approach is preferred for performance and reliability.
- Flush Magento caches after any change.
Missing x content type optionsQuick win
Add the `X-Content-Type-Options: nosniff` HTTP response header to every page of your store so browsers never guess at file types.
On Magento Open Source
- Same as Adobe Commerce (Magento) above — apply the Nginx or Apache server-block header directive, or use a Magento 2 plugin/interceptor.
- Add 'add_header X-Content-Type-Options nosniff always;' to your Nginx server block, or 'Header always set X-Content-Type-Options "nosniff"' to .htaccess.
- Flush cache via Admin → System → Cache Management → Flush Magento Cache, then verify in browser dev-tools.
Missing x frame optionsQuick win
Add an X-Frame-Options HTTP response header set to DENY or SAMEORIGIN to prevent your store's pages from being embedded in iframes on other websites.
On Magento Open Source
- Same as Adobe Commerce (Magento) above.
- In Magento 2 Open Source admin: Stores → Configuration → Security → X-Frame-Options Header → set to SAMEORIGIN.
- Flush the full-page cache after saving: System → Cache Management → Flush Cache Storage.
- For server-level enforcement, add 'add_header X-Frame-Options SAMEORIGIN always;' to your Nginx server block or 'Header always set X-Frame-Options SAMEORIGIN' in your Apache config.
Passive scan onlyModerate effort
Complement passive security scans with active Dynamic Application Security Testing (DAST) against a staging copy of your store before each release.
On Magento Open Source
- Magento Open Source is self-hosted, so you have full control. Create a staging server (identical PHP version, same extensions, same Magento version) on a private or IP-restricted URL.
- Disable cron jobs and order-notification emails on staging to prevent test data polluting real operations.
- Download OWASP ZAP and configure it to target your staging URL. Create a Magento test-customer account and use ZAP's 'Form-Based Authentication' to enable authenticated scanning of cart, checkout, and account pages.
- Run Active Scan; prioritise findings in custom modules under app/code/ and any third-party extensions in vendor/. Check REST API endpoints at /rest/V1/ and GraphQL at /graphql.
- Remediate findings — common Magento issues include insecure deserialization, SQL injection in custom modules, and admin-panel exposure. Re-run ZAP to confirm fixes.
- Add ZAP to your deployment pipeline: use the ZAP Docker image (ghcr.io/zaproxy/zaproxy) in your CI/CD (e.g. GitHub Actions) to automate scans on every release.
Ssl cert expiring soonQuick win
Renew your SSL/TLS certificate before it expires to keep your store secure, trusted, and visible in search results.
On Magento Open Source
- SSL is managed at the web server / hosting level (Apache, Nginx, cPanel, Plesk, etc.) — not within Magento itself.
- Renew via your hosting control panel or by running 'certbot renew' on the server if using Let's Encrypt.
- After renewal, verify in Admin → Stores → Configuration → General → Web → Base URLs (Secure) that all URLs use https://.
- Flush Magento cache: Admin → System → Cache Management → Flush Magento Cache, or run 'bin/magento cache:flush' via CLI.
Ssl errorModerate effort
Replace or reissue your SSL/TLS certificate so it is valid for the exact domain name your store uses, eliminating the hostname mismatch error.
On Magento Open Source
- SSL management is identical to Adobe Commerce self-hosted — handled at the server/hosting level, not inside the Magento admin panel.
- Use your hosting control panel (cPanel/Plesk) or Let's Encrypt/Certbot on the command line to issue a certificate that covers all domain variants.
- Run: `sudo certbot --nginx -d yourstore.com -d www.yourstore.com` (adjust for Apache if needed).
- In Magento Admin → Stores → Configuration → Web, update Secure Base URL to use https:// with the correct domain.
- Flush Magento cache after changes.
Ssl not accessibleModerate effort
Enable HTTPS on your store by opening port 443 and installing a valid SSL/TLS certificate so every page is served over a secure connection.
On Magento Open Source
- Follow the same server-level steps as Adobe Commerce above (open port 443, install TLS certificate via Certbot or hosting panel).
- In Admin → Stores → Configuration → General → Web → Base URLs (Secure), update the Secure Base URL to https://.
- Set 'Use Secure URLs on Storefront' and 'Use Secure URLs in Admin' to 'Yes'.
- Add a redirect in your Nginx or Apache config: for Nginx, add `return 301 https://$host$request_uri;` in the port-80 server block; for Apache, add `RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]` in your VirtualHost or .htaccess.
- Flush the Magento cache: `bin/magento cache:flush`.
X content type options weakQuick win
Set the X-Content-Type-Options response header to exactly `nosniff` (once, not duplicated) on every page and asset your store serves.
On Magento Open Source
- Follow the same Nginx/Apache steps as Adobe Commerce above.
- Check for any third-party Magento extension labelled 'Security Headers' in your Admin → System → Extensions — if one exists, disable the server-level directive and manage it only via the extension, or vice versa, to avoid duplication.
- Reload the web server and verify.
Site Lifecycle · 7 fixes
Cms versionModerate effort
Identify your ecommerce platform and CMS version, then ensure it is always kept up to date to protect your store from security vulnerabilities and avoid loss of vendor support.
On Magento Open Source
- Run `php bin/magento --version` via SSH to check your current version.
- Review the Magento Open Source GitHub releases page for the latest version and security patches.
- Back up your database and files, then use Composer to pull in updates: `composer require magento/product-community-edition=<new-version> --no-update && composer update`.
- Run the post-upgrade commands: `php bin/magento setup:upgrade`, `php bin/magento setup:di:compile`, `php bin/magento cache:flush`.
- Test your store on a staging environment before deploying to production.
Domain expiryQuick win
Enable auto-renew on your domain registration and set calendar reminders well before expiry to prevent accidental loss of your store's address.
On Magento Open Source
- Same as Adobe Commerce above — the domain is managed entirely at your registrar, not inside Magento.
- Set server-level or external monitoring alerts (e.g. via UptimeRobot or a WHOIS monitoring service) so the technical team is alerted if the domain stops resolving.
Html langQuick win
Add a correct `lang` attribute to your site's `<html>` tag so browsers, search engines, and assistive technologies know what language your store is written in.
On Magento Open Source
- Follow the same steps as Adobe Commerce above — edit root.phtml in your custom theme under app/design/frontend/<Vendor>/<Theme>/Magento_Theme/templates/.
- Add lang="en" (or the correct BCP 47 tag) to the <html> element.
- Run bin/magento cache:clean after saving, then verify via View Page Source.
Lifecycle oos schema not updatedModerate effort
Update the `offers.availability` field in your Product schema to `OutOfStock` (or `PreOrder`/`Discontinued`) whenever a product sells out, so Google's data matches your real inventory.
On Magento Open Source
- Follow the same steps as Adobe Commerce (Magento) above — the Admin panel paths, stock status fields, and schema template locations are identical in Magento Open Source.
Lifecycle products missing from sitemapModerate effort
Add every canonical product URL to your XML sitemap so search engines can discover and index your products faster.
On Magento Open Source
- Same as Adobe Commerce: Admin → Marketing → SEO & Search → Site Map → Add Sitemap.
- Ensure all live products have 'Visibility' set to 'Catalog, Search' (not 'Not Visible Individually') in Catalog → Products → Edit Product → Search Engine Optimization.
- Schedule auto-regeneration under Stores → Configuration → Catalog → XML Sitemap → Generation Settings.
- Submit to Google Search Console after regeneration.
Server versionModerate effort
Remove or suppress the Server version header so your web server software and version number are no longer exposed in every HTTP response.
On Magento Open Source
- Same server-level steps as Adobe Commerce (on-premises) above apply directly to Magento Open Source.
- On Nginx: add `server_tokens off;` to nginx.conf and use headers_more module to fully strip the Server header.
- On Apache: set `ServerTokens Prod` and `ServerSignature Off` in httpd.conf; add `Header unset X-Powered-By` in the vhost or .htaccess.
- Set `expose_php = Off` in php.ini to prevent PHP version disclosure via X-Powered-By.
- Restart the web server after changes and verify with `curl -I https://yourstore.com`.
Ssl expiryQuick win
Monitor your SSL/TLS certificate expiry date and set up auto-renewal so your store never goes offline or shows a security warning to shoppers.
On Magento Open Source
- SSL is managed at the server/hosting level — log into your hosting control panel or server and navigate to the SSL/TLS management section.
- Enable auto-renewal for Let's Encrypt, or note your paid certificate's expiry date and set calendar reminders at 60 and 30 days out.
- After certificate renewal, verify in Magento Admin → Stores → Configuration → General → Web that Base Secure URL is correct and uses https://.
- Flush the Magento cache (bin/magento cache:flush) to ensure the updated certificate is served immediately.