- List six components of an e-commerce site and which are customer-side or admin-side.
- Why must the cart total be calculated from the database and not from a hidden form field?
- Why do we use a transaction when saving an order?
- Write the SQL for page 3 with 8 products per page.
- Explain authentication versus authorisation. What is an IDOR bug?
- Why can a website never "send you your old password"? Describe a safe reset process.
- What is stored in the database for "stay signed in", and why is only a hash of the validator stored?
- What is a cached like count? How do you keep it consistent?
- Why is the gateway's return page not enough to mark an order as paid?
- Why use PHPMailer with SMTP instead of
mail()?
Show answers
Customer side: product catalogue and search, shopping cart, checkout and payment, registration/login and password reset, order history and likes. Admin side: product management, order management, user and role management, sales reports, inventory.
Anything sent from the browser (hidden fields, prices in JavaScript) can be edited by the user in DevTools, so they could pay Rs. 1 for an expensive item. The server must look up the real price from the database for each product id and calculate the total itself.
Saving an order needs several steps: insert the order, insert the order items, and reduce the stock. A transaction ensures they all succeed or are all rolled back, so there is never an order without items, or stock reduced for an order that failed.
- SQL
SELECT * FROM products ORDER BY id LIMIT 8 OFFSET 16; -- OFFSET = (3 - 1) * 8 Authentication checks who you are (logging in). Authorisation checks what you are allowed to do (for example only admins can manage products). An IDOR (Insecure Direct Object Reference) bug happens when the server uses an id from the URL without checking ownership, so changing
order.php?id=15toid=16shows another customer's order. Fix:WHERE id = ? AND user_id = ?(unless the user is an admin).Passwords are stored as one-way hashes (
password_hash), so the site does not know the original password and cannot send it. Safe reset:- The user enters their email; always show the same message whether or not the account exists.
- Create a random token (
random_bytes), store its hash with a short expiry (for example 1 hour). - Email a link containing the token.
- On the link, check the hash and expiry, let the user set a new password (
password_hash), then delete the token (single use) and the user's remember-me tokens.
The
auth_tokenstable stores the user id, a random selector, the SHA-256 hash of a random validator, and an expiry date. The cookie holdsselector:validator. Only a hash of the validator is stored so that if the database is stolen, the attacker still cannot build a working cookie (just as passwords are hashed).A cached counter (
products.like_count) stores a ready-made number of likes so pages do not have toCOUNT(*)thelikestable on every view. Keep it consistent by updating it in the same transaction as the insert or delete inlikes(+1 or −1), using a primary key on(user_id, product_id)to stop duplicate likes, and occasionally recalculating it from thelikestable.The return page is only a browser redirect, and the user can type or fake that URL, or close the browser before reaching it. The order should be marked paid only when the gateway's server-to-server notification (webhook / IPN) arrives and its signature and amount are verified (or by querying the gateway's API).
PHP's
mail()depends on the server's mail setup, gives no authentication or proper error reporting, and its messages often land in spam. PHPMailer with SMTP logs in to a real mail server (with TLS), supports HTML email and attachments, gives clear error messages, and is more reliably delivered.