Security
Web apps can be exposed or compromised in many ways. This guide covers the security practices every Shoplazza app should follow. They protect merchant data, and most of them are also verified during app review.
Protect against common web vulnerabilities
Your app must be protected against common web security vulnerabilities, including but not limited to the OWASP Top 10. The OWASP Top 10 is a standard awareness document that lists the most critical security risks to web applications, together with cheat sheets and references that explain how to defend against each of them.
For a Shoplazza app, pay special attention to:
- Injection: use parameterized queries or an ORM for every database access. This includes data that arrives from webhooks and API responses — treat it as untrusted input, the same as form input.
- Cross-site scripting (XSS): escape any merchant- or customer-provided content before rendering it in HTML, and set a
Content-Security-Policyheader to limit where scripts can be loaded from. - Broken authentication: never accept a
shopURL parameter as proof of identity. Read the store domain from a verified session token or a validated OAuth callback instead.
If a vulnerability is discovered during app review, your app will be rejected until you fix it. The Web Security Academy is a free training resource with interactive labs if you want to go deeper.
Encrypt traffic with TLS
All data exchanged between a client (such as a merchant's browser) and your app server must be encrypted with Transport Layer Security (TLS), so that data in transit can only be read by your server. Your app must be served over HTTPS with a valid certificate — a self-signed certificate is not accepted.
If you don't have a TLS certificate yet, you can get one free of charge from Let's Encrypt; a certificate issued by any trusted certificate authority is acceptable. After installing it, verify the setup with SSL Checker.
Set up iframe protection
An embedded app runs inside an iframe in the Shoplazza admin. If your app can be framed by arbitrary sites, an attacker can overlay it with invisible elements and trick a logged-in merchant into clicking actions they never intended — this is known as clickjacking.
To prevent it, set the Content Security Policy frame-ancestors directive on every response that renders HTML, allowing only the admin of the store that is currently using your app. The store admin lives on the store's own subdomain, so the value must be set dynamically per request:
Content-Security-Policy: frame-ancestors https://{shopdomain}.myshoplaza.com;
Replace {shopdomain} with the store domain from the verified session token or OAuth context — never from an unvalidated query parameter.
If your app is not embedded in the admin, disallow framing entirely:
Content-Security-Policy: frame-ancestors 'none';
To learn more about clickjacking, refer to OWASP Clickjacking or the frame-ancestors documentation on MDN.
Generate and verify tokens securely
Tokens your app issues
If your app relies on its own tokens to authenticate users, generate them randomly with at least 128 bits of entropy (64 bits only where token length is a hard constraint). Use your language's cryptographic random source:
For tokens that are publicly accessible (for example, included as a URL parameter):
- Set an expiration date of no more than seven days.
- Prevent the token from being leaked to or indexed by third parties: block search indexing with a
noindexmeta tag, and send aReferrer-Policyheader oforigin-when-cross-originor, preferably,no-referreron any URL that accepts a token.
Tokens Shoplazza issues
Verify every session token on your backend before trusting it — check the HS256 signature with your CLIENT_SECRET and reject expired tokens. See verifying a session token for the full steps and code.
If your app stores its own user credentials, store only salted password hashes, never plain passwords. Follow the OWASP Password Storage Cheat Sheet. And never collect Shoplazza account credentials — public apps must authenticate through OAuth.
Verify webhook signatures
Anyone who knows your webhook endpoint can send it forged requests. Before processing any webhook, verify the HMAC signature that Shoplazza attaches to each delivery, and respond with 401 when verification fails. See signature verification for the algorithm and code samples.
The same applies to your app's shared secret: it's the key that signs these messages, so keep it out of client-side code, public repositories, and logs.
Don't expose unnecessary network services
Avoid exposing any services publicly unless they are essential to your app. Common services that should never be reachable from the public internet include MySQL, Redis, Memcached, and Elasticsearch — bind them to internal interfaces or place them behind a firewall.
During app review, Shoplazza scans your app's host with Nmap for open ports. If unexpected ports are found, you'll be asked to explain what runs on them, why they must be public, and how they are secured — or to close them.