All 74 Security quiz questions below come with a short explanation, visible right on the page — no sign-in needed. They're grouped by beginner and intermediate levels and 33 subtopics, so you can revise one part at a time. Choose Try Security quiz above to take a scored run and review the questions you got wrong.
What the Security quiz covers
Practices6
Access Control4
Headers4
Passwords4
Sessions4
Validation4
Authentication3
Authorization3
Injection3
Rate Limiting3
API Keys2
CORS2
Cryptography2
CSP2
CSRF2
Dependencies2
Encryption2
Error Handling2
File Upload2
JWT2
Logging2
Secrets2
XSS2
API Security1
Cloud1
Containers1
Frontend1
Monitoring1
OAuth1
Path Traversal1
SSRF1
Supply Chain1
Transport1
Beginner level — 20 Security questions
Question 1·Injection
What is the most reliable way to prevent SQL injection?
A.Escape single quotes before concatenating into the statement
B.Allow only alphanumeric characters in every form field
C.Prepared statements with parameters, never string concatenation
D.Filter dangerous SQL keywords out of the input
Answer: C
Prepared statements / parameterization: WHERE email = $1 and pass the value separately. The DB treats parameters as pure data and never parses them into statements — so there is no way to inject SQL.
How should user passwords be stored in a database?
A.Hash with MD5 but add a long per-user salt
B.Encrypt with AES using a key in an environment variable
C.Hash with SHA-256 plus one system-wide salt
D.Hash them with bcrypt or argon2, with a per-user salt
Answer: D
bcrypt or argon2 (argon2id if choosing today), with a per-password salt generated by the library itself. The core point: the hash function must be deliberately slow — SHA-256 is fast, so it is unsuitable even with a salt.
You accidentally committed an API key and pushed to GitHub. First action?
A.Switch the repository to private so nobody can see it any more
B.Revoke that key immediately, then clean up the git history
C.Add the file to .gitignore and commit again to tidy it up
D.Remove the commit from the history and force push
Answer: B
Revoke the key first and issue a new one. Bots scan GitHub continuously and often find secrets within minutes, so assume the key is already compromised. Cleaning git history comes after and does not replace revocation.
pnpm audit reports a critical vulnerability in a dependency. Sensible step?
A.Ignore it if the project has had no problems in practice
B.Immediately upgrade every dependency to its newest version
C.Check whether the vulnerability affects how you use it, then upgrade
D.Replace the library with an equivalent one
Answer: C
Read the vulnerability description and check whether it actually applies to how you use it (many issues only affect features you don't use, or only appear in dev dependencies), then upgrade to a patched version.
When an API errors, what should it return to the client?
A.Only the status code with no message at all
B.The failed query so the cause is easier to find
C.The full stack trace so the client can report the bug to developers
D.A short message with an error code, with the detail written to the logs
Answer: D
A short message that doesn't leak internals along with an error code for the client to handle, and an error id for correlation. Stack traces, SQL statements, file names and library versions go only into server-side logs.
What situation does two-factor authentication protect against?
A.The password leaks but the second factor is missing
B.Insiders accessing data outside their remit
C.A session cookie stolen through an XSS hole
D.Data being read in transit over an insecure network
Answer: A
It protects against the case where the password is already compromised — leaked from another site, guessed, or obtained through simple phishing. An attacker holding the password still lacks the second factor. It's the most effective measure relative to the effort it takes to protect an account.
When logging requests for debugging, what must never be logged?
A.Passwords, tokens, card numbers and sensitive identifying information
B.The endpoint path the client called
C.The id of the user who sent the request
D.The processing time and the returned status code
Answer: A
Never log passwords, tokens, card numbers, OTP and sensitive personal data. Logs pass through many systems and are accessible to more people than the DB, so they are often the easiest leak to go unnoticed.
Which attack does X-Frame-Options: DENY (or frame-ancestors) prevent?
A.CSRF — sending a request with cookies from another site
B.Session cookie theft over an unencrypted connection
C.Clickjacking — embedding your page in an iframe to trick clicks
D.XSS — injecting script into your page
Answer: C
Clickjacking: the attacker embeds your real page in an iframe and overlays an invisible layer, so the user thinks they're clicking a button on the attacker's site but is actually clicking your page — with their logged-in session.
A.A production copy with every email address replaced
B.Synthetic data, or data with the personal information masked
C.A production copy for maximum realism
D.Empty data, created as needed
Answer: B
Faker-generated data or a copy with personal information masked/replaced. Staging usually has weaker passwords, less monitoring, and more people with access — so copying real data verbatim duplicates the risk into the weakest place.
How does the Referrer-Policy header relate to security?
A.It decides which sites may call your API
B.It stops other sites linking to your page
C.It stops users being redirected to an unknown page
D.It limits how much of your page's URL is sent to other sites
Answer: D
It controls how much of the current URL is sent along when the user clicks through to another site. If the URL contains a password reset token or internal id, a loose default leaks them to external sites and their analytics.
B.User accounts from having their passwords guessed
C.The data already stored in the database and in files on the server
D.The whole application source from being reverse-engineered
Answer: A
HTTPS protects data in transit: TLS encrypts the content, verifies integrity, and authenticates the server's identity via a certificate. Once the request reaches the application, the data is back in plaintext — every risk at the storage, authorization, or logic layer remains.
What is the core difference between hashing and encryption?
A.Hashing is one-way while encryption can be reversed with a key
B.Hashing needs a secret key while encryption needs no key at all
C.Hashing is for files and encryption is for character strings
D.Encryption always produces output shorter than the original data
Answer: A
Hashing is a one-way function: the same input always yields the same fixed-length output, with no way back. Encryption is a reversible, keyed transformation: whoever holds the right key can recover the original data. So passwords must be hashed, while data you need to read back (card numbers, tokens) must be encrypted.
Should an API return 401 or 403 when the user is logged in but lacks permission?
A.403 — the identity is valid but the access is not permitted
B.500 — so the resource's existence is not disclosed
C.400 — because the request is invalid in business terms
D.401 — every access-related error uses this code
Answer: A
403 Forbidden. 401 Unauthorized means "not authenticated or invalid credentials" and comes with a WWW-Authenticate header; 403 means "we know who you are, but you're not allowed". For sensitive resources where revealing existence is itself a risk, you can deliberately return 404 instead of 403.
Why is SHA-256 a poor choice for storing user passwords?
A.Because 256 bits of output is too short to hold a long password
B.Because SHA-256 can be reversed to recover the original password
C.Because collisions have been found in SHA-256
D.Because it is so fast that billions of guesses per second are possible
Answer: D
SHA-256 is designed to run fast, and fast is exactly what an attacker wants: a single GPU can try billions of candidates per second. Passwords need a dedicated hash function with a cost parameter — Argon2id, bcrypt, or scrypt — plus a random salt per user.
What is the difference between reflected and stored XSS?
A.Stored only affects the person who posted the content while reflected affects everyone
B.Reflected runs on the server while stored runs in the user's browser
C.Reflected is exploited through cookies while stored is exploited through localStorage
D.Stored keeps the payload in the system and serves it to many people
Answer: D
Reflected: the payload lives in the request (usually the query string), is reflected by the server into the response, so each victim must be lured into clicking a link. Stored: the payload is saved to the database and then served to every viewer — broader reach and usually rated higher severity.
A.It protects the API from being called too many times in a short period
B.It protects users: stopping another site from reading an API's response
C.It protects the server: blocking requests from disallowed origins
D.It protects data in transit from eavesdropping
Answer: B
CORS is a browser mechanism that protects users: by default the Same-Origin Policy stops page A from reading responses from origin B; CORS headers are how origin B says "I allow A to read". It doesn't block requests from reaching the server, so it's no substitute for authentication and authorization.
Is validating uploads by file extension alone safe enough?
A.Yes, when the file is stored outside the web server's root directory
B.No — the filename is set by the client so it can be anything
C.Yes, if the server renames the file before saving it to the directory
D.Yes, because the browser only offers files of the declared type
Answer: B
Not enough. The filename and Content-Type are both supplied by the client. You need to check the actual content (magic bytes), use an allowlist of file types, rename on save, store outside the static-serving directory, and return with a fixed Content-Type plus Content-Disposition: attachment where appropriate.
Under current NIST guidance, which password policy should be dropped?
A.Checking new passwords against a list of breached ones
B.Letting users paste a password from a manager
C.Requiring a minimum length of eight characters
D.Forcing a password change every 90 days
Answer: D
Drop forced periodic password rotation when there is no sign of compromise, and drop mandatory character-composition rules. Instead: encourage long passwords, check against breached-password lists, allow paste, and require a change only when there is evidence the account was affected.
What does the HttpOnly flag on a session cookie do?
A.It stops JavaScript reading the cookie via document.cookie
B.It stops the cookie being sent with requests from other sites
C.It forces the cookie to be sent only over an encrypted HTTPS connection
D.It limits the cookie's lifetime to one browsing session
Answer: A
HttpOnly makes the cookie invisible to JavaScript: the browser still sends it with requests, but document.cookie can't read it. That way an XSS bug can't directly steal the session token. The trio should go together: HttpOnly, Secure, SameSite.
What does least privilege mean for an application's database account?
A.Grant exactly the privileges the application needs on exactly the tables it uses
B.Use one shared account for every service so it is easy to manage
C.Grant administrative privileges but log every statement run
D.Set a longer and more complex database password than usual
Answer: A
The application account should have exactly the privileges it uses — usually SELECT, INSERT, UPDATE, DELETE on a specific set of tables — and should not own the schema, have DROP privileges, or be a superuser. Schema migrations run under a separate account used only at deploy time.
Rendering user input in React — when does XSS become possible?
A.When displaying data fetched from an API rather than from state
B.When using a template string to build the displayed content
C.When using dangerouslySetInnerHTML with unsanitized data
D.Always, because React still inserts data straight into the DOM
Answer: C
Mainly when using dangerouslySetInnerHTML with unsanitized data. JSX escapes text by default, so <div>{userInput}</div> is safe. Risk also remains in href={userInput} (javascript:) and other attributes that take URLs.
GET /orders/:id checks that the user is logged in. What is missing?
A.Checking that the order belongs to the calling user
B.Limiting how many times this endpoint may be called per minute
C.Using a UUID instead of an auto-increment order id
D.Checking that the id is a valid numeric format
Answer: A
Missing ownership check (IDOR / broken object level authorization): authentication only answers "who are you", you must also answer "do you have permission for this resource". Query should be WHERE id = ? AND user_id = ?.
What is CSRF and what is the most common defence today?
A.An attacker reads your cookies; blocked with the httpOnly flag
B.Intercepting and modifying requests in transit; blocked by enabling HTTPS site-wide
C.Injecting script into the page; blocked with a Content-Security-Policy
D.Another site sends a request carrying your cookies; blocked with SameSite
Answer: D
An attacker's site makes your browser send a request to the real site, and cookies are sent automatically so the request looks legitimate. Mitigate with SameSite=Lax or Strict on session cookies, plus a CSRF token for state-changing operations.
When verifying a JWT, which mistake is most dangerous?
A.Using the same secret across every deployment environment
B.Not checking the token's expiry time
C.Trusting the algorithm declared in the token header instead of fixing it
D.Storing the token in localStorage instead of a cookie
Answer: C
Trusting the alg in the token header. An attacker can change it to none (no signature) or switch RS256 to HS256 and sign with the public key. The server must enforce a fixed algorithm during verification, not read it from the token.
Who does CORS protect, and what does Access-Control-Allow-Origin: * mean?
A.It encrypts data exchanged between two domains when calling an API
B.It blocks CSRF attacks from other websites
C.It protects the server from requests from unwanted domains
D.It protects the user from other sites reading data; * opens it to every origin
Answer: D
CORS protects the user: it prevents JavaScript on origin A from reading responses from origin B. * means allow any origin to read. It does not protect the server — curl or another service can still call the API normally.
For image uploads, is checking the client-provided Content-Type enough?
A.No, the client can claim anything so the content must be checked
B.No, but renaming the file after saving is enough to be safe
C.Enough when combined with checking the filename extension
D.Enough, because the browser sets the Content-Type from the chosen file
Answer: A
Not enough.Content-Type and filename are both client-controlled. You must validate the actual content (magic bytes / image parsing library), limit size, generate a new filename, and store outside the web root.
What should a login form respond when the email does not exist?
A.Return a 404 and let the client display the message
B.Redirect to the signup page with the email prefilled
C.State clearly that the email is not registered, for a better experience
D.A generic message: "email or password is incorrect"
Answer: D
A message common to both cases: "email or password is incorrect". Distinguishing them clearly becomes an account probing tool (user enumeration) — the attacker knows which emails are registered to focus attacks.
A.It encrypts data more strongly than ordinary HTTPS
B.It redirects HTTP requests to HTTPS on the server
C.It prevents the TLS certificate being swapped for a forged one
D.It forces the browser to use HTTPS only for that domain
Answer: D
Tells the browser: from now on, only connect to this domain via HTTPS, for the declared max-age. So the next time the user types http://, the browser switches to HTTPS before sending, leaving no plain-HTTP request to be intercepted in transit.
The form validates with Zod on the client. Does the server need to validate again?
A.No, if the API is only called from your own application
B.Yes — client-side validation is for the experience, not for security
C.No, if the client and server use the same Zod schema
D.Only for the fields related to payment
Answer: B
Yes, always. Client-side validation is only for fast feedback to the user. An attacker calls the API directly with curl, bypassing the entire UI. Principle: never trust anything that comes from the client.
To stop password brute-forcing, what should you rate-limit on?
A.The source IP of the request is enough to stop password guessing
B.Per account, with a permanent lock after 5 consecutive failures
C.On both the account and the IP, plus a temporary lock after repeated failures
D.Per the user's current login session
Answer: C
Combine: rate-limit per account (blocks guessing one person's password) and per IP (blocks scanning many accounts), plus a temporary lockout with increasing duration. Don't lock permanently — that just becomes a tool for blocking real users.
B.httpOnly alone is enough since it blocks JavaScript from reading it
C.httpOnly, Secure, SameSite, and a sensible lifetime
D.Secure and a Domain broadened to every subdomain
Answer: C
Three required attributes: httpOnly (JavaScript can't read it, so XSS can't steal the session), Secure (sent only over HTTPS), SameSite=Lax (mitigates CSRF). Plus a sensible expiry and the narrowest possible path.
The application connects to the database as postgres (superuser). Risk?
A.Connections are slower because a superuser needs extra permission checks
B.No log can be kept of who changed the data
C.One small vulnerability becomes full control over the database
D.A connection pool cannot be used with a superuser account
Answer: C
The blast radius becomes unbounded. A small SQL injection bug then lets an attacker drop tables, read all data, or change DB configuration. The application user should only have read/write on the tables it needs.
C.An access token leaking from client-side storage
D.An authorization code being intercepted and used by another application
Answer: D
It prevents authorization code theft: the client generates a secret code_verifier, sends its hash at the start, then sends the original when exchanging the code for a token. Anyone who obtains the code without the verifier can't exchange it for anything.
A Content-Security-Policy is most effective when it forbids what?
A.Embedding the page in another site's iframe
B.Every request to a domain other than your own
C.Loading CSS from an external CDN to prevent style injection
D.Inline scripts and eval, allowing scripts only from named sources
Answer: D
It forbids inline script and eval, allowing scripts only from declared sources (using a nonce or hash for any script that must be inline). Since most XSS payloads are inline scripts, this is the part that delivers the most value.
A download endpoint takes a filename from the query. Risk and fix?
A.SQL injection; fix it by parameterizing the query
B.Path traversal; fix it by normalizing the path and checking it stays under the root
C.SSRF; fix it by checking the destination IP address
D.XSS; fix it by escaping the filename when displaying it back
Answer: B
Path traversal: ?file=../../.env lets you read files outside the intended directory. Prevent it by joining the path, normalizing it (path.resolve), then checking the result is still inside the allowed root directory.
Is checking permissions only on the frontend (hiding buttons) enough?
A.Enough for reads; only writes need server-side checks
B.No, the server must check again because the API can be called directly
C.Enough if the route is protected on the client too
D.Enough if the token already contains the user's role
Answer: B
No. Hiding buttons is just user experience. Anyone can open the network tab, see the endpoint, and call it again with curl. Every authorization decision must be enforced on the server, for both reads and writes.
For an email password-reset flow, how should the token behave?
A.Valid until the user sets a new password
B.It contains the user id and a timestamp, signed with a secret
C.A 6-digit code so the user can retype it easily
D.Securely random, single-use, expiring within minutes
Answer: D
Generate it with a secure random source (crypto.randomBytes), make it single-use, expire it after 15–60 minutes, and invalidate it immediately once used or when a new reset is requested. Store a hash of the token in the DB, not the original.
You must store national ID numbers for later verification. How?
A.Store it in plain text but restrict access to the table
B.Store only the last 4 digits for verification
C.Hash it like a password so nobody can read the content
D.Encrypt it with a separately managed key and decrypt only when genuinely needed
Answer: D
Distinguish clearly: if you need to read it back, encrypt (don't hash); if you only need to compare, hash. For national ID numbers, encrypt with a key managed outside the DB (KMS or secret manager), restrict who can decrypt, and log every decryption.
Issuing API keys to partners — how should the keys be stored?
A.Store the original so support can show it to partners who forget it
B.Store the original but let only admins see the value
C.Encrypt it with the system's key and decrypt when comparing
D.Store a hash and show the original exactly once at creation
Answer: D
Store the hash, show the original only once at creation. If a partner loses the key, issue a new one — no view function. This is the same principle as passwords: the system doesn't need to know the original value.
A user changes their password. What should happen to existing sessions?
A.Invalidate only sessions on other devices of the same type
B.Let them expire on their own schedule
C.Leave them, since the password is unrelated to the session
D.Invalidate them all, optionally keeping their current session
Answer: D
Invalidate all old sessions (usually keeping the current one). Otherwise an attacker who already hijacked a session keeps using it normally — while the user thinks changing the password made them safe.
Passing user data into a shell command (e.g. calling ffmpeg). Safe approach?
A.Allow only alphanumeric characters in the input
B.Spawn the process with an argument array rather than through a shell
C.Wrap the argument in double quotes when building the string
D.Escape the special characters before concatenating into the command string
Answer: B
Use the spawn API with an argument array (spawn('ffmpeg', ['-i', filePath, ...])), not exec with a command string. Without a shell interpreting it, ;, &&, backtick, and $() are just ordinary characters in an argument.
An SMS OTP endpoint is called repeatedly. What is the concrete risk?
A.Old OTPs stay valid so they are easier to guess
B.The user receives many codes and does not know which one to use
C.The carrier blocks the sending number for too many messages
D.It costs real SMS money and can be abused to harass unknown numbers
Answer: D
Two things are lost immediately: money (every SMS costs real money, so the attacker burns your budget) and reputation (your service becomes a tool for sending spam to strangers). You must rate-limit by phone number, by IP, and by account.
You find signs of unauthorized access. First action?
A.Rebuild the server from scratch to be sure it is clean
B.Change every password and key across every system
C.Notify the users about the incident right away
D.Preserve the logs and evidence, then close the access path being used
Answer: D
Preserve evidence (back up logs, snapshot state) then block the path being used. Work in order: record → isolate → determine scope → revoke credentials → recover → notify per your obligations.
What is the risk of keeping an access token in localStorage versus an httpOnly cookie?
A.A token in localStorage cannot be sent with requests
B.localStorage is cleared when the user closes the tab
C.JavaScript can read it, so one XSS hole hands over the token
D.localStorage has a size cap so a long token is truncated
Answer: C
JavaScript can read localStorage, so any XSS (even from a dependency with injected code) can steal the token. A cookie with httpOnly can't be read by scripts — in exchange you have to handle CSRF with SameSite.
In code review, which changes deserve the most security attention?
A.Changes to variable naming and directory structure
B.Changes in the build tool's configuration files
C.Changes that increase the application's bundle size
D.Changes in authentication, authorization and input handling
Answer: D
Three areas: authentication, authorization, and input handling (along with DB queries, shell commands, file paths). One wrong line there is a vulnerability, whereas a mistake in display code is just a bug.
A post-login redirect takes the destination URL from the query. Risk?
A.An open redirect — using your domain to lead people to a fake page
B.CSRF — the request is sent with the session cookie
C.Path traversal — the URL may point outside the root directory
D.SSRF — the server calls a URL the user supplied
Answer: A
Open redirect: the attacker sends https://site-that-thuc.com/login?next=https://site-gia.com. The link looks trustworthy because it starts with your real domain, but the destination is a phishing page.
An endpoint GET /api/invoices/:id only checks that the token is valid, then returns the invoice. What vulnerability is this?
A.Session leakage — the token is reused after it has expired
B.CSRF — the request carries the user's session cookie
C.IDOR — no ownership check on the resource
D.SQL injection — the id is concatenated straight into the query
Answer: C
This is IDOR (Insecure Direct Object Reference), part of Broken Access Control — the number one category in the OWASP Top 10. Authentication is present but there's no per-record authorization check, so simply changing :id lets you read someone else's invoice. The fix: every query must be scoped to the owner.
A controller binds the whole JSON body straight onto a User entity and saves it. What is the concrete risk?
A.It slows queries because the entity must update every column
B.Mass assignment — the client sends a role field to escalate itself
C.It only causes type errors when a field does not match the schema
D.No risk, as long as the interface shows no input for those fields
Answer: B
Mass assignment: a request like {"email":"…","role":"admin"} will write the role column too, because the field name matches an entity property. The fix is to use a DTO that explicitly declares an allowlist of permitted fields and map manually, instead of binding the whole object from the body.
A.It restricts sending the cookie with requests originating from another site
B.It encrypts the cookie's value before the browser writes it to disk
C.It forces the cookie to be sent only over HTTPS
D.It stops JavaScript reading the cookie via document.cookie
Answer: A
SameSite decides whether a cookie is sent along with a cross-site request. Strict never sends it on navigation from another site; Lax (the current browser default) sends it only on top-level GET navigations; None sends it always and requires Secure.
Why is immediate logout hard to implement with JWT access tokens?
A.Because a JWT's payload is encrypted so the server cannot read it
B.Because a JWT has no expiry field so it never becomes invalid
C.Because the browser keeps the JWT in memory and will not delete it
D.Because the server only checks the signature and expiry rather than any stored state
Answer: D
JWTs are stateless: the server only verifies the signature and exp, with no session table lookup, so there's nowhere to mark "this token has been revoked". The practical approach: give access tokens a short lifetime (5–15 minutes) and handle revocation at the refresh token — stored in the database, rotated, and invalidated on logout.
A login page reads a ?next= parameter and redirects there after sign-in. Unvalidated, what vulnerability does this create?
A.Clickjacking — the page is embedded in another site's iframe
B.Session fixation — the attacker presets the victim's session id
C.Stored XSS — the value is saved to the database and rendered again
D.Open redirect — leading the victim to the attacker's domain
Answer: D
Open redirect. An attacker spreads a link like https://site-that-nguoi-dung-tin.vn/login?next=https://site-gia.example; the victim sees a familiar domain and clicks, then gets sent to a fake page to re-enter their credentials. The fix: only accept internal paths, or match against a domain allowlist.
A system limits login attempts to 5 failures per IP per 15 minutes. Which attack still gets through?
A.Logging in with a password obtained through a phishing email
B.A denial-of-service attack aimed at the login page
C.Credential stuffing from many IPs, trying each account once
D.Brute force running continuously from one server for hours
Answer: C
Distributed credential stuffing: the attacker already has a list of leaked email/password pairs and runs it through a botnet, so each IP only tries a few times. You also need rate limiting per account and per (account, IP) pair, plus system-wide anomaly detection.
A production API key was committed to Git three months ago. What is the first thing to do?
A.Revoke it and issue a new key
B.Delete the line containing the key and commit again
C.Switch the repository to private
D.Rewrite the repository history with git filter-repo
Answer: A
Rotate the key first — revoke the old one, issue a new one, update where the secret is stored. Everything else (rewriting history, adding a scanner) comes later, because a key that has sat in Git history for 3 months must be treated as already exposed.
What problem does the Strict-Transport-Security (HSTS) header solve that an HTTP-to-HTTPS redirect does not?
A.Prevents SSL stripping after HSTS is remembered
B.A TLS certificate expiring without anyone noticing
C.Cookies being sent with cross-site requests
D.Mixed HTTP content embedded in an HTTPS page
Answer: A
HSTS blocks SSL stripping: a 301 redirect only works *after* an HTTP request has left the user's machine, and a man-in-the-middle can intercept that exact request. With HSTS, the browser remembers that this domain is HTTPS-only and upgrades every subsequent access on the client side.
How should a forgot-password form respond when the submitted email does not exist?
A.Return the same message as when the email does exist
B.Return a 404 so the client can display an appropriate message
C.State clearly that the email is not registered so the user can correct it
D.Redirect straight to the registration page
Answer: A
Return an identical neutral message for both cases: "If this email is in our system, we have sent password reset instructions." Differences in content, status code, or response time turn the form into a user enumeration tool.
The UI hides the "Delete" button for non-admin users. Is that enough to prevent deletion?
A.No — the delete endpoint can still be called directly
B.Yes, because users generally do not know the endpoint's address
C.Yes, if the token expires after a few minutes
D.Yes, if the application uses a framework with CSRF protection
Answer: A
Not enough. Hiding the button is only UX, not access control. Every data-changing endpoint must check role and ownership on the server; the UI layer only accompanies it so users don't see actions they can't perform.
A CSP has script-src 'self' 'unsafe-inline'. Why is it nearly useless?
A.unsafe-inline reopens the door to inline scripts
B.Without default-src the browser ignores the whole policy
C.CSP only works when sent as a <meta> tag
D.'self' allows loading scripts from every subdomain of the site
Answer: A
CSP's biggest value against XSS is blocking inline scripts; declaring 'unsafe-inline' reopens exactly that door. The right approach is a nonce or hash per legitimate script, combined with strict-dynamic so you don't have to list subsequently loaded scripts manually.
An "import image from URL" feature accepts any address the user types. What is the main risk?
A.CSRF — the request carries the user's cookies
B.Bandwidth leakage from downloading very large files
C.SSRF — the server calls internal addresses on the user's behalf
D.XSS — the downloaded image file could contain malicious JavaScript
Answer: C
SSRF (Server-Side Request Forgery): an attacker points the URL at 169.254.169.254 (cloud metadata), localhost, or internal IP ranges, turning the server into a bridge into the private network. This was the path in the 2019 Capital One incident, which led to the leak of data on over 100 million people.
Which field must never be written to application logs?
A.The internal identifier of the logged-in user
B.Each request's path, method and status code
C.The access token value in the Authorization header
D.The execution time of each database query
Answer: C
Never log credentials and sensitive data: tokens, passwords, card numbers, OTP codes, API keys, session cookies. Logs are usually forwarded to centralized systems, retained for months, and accessed more widely than the database — so a token sitting in a log is a leaked session.
Why is SMS-based two-factor authentication considered weaker than TOTP?
A.SMS codes are shorter so they are easier to guess sequentially
B.TOTP codes expire while SMS codes never do
C.SMS is unencrypted while TOTP travels over an encrypted channel
D.The phone number can be taken over through a SIM swap
Answer: D
The SMS channel is outside the application's control: SIM swap, SS7-layer redirection, and codes shown on the lock screen all let an attacker obtain the code. TOTP generates codes locally from a shared secret, so there's no transmission channel to intercept. NIST downgraded its recommendation for SMS back in 2016.
By what mechanism does a prepared statement prevent SQL injection?
A.The database runs the query in a session with reduced privileges
B.The statement is parsed first and the parameters are sent separately as data
C.The driver strips dangerous SQL keywords out of the parameters
D.The parameters have their special characters escaped before being concatenated
Answer: B
A prepared statement separates structure from data: the database parses and plans the statement with placeholders first, then receives the values. Because the parse tree is already fixed, the string ' OR 1=1-- is only ever understood as a string value, never as syntax.
Customer national ID numbers must be stored and sometimes displayed back. What is the right storage approach?
A.Encrypt with a key managed in a dedicated key management service
B.Base64-encode it before saving to a text column
C.Hash with Argon2id and store only the hash
D.Store it in the clear but restrict read access to a few accounts
Answer: A
Data that must be read back needs two-way encryption: AES-GCM with keys held by a key management service (KMS, Vault), kept completely separate from the database. Alongside that: mask partially by default when displaying, log every decryption, and only decrypt at the moment it's needed.
An API takes its token only via the Authorization header and uses no cookies. Does it need CSRF protection?
A.No — the browser does not attach that header automatically
B.Yes — every data-changing API must have a CSRF token
C.Yes — because an attacker can read the token from localStorage and send it
D.No, but only if the API sets SameSite=Strict on every cookie
Answer: A
No. CSRF exploits the browser automatically attaching credentials (cookies, HTTP Basic, client certificates). The Authorization header must be set by JavaScript, and another site's JavaScript can't read your token, so a valid request can't be constructed.
npm audit reports a critical vulnerability in a transitive dependency. What is the first step?
A.Add the package to an ignore list so the pipeline continues
B.Immediately run npm audit fix --force to update everything
C.Verify whether the application actually reaches the affected code
D.Remove the direct dependency pulling in that package
Answer: C
First assess exploitability in your context: does the application call the vulnerable function, is the input user-controlled, does the package run in production or only at build time. Only then choose: upgrade the version, pin a patch, or record a time-limited accepted risk.
A mobile app needs to call a paid third-party API. Where should the API key live?
A.On your backend; the app calls your backend which calls onward
B.In a configuration file downloaded at app startup
C.Embed it in the source but obfuscate it so it is hard to read
D.In a build-time environment variable of the mobile app
Answer: A
The key must live in your backend; the mobile app calls your backend with the user session, and the backend calls the third-party API. Any secret packaged with the app can be extracted by unpacking the install package or by intercepting traffic on a compromised device.
A.Because a root process consumes more memory than an ordinary user
B.Because an image running as root cannot be pushed to a public registry
C.Because a container running as root will not start on Kubernetes
D.Because a container escape then arrives with high privileges on the host
Answer: D
A container is not as strong a security boundary as a VM. Without user namespaces enabled, root inside the container is uid 0 on the host, so a runtime bug or a misconfigured volume mount grants high privileges on the server. Declare a non-root USER in the Dockerfile.
An S3 bucket with customer invoices was accidentally made public. What prevents this at the organization level?
A.Enable the account-level public access block
B.Enable access logging to spot when someone downloads a file
C.Move it to a cold storage class to limit access
D.Use a hard-to-guess bucket name so nobody finds it
Answer: A
Enable account-level Block Public Access. This setting applies to all existing and future buckets, so a bad policy on one bucket still can't create public access. Add an organization-level SCP so nobody can turn that setting off.
Which event should trigger an immediate alert rather than just being logged?
A.A user typing the wrong password twice and then logging in
B.An endpoint returning 404 for a path that does not exist
C.Request volume rising 20% at peak hours
D.An account being granted administrative privileges outside working hours
Answer: D
Alert on rare, high-impact events: permission changes, creation of new access keys, successful logins from an unfamiliar location or device on admin accounts, disabling of logging, and bulk access to sensitive data. Alerting on everyday events just causes alert fatigue.
An application builds a shell command from a user-supplied filename. What is the best way to prevent command injection?
A.Escape the special characters in the filename before concatenating
B.Block dangerous characters such as semicolon and pipe
C.Invoke the program directly with an argument array, bypassing the shell
D.Run the command as a lower-privileged user
Answer: C
Use an API that takes an argument array instead of a command string: execFile("convert", [input, output]) in Node, subprocess.run([...], shell=False) in Python. With no shell, ;, |, $() are just characters in the filename. Also: validate the filename against an allowlist and run with least privilege.
A.A path containing the email and a timestamp encoded in base64
B.A random, single-use token that expires quickly
C.A six-digit code emailed to the user, valid for 24 hours
D.A token that stays valid until the user changes their password
Answer: B
The token must be sufficiently random (from a cryptographic source, ≥128 bits), single-use, expire in 15–60 minutes, and be stored hashed in the database. After a successful password change, invalidate all open sessions and notify the user by email.
How should a public API handle a client-supplied pagination limit parameter?
A.Only limit anonymous users and let authenticated ones through
B.Push the limiting down to the database with a timeout
C.Accept the client's value and return an error if the query is too slow
D.Cap the value server-side regardless of what the client sends
Answer: D
Always clamp the value server-side: set a sensible default and a hard ceiling (e.g. default 20, max 100), and ignore values above the ceiling rather than erroring. This falls under "Unrestricted Resource Consumption" in the OWASP API Security Top 10.
A.The package manager preferring the higher version from the public registry
B.An indirect dependency not being recorded in the lockfile
C.The internal registry not supporting authentication for downloads
D.Developers mistyping a package name when installing
Answer: A
It exploits package source resolution order: when an internal package name (@company/utils or company-utils) also exists on the public registry with a higher version, many configurations will pull the public one. Prevent it by scoping the internal registry and pre-registering the package names on the public registry.
A.RBAC grants by role while ABAC decides from contextual attributes
B.RBAC is for internal users and ABAC for external customers
C.RBAC is an open standard while ABAC is a vendor-proprietary model
D.RBAC is checked at the API layer and ABAC at the database layer
Answer: A
RBAC: permissions attach to roles ("editor can edit posts"). ABAC: decisions are computed from attributes at access time ("can edit if they're the author, the post is unpublished, and it's during working hours"). RBAC is easy to understand and audit; ABAC is more flexible but harder to reason about and test.
What is wrong with generating session tokens using Math.random()?
A.The function is slow so it becomes a bottleneck with many sessions
B.It returns a floating-point number so there are not enough characters for a token
C.That generator is predictable so the tokens can be guessed
D.The result differs between browsers so the tokens are inconsistent
Answer: C
Math.random() is a pseudo-random generator not intended for cryptography: its internal state can be recovered from a sequence of outputs, so the next token is predictable. Use a cryptographic random source: crypto.randomBytes(32) (Node), crypto.getRandomValues() (browser), secrets (Python).