Application Security Engineer interview questions
100 real questions with model answers and explanations for Middle candidates.
See a Application Security Engineer resume example →Practice with flashcards
Spaced repetition · Hunter Pass
Questions
I trace the value across call boundaries and record where its security properties actually change.
- I start from concrete sources such as Express `req.query`, follow returns, parameters, fields, callbacks, and aliases, and end at sinks such as `db.query` or `child_process.exec`.
- I inspect wrappers rather than trusting their names, because `runSafeQuery` may still concatenate a string before calling the database driver.
- I use a call graph or a CodeQL path query to confirm interprocedural routes, then review each reported path for feasible control flow.
- I add a focused test with attacker-controlled input and a safe counterpart to confirm which branch reaches the sink and whether the intended sanitizer changes the value.
Why interviewers ask this: The interviewer is checking whether the candidate can reason beyond one function and distinguish naming from real data-flow guarantees.
I model separate taint kinds because a transformation safe for one sink can be unsafe for another.
- HTTP parameters, message payloads, and database values originally supplied by users are sources, while SQL execution, HTML rendering, and process creation are distinct sink classes.
- Parameter binding clears SQL taint only for value positions; HTML encoding clears output for one rendering context; neither makes a value safe for a shell.
- I model propagation through collections, object properties, builders, and framework helpers so the rule does not lose taint at ordinary application abstractions.
- I add negative tests for safe flows and positive tests for each source-to-sink combination before enabling the model in CI.
Why interviewers ask this: A strong answer treats taint as context-specific metadata and explains how the model stays both complete and precise.
I mark a helper as a sanitizer only when its contract removes the exact exploitability required by a specific sink.
- An `isUUID` check can constrain a path or identifier, but it does not sanitize the original string for HTML or a command line.
- I read the implementation for Unicode, decoding, length, and failure behavior, and confirm callers use the validated return value rather than the original input.
- I prefer modeling a typed transformation such as `parseTenantId(): TenantId` over a boolean guard because the safe value is harder to lose.
- Regression tests include bypass candidates and a rule test proving taint stops only on the intended branch.
Why interviewers ask this: The interviewer wants evidence that sanitizer modeling is tied to an explicit security contract rather than a convenient function name.
I rely on auto-escaping only for the output context the framework documents and keep track of every escape hatch.
- React text interpolation and Jinja HTML templates normally encode HTML text, but `dangerouslySetInnerHTML`, Jinja `safe`, and raw template blocks remove that protection.
- HTML-text encoding is not sufficient inside JavaScript, CSS, or a URL, so those contexts need dedicated APIs or strict allowlists.
- Server-rendered values can become DOM XSS later if client code passes them to `innerHTML`, `insertAdjacentHTML`, or an unsafe third-party widget.
- I review template configuration and custom filters because disabling autoescape globally turns a framework guarantee into an application-wide assumption.
Why interviewers ask this: This tests whether the candidate understands contextual encoding and the limits of framework defaults.
I map the changed trust boundaries first, then spend review time on code that moves or interprets untrusted data.
- I inspect route, schema, authorization, serializer, template, query, filesystem, and outbound-request changes before mechanical refactors or generated files.
- I trace one complete request from entry point to side effect and compare the new path with the existing authentication and tenant-isolation pattern.
- I examine removed checks and changed defaults in the diff, then use blame or surrounding code when the patch depends on an unstated invariant.
- I ask for focused tests around negative authorization, malformed input, and boundary cases rather than approving based only on happy-path coverage.
Why interviewers ask this: The interviewer is evaluating whether the candidate can prioritize review effort while still following a concrete end-to-end data path.
I focus on APIs that reinterpret strings as code, markup, paths, queries, or commands.
- `eval`, `Function`, string-based timers, and `vm.runInNewContext` are code-execution sinks even when the input first passes through JSON parsing.
- `child_process.exec`, `execSync`, and `{ shell: true }` invoke a shell; `spawn` or `execFile` with a fixed executable and argument array avoids shell parsing.
- `innerHTML`, `insertAdjacentHTML`, and React `dangerouslySetInnerHTML` require context-appropriate sanitization such as a tightly configured DOMPurify policy.
- Dynamic `require`, filesystem paths, and object merges need allowlists or canonicalization because they expose traversal and prototype-pollution paths.
Why interviewers ask this: A strong answer names concrete JavaScript APIs and matches each one to the interpretation boundary it creates.
I review Java APIs that execute expressions, construct queries, deserialize objects, or start operating-system processes.
- `Runtime.exec(String)` does not automatically invoke a shell: it splits the string into an executable and arguments, so shell metacharacters alone are not interpreted, although attacker-controlled executable names or options still create argument and process-selection risks.
- `new ProcessBuilder("sh", "-c", value)` explicitly invokes a shell and is vulnerable when `value` is untrusted; I instead use a fixed executable, separate arguments, and allowlisted options.
- `Statement.execute` with concatenation is a SQL sink; `PreparedStatement` protects values but cannot parameterize table names or sort directions.
- SpEL, OGNL, template or scripting evaluation, and `ObjectInputStream` over untrusted bytes can expose code-execution paths and require removal or narrowly constrained designs.
Why interviewers ask this: The interviewer is checking whether the candidate distinguishes Java argument parsing from explicit shell interpretation and recognizes other language-specific sinks.
I flag Python APIs that deserialize objects, evaluate expressions, invoke shells, or build paths and queries from strings.
- `pickle.loads`, `marshal.loads`, and unsafe `yaml.load` can construct attacker-chosen objects; JSON or `yaml.safe_load` is preferable for plain data.
- `eval`, `exec`, and dynamic imports execute code, while `subprocess.run(..., shell=True)` adds shell metacharacter interpretation.
- SQL f-strings remain injectable; DB-API placeholders must carry values, with identifiers selected from an allowlist or composed by the driver's SQL builder.
- `tarfile` or `zipfile` extraction and `pathlib` joins need destination containment checks before writing files.
Why interviewers ask this: The interviewer expects specific Python sinks and safer alternatives, not simply a warning to validate input.
A path check and a later open are separate operations, so an attacker can replace a symlink or directory entry between them.
- `realpath` followed by `open` still leaves a race window if another process can modify the checked path.
- On Linux I prefer descriptor-relative operations such as `openat` with `O_NOFOLLOW`, trusted directory descriptors, and restrictive ownership and permissions.
- I perform authorization and file use on the same opened descriptor, then use atomic `rename` for publication instead of re-resolving the pathname.
- Temporary files come from `mkstemp` or an equivalent API with exclusive creation, not a predictable name checked with `exists` first.
Why interviewers ask this: This tests whether the candidate understands that canonicalization alone does not make a multi-step filesystem operation atomic.
A security check can become stale when concurrent requests change the protected state before the write commits.
- Two redemption requests can both observe `used = false` and spend one coupon twice if the check and update are separate statements.
- I encode the invariant in one conditional update, a unique constraint, or a transaction with the required row lock, then accept only the winning result.
- For authorization tied to mutable membership, the policy check and sensitive mutation belong in the same transaction or trusted database operation.
- Idempotency keys stop duplicate retries, but they do not replace locking or constraints for two different requests targeting the same resource.
Why interviewers ask this: The interviewer is evaluating whether the candidate can turn a concurrency risk into an enforceable application invariant.
I constrain the entire outbound request lifecycle, not just the URL text received from the user.
- I parse with one well-defined URL library, allow only `http` or `https`, reject credentials and unusual numeric IP forms, and resolve every address before connecting.
- The connection layer blocks loopback, link-local, RFC 1918, IPv6 local ranges, cloud metadata addresses, and disallowed ports even after DNS rebinding.
- Redirects are disabled or each target is revalidated, with response-size, timeout, and redirect-count limits.
- High-risk fetchers run behind an egress proxy or isolated network whose allowlist makes internal services unreachable by design.
Why interviewers ask this: A strong answer covers parser ambiguity, DNS and redirects, and network enforcement rather than offering a fragile string blacklist.
I trace where typed query construction falls back to raw SQL and verify which parts still receive structural interpretation.
- APIs such as SQLAlchemy `text`, Prisma `$queryRawUnsafe`, Knex `raw`, Hibernate native queries, and string-based `orderBy` deserve sink-level review even when surrounding code uses an ORM.
- Placeholders bind values only; table names, column names, operators, sort directions, and SQL fragments must come from fixed mappings or builder APIs, not request strings.
- I inspect wrappers and tagged-template behavior because some APIs parameterize interpolations while similarly named unsafe variants concatenate them.
- Tests use metacharacters in values and unexpected identifier choices, then inspect generated SQL and results to prove data never changes query structure.
Why interviewers ask this: The interviewer is checking whether the candidate can find the precise point where an ORM's structural guarantees end.
I examine both attacker-supplied patterns and fixed patterns whose worst-case backtracking grows sharply with input length.
- Nested or overlapping quantifiers, ambiguous alternation, and repeated groups followed by a failing suffix are warning signs; anchors alone do not make such a pattern linear.
- I cap input length before matching and replace ambiguous expressions with simpler parsing, bounded quantifiers, or a linear-time engine such as RE2 where its feature set is sufficient.
- User-supplied regex is disabled or compiled through a constrained syntax and strict size limits rather than trusted because compilation succeeded.
- Regression benchmarks include near-miss adversarial strings and enforce a time budget, while process isolation or timeouts provide only defense in depth.
Why interviewers ask this: A strong answer combines code-level regex analysis, bounded input, safer engines, and adversarial performance tests.
Prototype pollution occurs when attacker-controlled property paths modify an object's prototype instead of only its own data.
- Recursive merge and path setters must reject `__proto__`, `prototype`, and `constructor` at every depth, not only at the top level.
- I update vulnerable merge libraries and prefer schema-driven copying into explicit DTOs or null-prototype maps for dictionary data.
- Authorization and configuration code must use own-property checks such as `Object.hasOwn` rather than trusting inherited defaults.
- Tests submit nested JSON and query-string forms, then verify both ordinary objects and security decisions remain unchanged.
Why interviewers ask this: The interviewer wants the candidate to explain both the pollution primitive and how inherited properties become an application exploit.
I bind the request to a strict operation-specific form object and keep the JPA entity outside the web binding boundary.
- The form declares only editable fields, while `WebDataBinder.setAllowedFields` adds a framework-level allowlist and `setIgnoreUnknownFields(false)` prevents unknown properties from being ignored by default.
- Because disallowed fields are suppressed rather than rejected automatically, I reject the request when `BindingResult` has errors or `getSuppressedFields()` is nonempty and map strict binding failures to a 400 response.
- The service copies validated values into a loaded, tenant-scoped entity and derives ownership, role, and account ID from authenticated server context, so nested paths cannot select privileged state.
- MVC tests submit privileged, unknown, and nested names such as `roles[0]` and assert rejection plus the absence of persistence side effects.
Why interviewers ask this: The interviewer is checking whether the candidate knows Spring's actual suppression and unknown-field semantics rather than merely recommending an allowlist.
I choose a data-only format with an explicit schema and avoid formats that can instantiate arbitrary runtime types.
- JSON, Protobuf, or a constrained CBOR schema carries primitives and declared messages without Java `ObjectInputStream`, Python pickle, or .NET type-name activation.
- Input limits cover nesting depth, collection size, string length, and total bytes because safe object construction can still exhaust memory or CPU.
- Authenticity such as an HMAC prevents tampering but does not make a dangerous deserializer safe if a signing key or trusted producer is compromised.
- Legacy native serialization is isolated behind an allowlist and migration boundary, with gadget-capable dependencies removed where possible.
Why interviewers ask this: The interviewer is assessing whether the candidate separates data integrity from the code-execution behavior of the deserializer.
I disable DTDs and all external entity resolution, then verify those settings on the exact parser and version in use.
- The parser must not fetch external general entities, parameter entities, schemas, or XSLT resources from network or local files.
- I apply input-size, entity-expansion, nesting, and processing-time limits to cover denial-of-service variants such as exponential entity expansion.
- If a business format requires a schema, it is loaded from a trusted local catalog rather than a URI supplied by the document.
- A regression fixture attempts file disclosure and an outbound callback so tests prove the configuration rather than merely setting a flag.
Why interviewers ask this: The interviewer expects concrete XML parser boundaries, including external schemas and resource exhaustion.
I ensure that validation, authorization, signature handling, and business logic operate on one unambiguous interpretation of the request.
- Duplicate object keys, out-of-range numbers, non-finite values, invalid Unicode, and excessive nesting are rejected before a gateway and application can choose different meanings.
- Schema validation runs on the same parsed value that business code consumes, rather than validating raw text in one component and reparsing it with another library.
- If a protocol signs canonical JSON, every producer and verifier follows the same documented canonicalization; otherwise I verify the exact raw bytes before parsing.
- Differential fixtures send ambiguous payloads through the production gateway and application parsers and assert identical rejection and no side effects.
Why interviewers ask this: The interviewer is checking whether the candidate can eliminate ambiguity where several parsers protect one code path.
I treat the decoder and every derived artifact as untrusted processing inside an isolated pipeline.
- The service checks magic bytes and decodes the image with a patched library, then re-encodes a supported format instead of preserving attacker-controlled metadata or polyglot content.
- Pixel count, dimensions, frame count, decompressed memory, CPU time, and output size are bounded before thumbnail generation.
- Processing runs as a non-root identity in a sandbox with no network, a read-only filesystem, and a fresh temporary directory.
- Original and generated objects use random keys in private storage, and downloads receive fixed content types plus `Content-Disposition` rather than browser sniffing.
Why interviewers ask this: The interviewer is checking for layered controls across decoding, resource limits, isolation, storage, and delivery.
I extract into an isolated temporary directory under strict path and resource limits, then validate the resulting file set.
- Each entry is normalized and resolved beneath the destination; absolute paths, parent traversal, symlinks, hard links, devices, and duplicate normalized names are rejected.
- Limits cover entry count, per-file size, total expanded size, compression ratio, nesting, and processing time to stop archive bombs.
- Extraction uses safe library APIs and descriptor-relative writes, then a second stage parses only allowlisted file types as an unprivileged worker without network access.
- Nothing is published until the entire import succeeds, and cleanup removes partial output on every failure path.
Why interviewers ask this: A strong answer addresses path escape, decompression abuse, special entries, parser chaining, and atomic publication.
Locked questions
- 21
How would you prevent authorization bypasses caused by Express router and middleware composition?
authidentity-accessmiddleware - 22
How do `state` and `nonce` serve different purposes in an OpenID Connect login?
identity-accesscryptographyoidc - 23
How would a resource server enforce sender-constrained OAuth access tokens with DPoP, including replay and nonce handling?
oauthtokensidentity-access - 24
How do you prevent JWT algorithm and key confusion in application code?
jwtalgorithms - 25
How would you design the lifecycle of a sensitive web session?
sessionsdesign - 26
What does an application need to verify during WebAuthn registration and authentication?
authidentity-accesswebauthn - 27
A workspace application has organization roles, document sharing, and regional restrictions; how would you compose its authorization policy?
authidentity-access - 28
How would you integrate a centralized authorization policy engine into application code?
authidentity-access - 29
How would you define canonicalization for an API request-signing scheme without creating verification bypasses?
api - 30
How do you design authorization tests for a multi-tenant REST API?
authidentity-accessrest - 31
How would you threat-model a feature that lets users add a new passkey to their account?
threat-modeling - 32
How would you threat-model workspace invitation links in a multi-tenant SaaS product?
multi-tenancythreat-modelingcloud - 33
How would you use STRIDE and abuse cases for a bulk CSV user-import feature?
stride - 34
How would you threat-model a product feature that sends outbound webhooks to customer-configured URLs?
threat-modelingwebhooksconfig - 35
How would you threat-model private file sharing through expiring links?
threat-modeling - 36
How would you threat-model changing the primary email address on an account?
threat-modeling - 37
How would you threat-model a saved-payment-method feature using a payment processor's tokens?
tokensconcurrencythreat-modeling - 38
How would you threat-model a GraphQL backend-for-frontend that aggregates several internal services?
graphqlgraphql-authorizationaggregation - 39
How would you threat-model asynchronous customer-data exports delivered through object storage?
threat-modelingasync - 40
How would you threat-model an AI assistant that can call application tools on a user's behalf?
threat-modeling - 41
How would you design a Semgrep taint rule for a project-specific SQL wrapper?
sqldesignsemgrep - 42
What makes a custom Semgrep rule safe enough to offer an autofix?
semgrep - 43
How would you model a custom framework in a CodeQL data-flow query?
queriescodeql - 44
How do you improve the precision of a CodeQL security query without hiding real vulnerabilities?
queriesvulnerabilitiescodeql - 45
A SAST finding lands in generated code that is overwritten on every build; how would you decide where to fix it without suppressing the vulnerability?
vulnerabilitiessast - 46
How should SCA reachability influence dependency vulnerability prioritization?
dependenciesscavulnerabilities - 47
How do SBOM and VEX artifacts work together during vulnerability response?
artifactssbomvex - 48
What application supply-chain properties do signed builds and provenance provide?
- 49
How would you assign ownership and maintenance for security regression tests across several application teams?
regressionsecurity-regressionownership - 50
How would you use OWASP ASVS to define and verify requirements for an application release?
owaspasvs - 51
A Python report builder stores a user-defined filter safely, but later concatenates that filter into an SQLAlchemy text query; how would you trace and fix the second-order SQL injection?
sqlqueriesorm - 52
A Node.js URL preview service validates the first DNS answer, follows five redirects with undici, and was observed reaching 169.254.169.254; how would you fix redirect and DNS-rebinding SSRF?
validationssrfdns - 53
A Java API accepts a base64 `preferences` blob and Jackson enables default typing; a test payload instantiates an unexpected class, so how would you remediate the deserialization path?
api - 54
A Go import worker uses `archive/zip` and joins each entry name to `/tmp/import`; how would you fix an archive that writes through `../../` and a symlink entry?
joins - 55
A Flask email-preview endpoint passes a user-edited template to `render_template_string`, and `{{ config.items() }}` exposes secrets; how would you trace and fix the server-side template injection?
secretsinjectionconfig - 56
A Java download service writes a stored filename into a raw `Content-Disposition` header, and a CRLF filename creates a second response header; how would you trace and fix the response splitting?
tracing - 57
A FastAPI video endpoint builds `ffmpeg -i {filename} {output}` and calls `subprocess.run(..., shell=True)`; how would you fix the multi-step command injection without breaking unusual filenames?
injectionendpointsframeworks - 58
A React support console sanitizes Markdown before storage, but a later admin export reparses the original Markdown with `dangerouslySetInnerHTML`; how would you fix this stored XSS chain?
reactreact-xssxss - 59
A Spring document service parses uploaded SVG files with a default `DocumentBuilderFactory`, and a test entity reads `/etc/hostname`; how would you remediate the XXE path?
xxe - 60
An Express download route decodes `req.params.name` before passing it to a helper that decodes again, allowing `%252e%252e%252f`; how would you trace and fix the traversal?
tracing - 61
A money-transfer API accepts a password-only session even though the web UI requires recent MFA; what traffic and code evidence would you collect to debug the missing step-up check?
passwordssessionsidentity-access - 62
A Go API accepts a token with `alg: HS256` even though production issues RS256 JWTs; how would you prove and fix the verifier confusion?
tokensapi - 63
After a Rails deploy, two concurrent login requests sometimes leave the pre-login session ID valid; how would you debug and correct the session rotation race?
sessionsdeploymentconcurrency - 64
A credentialed API reflects `Origin` when it matches `/example.com$/`, and Burp succeeds from `evil-example.com`; how would you debug and fix the CORS policy?
corsappsec-tools - 65
CSP reports show that a cached HTML page reuses another response's nonce, and an injected script executes only on cache hits; how would you diagnose and fix it?
htmlcachingcryptography - 66
A GraphQL DataLoader caches `userById` globally, and traces show tenant B receiving an object first loaded by tenant A; how would you isolate and fix the authorization failure?
authidentity-accessgraphql - 67
Stripe webhook signatures fail only after an Express middleware change, while replayed events sometimes create duplicate credits; how would you debug both issues?
middlewarewebhooks - 68
A background PDF export returns another tenant's invoices even though the initiating REST endpoint checks ownership; how would you trace the broken object authorization?
authidentity-accessrest - 69
A single-page app refreshes sessions successfully, but a stolen old refresh token also works within 30 seconds; how would you debug token-family rotation?
tokenssessions - 70
A CSRF regression appears only when a payment form uses `fetch` after a frontend rewrite; how would you use browser traffic and server code to locate it?
csrfforms - 71
How would you write and tune Semgrep models for Express input reaching an internal `runTool` wrapper around `child_process.spawn`?
semgrep - 72
An Express service adds routes faster than authorization tests, and CI missed a new admin endpoint because it was absent from a hand-maintained list; how would you build a route-policy coverage gate?
authidentity-accesscoverage - 73
A Prisma service repeatedly introduces `findUnique({ where: { id } })` for tenant-owned models; how would you add a schema-aware CI check without flagging global tables?
schema - 74
After a protobuf code-generator upgrade, malformed money values reach a Go handler because validation annotations are no longer emitted; how would you make the pipeline catch this regression?
validationgeneratorsci-cd - 75
An IAST agent sees no tainted path in a Spring checkout service even though a manual test confirms injection; how would you improve the pipeline?
injectionci-cd - 76
Semgrep reports 900 XSS findings in generated React API clients, with only 6 confirmed issues in handwritten components; how would you reduce noise responsibly?
reactcomponentsapi - 77
A custom Semgrep rule for Flask SSTI has 94% precision but missed two historical incidents; how would you build a regression suite before enforcing it?
incidentsframeworksregression - 78
Security wants to know whether a new CodeQL query is useful after scanning 30 repositories; which false-positive metrics and sampling method would you use?
monitoringcodeqlqueries - 79
A monorepo security job must stay under eight minutes, but changed-file scanning misses flows through shared TypeScript packages; how would you tune the pipeline?
monorepoci-cdtypescript - 80
A Next.js application enforces Trusted Types, but a production bundler plugin introduces DOM sinks that source-only checks do not see; how would you gate the built frontend?
domnextjstrusted-types - 81
A product is replacing passwords with emailed magic-link sign-in and a support-assisted account-recovery fallback; how would you threat-model the change?
passwordsthreat-modeling - 82
A GitHub App will analyze customer repositories and open automated security-fix pull requests; what threats and release criteria would you define?
code-review - 83
A SaaS product will let customers configure outbound webhooks with custom headers and ten retries; how would you prevent header injection and credential leakage?
configcloudwebhooks - 84
A desktop product is adding third-party JavaScript plugins that can read project data and call APIs; how would you design the threat model and minimum sandbox?
threat-modelingdesignapi - 85
A multi-tenant observability product will let customers define regular-expression redaction and routing rules for every ingested event; how would you threat-model the flow?
multi-tenancythreat-modelingobservability - 86
A mobile banking app is adding universal links for payment approval and a custom-scheme fallback; how would you review the change?
- 87
An HR SaaS product is adding SCIM 2.0 provisioning with customer-defined group-to-role mappings; how would you threat-model it before launch?
threat-modelingcloud - 88
A project-management app lets guests unlock a shared project with a password and optionally comment; how would you secure the commenting capability?
passwords - 89
A SaaS marketplace will let users install third-party OAuth apps that read workspace data and post messages; how would you threat-model installation and consent?
oauthidentity-accessdependencies - 90
A CRM is adding bidirectional contact sync with a third-party OAuth provider and inbound change callbacks; how would you threat-model the integration?
oauthidentity-accesscallbacks - 91
A HackerOne report claims account takeover through password reset but includes only screenshots and no request sequence; how would you triage it?
passwords - 92
Five bounty reports describe IDOR across invoice view, PDF download, email resend, export, and mobile API routes; how would you decide duplicates and root-cause groups?
api - 93
A stored XSS requires a workspace editor role but executes in a billing administrator's browser; how would you combine CVSS with business impact?
xssvuln-management - 94
A bounty report finds SSRF in image import, and code search reveals the same `fetchRemote` helper in three features; how would you coordinate remediation?
ssrf - 95
A researcher plans to publish an SSTI report in 14 days, while the product team estimates a safe renderer migration will take 10 days; how would you coordinate disclosure and remediation?
estimationmigrations - 96
A product owner requests a 45-day exception for a high-confidence CodeQL command-injection finding because the replacement library misses a launch date; what would you require?
injectionerror-handlingcodeql - 97
Three teams repeatedly introduce unsafe URL fetches despite review guidance; what developer enablement would you ship?
- 98
A bounty report demonstrated two synchronized withdrawals spending the same balance twice, and the team added an idempotency key; what evidence would you require before closure?
idempotencyclosures - 99
Two researchers report different exploit chains that both end in admin template execution; how would you score and remediate them without losing chain details?
attacks - 100
After closing a webhook signature bypass, how would you turn the remediation into practical enablement for the product team?
webhooks