Pentesters can find meaningful API vulnerabilities from a running system without source code, but source-assisted testing improves coverage and root-cause precision when the API has complex authorization, hidden routes, multiple frameworks or distributed trust. The strongest model remains adversarial runtime testing, with targeted code access used to discover hypotheses, inspect control consistency and guide remediation—not to replace proof in the deployed application.

Define the architecture question before testing

Choose access based on the assurance question. Black-box testing measures what an external attacker can discover. Grey-box access adds accounts, API specifications and architecture. Source assistance reveals routes, policy calls and dangerous sinks. None alone proves the deployed build and configuration behave securely.

Write the expected security invariant and the prohibited outcome in language that engineering, security and operations interpret the same way. Name the identity, trust transition, protected asset and authoritative state. That statement becomes the basis for scope, evidence and retesting.

Build the minimum evidence pack

  • A current component and trust-boundary diagram for the environment under test.
  • Identity, credential, network and data-flow details relevant to the decision.
  • Representative accounts, workloads and synthetic records with known ownership.
  • Logs or traces that follow the action through every material control point.
  • Explicit safety limits, stop conditions, owners and restoration steps.

Provide the tested build, API specs, role and tenant accounts, architecture, deployment configuration and a targeted source view of route registration, authentication, authorization, serialization, storage and integration code. Define repository boundaries and protect proprietary material through least access and confidentiality controls.

Understand what runtime-only testing does well

A running API reveals actual exposure, network controls, authentication behaviour, deployed configuration and exploitable composition. It preserves the adversarial need to discover paths and chain effects.

  • Enumerate documented and observable routes and versions.
  • Exercise tokens, roles, tenants and object relationships.
  • Test parsing, workflow and integration behaviour.
  • Validate findings against authoritative state.
  • Observe gateways, caches and deployed infrastructure controls.

Runtime proof should include exact request, identity, state and effect. It can still miss unreachable branches, rare conditions and routes not discoverable during the window.

Use source access to improve route and sink discovery

Code can expose registered endpoints, hidden feature paths, dangerous interpreters, dynamic queries, object deserialization and internal integrations that are difficult to infer externally.

  • Trace route registration and version aliases.
  • Find authorization helpers and direct repository access.
  • Review user input reaching queries, templates, commands or fetchers.
  • Inspect webhook, queue and background consumers.
  • Compare source routes with gateway and runtime inventories.

Treat suspicious code as a hypothesis until the deployed path is confirmed. Dead code, protected routes or non-deployed branches should not be reported as exploitable findings.

Inspect authorization consistency without trusting appearances

Source assistance helps compare policy use across dozens of handlers, but reviewers must understand data ownership and runtime identity propagation.

  • Find handlers that omit the standard policy helper.
  • Trace tenant context from token to data query.
  • Inspect bulk, nested and administrative operations.
  • Check service calls that replace user identity with workload privilege.
  • Review cache and asynchronous consumers for the same invariant.

Validate representative gaps through runtime identities and objects. Report the common root cause and affected pattern rather than dumping every code search match.

Test the deployed configuration and build

Source can look correct while feature flags, environment variables, gateway rules, dependency versions or deployment artifacts create a different behaviour.

  • Tie commit and artifact identifiers to the target.
  • Compare security-relevant flags and environment settings.
  • Verify gateway, WAF and identity-provider configuration.
  • Check generated routes and framework defaults.
  • Confirm secrets and cloud permissions outside the repository.

Record any build-to-source uncertainty as a limitation. Never claim a code fix is live until the target demonstrates it.

Protect developer trust and intellectual property

Source access should be narrow, time-bound and auditable. Security value does not require uncontrolled repository copies.

  • Grant read-only access to relevant repositories or snapshots.
  • Exclude unrelated products and embedded credentials.
  • Use approved workspaces and retention periods.
  • Log access and revoke it after closure.
  • Control code excerpts in reports and evidence.

The engagement agreement should define source handling, disclosure, deletion and who can receive code-level evidence.

Turn code insight into better remediation

Source-assisted testing can point to the owning middleware, repository, serializer or service rather than recommending an endpoint patch.

  • Identify the failed invariant and control owner.
  • Show the relevant code path without over-collecting source.
  • Recommend pattern-level changes and safe interfaces.
  • Add negative tests near the policy boundary.
  • Locate sibling consumers needing migration.

Developers should be able to reproduce the runtime proof and understand why the control failed. Code location alone is not a remediation plan.

Retest in the running application

A reviewed patch can still be misconfigured, bypassed or absent from the deployed artifact. Final closure belongs to runtime evidence.

  • Repeat the original request and preconditions.
  • Test alternate routes using the same changed helper.
  • Verify the deployed version contains the fix.
  • Confirm legitimate behaviour and performance remain acceptable.
  • Inspect final data and asynchronous side effects.

Closure should connect source change, artifact, environment and observed runtime result while preserving any residual coverage limitations.

Execute as controlled hypotheses

  1. Establish the legitimate baseline and capture authoritative state.
  2. Change one trust variable—identity, route, scope, object, time or environment.
  3. Observe the decision at each layer rather than relying only on the response.
  4. Stop at the minimum proof that demonstrates or rejects the hypothesis.
  5. Restore test state and record residual uncertainty or blocked coverage.

Begin from the external or grey-box perspective, then use source to target blind spots and systemic patterns. Keep access least-privileged and prevent secrets from entering evidence. Do not substitute static search results for exploitation, and do not spend the engagement performing an unfocused full code audit.

Report the architectural consequence

Label each conclusion as runtime-proven, source-observed, configuration-confirmed or unvalidated hypothesis. Include the tested artifact, evidence chain and affected pattern. This lets stakeholders understand assurance strength without overstating code review.

Separate observed evidence from inference. State prerequisites, repeatability, blast radius and the shared component responsible for the decision. When multiple findings have one architectural cause, keep the individual proofs but group the remediation around the common control.

Required closure evidence

  • The original proof no longer succeeds.
  • A legitimate workflow still succeeds under the intended identity and route.
  • Alternate consumers of the same pattern enforce the same invariant.
  • Telemetry records both allowed and denied decisions with useful context.
  • The architecture record and threat assumptions reflect the new control.

Remediate at the durable control point

Fix at the shared policy, repository or platform boundary revealed by the code path; add negative tests; remove insecure alternate routes; and ensure build and deployment controls carry the fix. Use source insight to reduce recurrence, not merely accelerate one patch.

Retest the invariant, not just the payload

Deploy the candidate fix and repeat the attack path against the running API. Sample sibling handlers identified through source analysis, verify flags and gateway configuration, and confirm authoritative state. A pull request approval is not a penetration-test retest.

Use the NIST Technical Guide to Information Security Testing and Assessment for assessment planning and evidence discipline, and the OWASP Web Security Testing Guide for relevant application techniques. Adapt both to the system-specific trust decision described here.

The architecture decision

Choose runtime-only testing for a realistic external view, and add source assistance when hidden surface, complex policy or systemic remediation justifies it. Preserve adversarial proof: the assessment is strongest when code explains where to look and the deployed system proves what an attacker can actually do.

Ask WIMD to choose the right API testing depth from external runtime testing through targeted source-assisted validation.