Card Data on Plain HTTP and an Order ID Anyone Can Edit
Kala Bazaar sells handmade brass lamps from Coimbatore: about 60 orders a month, average order value Rs. 3,200, hosted on a shared cPanel plan. Checkout collects card number, expiry date and CVV in the store's own HTML form and posts them over plain HTTP/1.1 to /pay.php on the same host; the details are written to a log file for "reconciliation". The confirmation email links to https://kalabazaar.example/order.php?id=1043. The admin panel has a single shared login admin with password kalabazaar@123 and no second factor. Several customers report emails from [email protected] asking them to "re-verify card details" with a link to kalabazaar.example.card-verify.info. Google Search Console flags the /blog/ directory as containing deceptive pages; the owner does not remember creating /blog/. The host's weekly backup exists but has never been restored.
1. Rank the remediation work by risk and state what must stop today. Justify each decision against the business facts given.
Read the worked answer
Stop today
- Stop accepting card data on the site. The form collects CVV and posts over plain HTTP, so the PAN and CVV travel readable across every network in between, and the log file keeps them on a shared host. Storing the CVV after authorisation is prohibited outright under PCI DSS, and a shared cPanel plan cannot meet the segmentation and key-management requirements - a neighbouring site on the same server could read the log. Replace the form with a redirect to a PCI-DSS-compliant payment gateway (Razorpay, PayU, Stripe). The card never touches the store's server, so the store drops to SAQ A with a much smaller scope. Delete the existing log file and grep backups for PANs.
- Enforce HTTPS everywhere: a redirect from port 80, HSTS, and
Secure+HttpOnlycookies. Plain HTTP also exposes the session cookie used by the admin panel.
This week
3. Investigate /blog/. An unknown directory that Google calls deceptive is a strong sign of a compromised host - an uploaded webshell used for a phishing kit. Take the site offline or move the DNS, pull the files and access logs, change every credential, and only then rebuild. Attacker persistence beats any other fix.
4. Fix order.php?id=1043 (next task). Leaking a customer's address and phone is a privacy problem even without payment data.
5. Per-admin accounts with 2FA; admin / admin@123 style shared credentials mean one leak compromises everything and nothing is attributable.
This month 6. Test a restore of the backup. An untested backup is a hope, not a control; with 60 orders a month, losing six weeks of order data is survivable, but only if the restore actually works. 7. Publish SPF/DKIM/DMARC and warn customers - the phishing domain is not the store's and cannot be taken down by editing the site.
Ranking logic: active compromise > live card exposure > credential weakness > resilience.
2. Name the vulnerability in `order.php?id=1043`, walk through the exploit, and give the code-level fix.
Read the worked answer
This is IDOR - Insecure Direct Object Reference (CWE-639), a broken access control. The page accepts a database key from the client and uses it without checking that the requester owns that record.
Exploit path: a customer clicks the link in the confirmation email, sees id=1043, and edits it to id=1042 or id=1100. The page runs SELECT * FROM orders WHERE id = ? and renders the full order - name, phone, address, items. IDs are sequential, so one order page yields a complete walk of the whole order book, and there is no rate limiting to stop it. The URL is also a poor secret: it sits in the email body, in browser history, and is sent in the Referer header to any third-party asset on the page, so the link leaks even without editing.
Fix - authorise the session, do not trust the parameter:
session_start();
$orderId = (int)($_GET['id'] ?? 0);
$stmt = $pdo->prepare(
'SELECT * FROM orders WHERE order_id = ? AND cust_email = ?'
);
$stmt->execute([$orderId, $_SESSION['cust_email']]);
$order = $stmt->fetch();
if (!$order) { http_response_code(404); exit('Not found'); }
The AND cust_email = ? clause makes someone else's order indistinguishable from a non-existent one, so the page leaks nothing about which IDs exist. Casting (int) rejects 1043abc. Better still, send an opaque token in the link - random_bytes(32) hex, stored per order with an expiry - so the URL is not guessable even if the ownership check is later refactored away. Prefer POST if the page carries any action. Add Referrer-Policy: no-referrer so the URL stops leaking to third parties, and log repeated 404s from one session as an attack signal. Never rely on hiding the ID by obfuscation or base64 encoding; both are reversible.
3. Classify the `mailinator.com` email, explain whether SPF, DKIM and DMARC would have stopped it, and say what the store should actually do about it.
Read the worked answer
It is phishing - specifically a brand-lookalike phishing attempt using a lookalike domain (kalabazaar.example.card-verify.info, where the real name is a subdomain of an attacker-controlled .info). It is not pharming, which redirects the victim at the DNS/hosts level so the real URL bar shows a wrong site; the customer is clicking a link in an email. It is not SQLi or XSS - no injection into the store's application is involved. The request for CVV is the tell: a genuine merchant never needs the CVV re-verified.
Would SPF/DKIM/DMARC stop it? No. Those records protect kalabazaar.example: SPF authorises sending IPs, DKIM signs the message, DMARC tells the receiver what to do with mail that fails and claims to be from your domain. The attacker sent from @mailinator.com, a domain they control or abuse, so nothing in the store's DNS is consulted. Mailinator would have to publish the records. This is the classic wrong mental model - the anti-spoofing stack stops someone sending as your domain, which is why a spoofed [email protected] would be blocked, but it does not stop a lookalike domain.
What the store should do:
- Publish SPF, DKIM and
_dmarcwithp=quarantine(thenreject) so its own domain cannot be spoofed - a real risk for order confirmation emails customers may trust blindly. - Warn customers in the confirmation email and on the site: "We never ask for your CVV or card number by email", and confirm that the only domain used is
kalabazaar.example. - Give buyers a way to verify an order by logging in, rather than clicking links.
- Report the URL to the host and to Google Safe Browsing; submit the mailinator address for abuse handling.
- Monitor newly registered lookalike domains, and keep TLS plus HSTS intact so users who mistype are less likely to land on an HTTP clone.