Neutron, our AI engine, scored 97.1% on UC Berkeley's CyberGym benchmark. Learn more

Product

Product

Ostorlab vs. Manual Pentesting: More Critical Findings, Less Time, Lower Cost

Ostorlab reports more critical findings, shorter testing time, and assessment costs of one-tenth to one-fortieth of manual pentests in completed head-to-head PoCs. Examine the technical evidence and comparison limits.

Ostorlab automates penetration-testing work that otherwise requires a tester to investigate application behavior, develop attack hypotheses, execute tests, and validate impact. For AppSec teams buying manual pentests, the comparison is whether Ostorlab can find more critical vulnerabilities, deliver the results sooner, and reduce assessment cost on the same scope.

Our team reports that Ostorlab found more critical vulnerabilities, completed testing sooner, and cost one-tenth to one-fortieth as much as the manual pentests it ran alongside in every completed head-to-head proof of concept. The completed comparisons covered mobile applications, web applications, source code, and Active Directory testing.

Ostorlab vs. manual pentesting: reported PoC results

Measure Result reported by the Ostorlab team
Critical findings More critical findings than the parallel manual assessment in every completed comparison.
Testing time Testing completed sooner in every completed comparison; engagement durations and a measured speedup range are not published here.
Assessment cost One-tenth to one-fortieth of the parallel manual assessment cost across the completed comparisons.

These are our team's engagement results for the scopes and access conditions assessed. They are not an independent benchmark or a guarantee for another application. This article does not publish the cohort size, matched finding counts, engagement durations, or itemized cost breakdown. The reported cost range is therefore not a forecast of your total savings; a comparison on your scope should include setup, human review, retesting, and engineering effort.

The technical cases explain the investigation and validation work behind Ostorlab's results. In one mobile assessment, the agent extracted credentials from a Flutter iOS binary, tested their permitted API audiences, and demonstrated access to an identity-management API. In an enterprise application assessment, it obtained an administrative token without a client secret and used that token to reach a feature that executed supplied server-side code. These are examples of the investigative work a customer hires a pentester to perform.

Technical evidence behind the comparison

The following anonymized examples come from Ostorlab finding records and execution histories. They show what the platform investigated and confirmed. They do not identify findings missed by a particular human tester or independently substantiate the aggregate comparison results; customer-level scorecards and auditor reports are not published here.

Investigation Demonstrated result Limit of the evidence
Mobile credential → Management API Token issuance for a second audience and a directory-page read User-management write scopes were present but not exercised.
Secretless token → server execution Protected API access, supplied code execution, privileged process identity, and outbound connectivity Results apply to the assessed configuration and access path.
Enrollment ownership Unauthorized reads and persisted writes to a tester-controlled enrollment Final activation and login did not complete.
Mobile signing and logging Recoverable signing material and a locally reproduced masking gap Backend acceptance, live telemetry transmission, and credential replay remained unverified.

The mobile credential case and the secretless-token-to-server-execution chain are detailed in Cases 1–3. Additional technical evidence covers enrollment, signing, and logging. A separate AD lab example is included there for readers evaluating internal testing; it is not customer comparison evidence. Code excerpts use synthetic values and illustrate the reported mechanisms rather than reproduce captured customer exchanges.

To inspect the deliverable before arranging a call, open the web sample report or mobile sample report.

Case 1: a leaked mobile credential reached the tenant management API

Ostorlab assessed an iOS application built with Flutter that used Auth0 machine-to-machine credentials to obtain API access tokens. The application's compiled binary contained the client_id and client_secret, supplied at build time through Flutter's DART_DEFINES mechanism. The assessment tested whether those credentials were valid and which APIs they could access.

The expected boundary. A machine-to-machine credential should be scoped to the one audience and set of operations its service needs. A credential embedded in a distributed client is not a secret; it is available to anyone who can obtain the build. The assessment therefore examined both whether the credential was live and what else it could authenticate to.

The investigation. The agent extracted the credential from the Mach-O binary and requested a token from the tenant's /oauth/token endpoint. The request succeeded with HTTP 200 and a signed JWT; a fabricated credential returned HTTP 401. The token carried a read:TSC scope, a client-credentials grant, and a signing key traceable to the tenant's JWKS endpoint.

The initial finding was rated High. The record also labels it “Fixed & Verified,” but the material available for this case does not document the repair or its retest chronology. That label alone does not establish that the credential was rotated or that its access was removed.

To assess access beyond the API used by the app, Ostorlab submitted token requests for 38 candidate audiences to the same token endpoint. In these requests, the audience identifies the API for which access is requested. A token request for the tenant's Management API audience returned HTTP 200 with a token carrying eight scopes, including update:users, delete:users, create:users, and create:client_credentials. A single non-destructive GET to the Management API returned the first page of a 1,000-record user directory containing emails, phone numbers, last IPs, and login behavior. The assessment demonstrated this read; it did not exercise the token's user-create, update, or delete permissions.

Diagram: mobile credential, audience enumeration, and management API access
Open full-size diagram

The token endpoint accepted the extracted client credentials for both the internal-service audience and the Management API audience. A subsequent directory request confirmed read access through the Management API.

Illustrative HTTP sequence · synthetic host, client, and token values.

# The credential is extracted from the mobile binary.
POST /oauth/token HTTP/1.1
Host: tenant.example.invalid
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=MOBILE_CLIENT&client_secret=EXTRACTED_SECRET&audience=AUDIENCE_A
# Article outcome: a read:TSC token for the internal service.

POST /oauth/token HTTP/1.1
Host: tenant.example.invalid
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=MOBILE_CLIENT&client_secret=EXTRACTED_SECRET&audience=MANAGEMENT_API
# Article outcome: a token with eight management scopes.

GET /api/v2/users?per_page=100 HTTP/1.1
Host: tenant.example.invalid
Authorization: Bearer FAKE_MANAGEMENT_TOKEN

# Article outcome: the first page of a 1,000-record directory.
Evidence collected What it established
Credential extracted from the shipped iOS binary The secret was distributed to every installation, not held server-side.
Token request with the extracted credential returned HTTP 200; a fabricated credential returned HTTP 401 The credential was live, not a stale build artifact.
read:TSC scope and a client-credentials grant in the first token The app's intended audience was an internal service.
38 candidate audiences tested against the same token endpoint The credential's authorization surface was broader than the app's use.
Token request for the Management API audience returned a token with eight scopes, including user create, update, and delete The token carried management write permissions; those operations were not exercised.
One non-destructive GET returned the first page of a 1,000-record user directory The impact extended to tenant-wide PII, not just a scope label.
The initial finding for the app's own audience was labeled “Fixed & Verified”; the Management API finding remained open A status label did not establish that access across all audiences had been removed; the repair chronology is not documented here.

Assessment result. The extracted credentials could obtain tokens for the internal service and the Management API. The directory read confirmed access to personal information; the management write permissions remained untested. Remediation verification therefore needs to cover the client's permitted audiences, rather than only the API called by the app. The available records do not document which repair was attempted between the two findings.

What Ostorlab automated. This assessment combined binary analysis, live credential validation, audience enumeration, and a controlled API read. A tester performing the investigation manually would need to carry out and connect those same steps. Ostorlab established the credential's usable access beyond the API called by the app, giving the AppSec team a validated exposure to prioritize and a broader retest requirement.

The remediation direction. Remove the secret from the client and rotate it. Review the client's permitted audiences and scopes, and separate tenant-management credentials from client-facing service credentials. Invalidate tokens issued under the vulnerable configuration. The retest should enumerate the client's full authorization surface, not only the audience the app calls.

A longer write-up of this case is available in the Agentic Deep Scan case study.

Case 2: administrative access from a secretless token request

In an enterprise application assessment, Ostorlab found an identity-service configuration that issued administrative tokens without a client secret. The investigation established that the token was usable: a protected directory operation accepted it and returned hundreds of organizational profiles. The returned expiration information showed that the token could remain valid well beyond a short session, increasing the persistence risk.

The expected boundary. A client requesting administrative access should have to establish the identity and authority required for that access. An issued token also needs an appropriately restricted audience, scope, and lifetime. The test examined both issuance and use, because those are separate security decisions.

The investigation. Ostorlab submitted a token request using a client identifier and an administrative scope, with no client secret. The identity service returned a bearer token. Ostorlab then inspected the returned token's claims and used it against a protected directory operation, which returned organizational profiles.

Diagram: secretless token issuance and acceptance flow
Open full-size diagram

Issuance and acceptance are separate checks. The assessment demonstrated both: a secretless token request produced a credential that a protected directory operation accepted.

Illustrative HTTP sequence · synthetic routes, field values, and token placeholders.

# Request shape is illustrative; the article omits routes and exact fields.
POST /example/token HTTP/1.1
Host: identity.example.invalid
Content-Type: application/x-www-form-urlencoded

client_id=DEMO_CLIENT&scope=DEMO_ADMIN_SCOPE
# No client_secret and no client-authentication header.
# Article outcome: an administrative bearer token was issued.

GET /example/protected-directory HTTP/1.1
Host: directory.example.invalid
Authorization: Bearer FAKE_ISSUED_TOKEN

# Article outcome: protected access returned organizational profiles.
# Synthetic request shape; this is not a literal captured exchange.
Evidence collected What it established
Token request without a client secret, followed by successful issuance The tested client configuration permitted that issuance path.
Administrative audience and scope in the returned token The credential carried the authority relevant to the next test.
Protected directory request accepted with that token The token provided usable administrative API access.
Expiration information in the response and claims The exposure could persist well beyond a short session.

Assessment result. The test demonstrated both token issuance without a client secret and acceptance of that token by a protected directory operation. The directory request used the token obtained through the tested issuance path, rather than a supplied administrator credential. This establishes a connection between the identity-service misconfiguration and the unauthorized API access.

The remediation direction. Review the client's authentication requirements and permitted grant types; restrict its scopes and audiences; shorten the lifetime to match its purpose; and invalidate credentials issued under the vulnerable configuration as appropriate. The retest should cover both new issuance attempts and the treatment of previously issued credentials.

The remediation retest must verify both controls: client authentication at the token endpoint and authorization at the protected API.

Case 3: an integration feature executed supplied server code

In the same enterprise application assessment, Ostorlab used the administrative token from Case 2 to reach an authenticated integration feature in a vendor-supplied IAM module. The feature accepted custom C# and compiled it inside the application server process. Controlled timing tests, subprocess execution, host diagnostics, and outbound network checks demonstrated execution under the application's IIS app-pool identity — an account that was a member of BUILTIN\Administrators and held SeDebugPrivilege and SeImpersonatePrivilege.

The expected boundary. Extensibility features need an explicit trust model: who may supply executable code, where it runs, and which privileges it receives. Access to an integration configuration screen is not, by itself, an acceptable trust boundary for executing supplied code inside a privileged application process.

The investigation. The agent worked through the feature's expected interface. It wrote a probe that implemented that interface, so the payload passed compilation and type checks before its constructor ran. The application used Roslyn to compile the source in-process, loaded the resulting assembly with AssemblyLoadContext.Default.LoadFromStream(), and created the instance with Activator.CreateInstance().

A normal request established a baseline. Constructor payloads introduced controlled delays. The recorded response times followed the requested progression: a baseline around 122 ms, then roughly 2.13 s, 5.14 s, and 10.15 s for the two-, five-, and ten-second probes, with repeated probes following the same pattern. Further tests recorded subprocess execution, the identity running the code, and outbound DNS and TCP connections to a tester-controlled host.

Diagram: authenticated C# integration execution path
Open full-size diagram

The integration feature compiled and instantiated supplied C# in its server process. The requested delay ladder supported constructor execution; separate subprocess tests, host diagnostics, and egress checks established additional impact.

Illustrative C# probe · adapt to the integration interface of an authorized test fixture.

using System;
using System.Threading;

public sealed class IntegrationProbe
{
    // Implements the interface the integration feature expects.
    public IntegrationProbe()
    {
        Thread.Sleep(2000);
        Console.WriteLine(Environment.UserName);
    }
}

// Compare baseline with 2, 5, and 10 second constructor delays.
// This snippet illustrates timing and identity diagnostics only.
// The article reports subprocess execution and egress from separate tests.
Test stage Recorded observation Supported conclusion
Baseline integration input Normal response time, around 122 ms A reference for subsequent measurements.
Constructor delays of two, five, and ten seconds Response times of roughly 2.13 s, 5.14 s, and 10.15 s; repeated probes followed the same pattern Supplied constructor behavior executed synchronously.
Subprocess test Process execution evidence Execution extended beyond merely parsing or compiling a file.
Host diagnostics The worker ran as the IIS app-pool identity, was a member of BUILTIN\Administrators, and held SeDebugPrivilege and SeImpersonatePrivilege The code inherited administrative rights and credential-theft primitives, not just application-level execution.
Outbound network test DNS resolution and TCP connections to a tester-controlled host succeeded The same process could reach external infrastructure for exfiltration or payload retrieval.

The negative control. The agent also tested a sibling integration endpoint that enforced pre-instantiation type gating. The same probe was rejected before compilation or instantiation, and no timing effect appeared. This control test showed that the two integration endpoints applied different validation before executing supplied code.

Assessment result. The timing tests demonstrated constructor execution. Separate subprocess, identity, and egress tests established execution privileges and network access. The integration endpoint required authentication, supplied by the token obtained in Case 2. The demonstrated sequence was secretless token issuance, administrative API access, and authenticated server-side code execution.

The remediation direction. Keep untrusted integrations outside the privileged application process:

  • Use a separate worker with an appropriate OS-enforced security boundary. A collectible AssemblyLoadContext supports unloading assemblies; it is not a security sandbox. Microsoft describes the distinction between loading isolation and process security boundaries.
  • Give the worker a low-privilege identity, restricted access to secrets, and an egress allowlist.
  • Restrict who may create or modify integrations.
  • Retest authorization, process identity, protected-resource access, and disallowed egress. If executing integrations is an intended feature, successful compilation alone is not a failed fix.

What Ostorlab automated. Cases 2 and 3 required the agent to carry a credential from one finding into another test, construct a probe compatible with the integration interface, compare timing results, and establish process privileges and network access. This is attack-chain investigation and impact validation within the assessment. The comparison with a manual pentest should assess whether either provider found and demonstrated the complete path, alongside the time and cost required to do so.

Running Ostorlab alongside a manual pentest

Give Ostorlab and the manual pentest provider equivalent targets, accounts, access, and permitted actions. This allows your team to compare the investigation and validated findings under the same conditions. Start with a representative staging environment and dedicated test accounts where practical. If production testing is required, agree permitted actions, data access, traffic limits, and incident escalation with the application owner before execution. A connection discovered in an app does not automatically authorize testing its identity provider or analytics service.

Use this operating plan when scoping the evaluation:

Decision What to agree before execution
Assets and access Customer application owner identifies builds, endpoints, accounts, roles, supporting services, and exclusions; both providers receive equivalent access for a comparison.
Enforced restrictions Assessment operator configures firewall exclusions and traffic limits, verifies them, and records which scope restrictions are guidance rather than enforced network boundaries.
Supervision and stopping Name an operator and a customer incident contact. Agree how to stop the scan, confirm testing has ceased, revoke test access if needed, and escalate unexpected effects. Verify the stop procedure before production testing.
Schedule Record the timezone, permitted windows, scan pause behavior, and final stop conditions. Choose a scan type and operating procedure compatible with any strict cutoff.
Changes and cleanup Assign an owner for each test account, session, file, credential, and configuration change. Record restoration or revocation evidence and have the customer owner accept the handoff.

These are engagement decisions to confirm with the assessment team, not a promise that every action is automatically approved or reversed.

Scope and action controls

The October platform update describes scope guidance, firewall exclusions, traffic controls, monitoring, and requested-action approvals. The scope whitelist guides the agent; it is not a hard network boundary. Firewall exclusions block configured addresses and networks. Monitoring adds drift detection and optional shutdown.

Platform scan setup showing vulnerability scope, blocked IPs, and additional instructions
Scope guidance and enforced network exclusions have different responsibilities.

Approval settings govern decisions requested by the agent. “Ask me, block if no answer” keeps a requested action waiting for a decision; it does not require a human review before every tool call. The operator must configure these settings for the engagement.

Platform approval settings with Ask me, block if no answer selected
Requested-action approval does not mean human review of every tool call.

Execution windows and stop conditions

Execution windows specify days, hours, and timezone. A scan created outside its window waits; a pausable scan pauses at closing and resumes in the next window. Non-pausable scans continue until completion after closing. Confirm the chosen scan type's behavior before treating a closing time as an operational cutoff. A recurring schedule also needs a separate final stop condition.

Execution-window controls with timezone, preset schedules, custom overnight hours, and day selectors
Pause behavior depends on the scan type; non-pausable scans can continue after closing.

See the execution-window documentation for the supported scheduling behavior. These screenshots are platform examples from public documentation, not evidence captured from the anonymized assessments.

Compare the investigation evidence and handoff

A findings count is only useful if your team can verify the findings. Compare the manual provider's supporting evidence with Ostorlab's investigation record, including how each established exploitability and impact. Ostorlab's AI Pentest analysis view connects plans and tasks to recorded tool names, arguments, outputs, and timestamps. Inspect an important finding from its initial hypothesis through the response establishing impact. A source trace, a successful runtime test, and a blocked attack stage should be distinguishable in the report.

Risk Plan tab showing the investigation objectives and task list for a public demo application
Public documentation example: a plan identifies what to investigate; it does not prove impact.

Risk Analysis tab with the execution timeline and an expanded tool call showing arguments and output
Public documentation example: reviewers can inspect recorded commands and outputs.

The handoff should identify starting privileges, reproduced impact, unsuccessful branches, outstanding checks, and the proposed repair. Count distinct validated findings, with duplicate root causes and attack chains reconciled. Do not count an untested hypothesis as a confirmed critical vulnerability.

Execution records also help the operator verify cleanup. One reviewed web assessment recorded a support session being created, checked, revoked, and checked again to confirm logout. Apply the same discipline to changed configuration, uploaded files, and issued credentials. Record unresolved artifacts explicitly and assign an owner; logging an action is not the same as reversing it.

Extend the comparison through remediation

The comparison should include the work required to turn a finding into a verified repair. Ostorlab can carry a finding into remediation with custom fix recommendations and proposed code changes delivered through supported repository integrations. Developers review the resulting diff in their existing pull-request workflow, run the relevant checks, and use follow-up testing to assess whether the changed application resolves the original issue.

The proposed repair should address the control identified by the assessment. Enrollment findings require record-ownership checks; credential-bearing logs require changes at the logging and serialization call sites; secretless-token findings require review of token issuance and downstream authorization.

The table lists remediation and retest criteria derived from the cases; it does not claim that any particular patch has been created or merged:

Finding Proposed repair direction Meaningful retest
Secretless administrative token issuance Correct client authentication, grants, scopes, audience, and credential lifecycle. Unauthorized issuance fails; downstream access follows the corrected policy.
Authenticated code execution in an integration feature Isolate untrusted execution in a separate restricted worker; enforce authorization, least privilege, and egress policy. Unauthorized execution fails; permitted integrations cannot access protected resources or disallowed network destinations.
Enrollment ownership failure Enforce record authorization on reads and writes across the workflow. A non-owner with a valid CSRF token cannot read or change the test record.
Shared client signing secret Revisit the trust design and the request properties being authenticated. Check the revised client and server behavior, including tampered content and replay.
Credential-bearing logs Remove sensitive log inputs and cover every serialization path. Synthetic credentials are absent from queued and transmitted events.
M2M credential with tenant-management audience Remove the secret from the client; rotate; restrict audiences and scopes; separate management credentials. The client cannot obtain a Management API token; previously issued tokens are invalid.
  • Ostorlab Autofix supports custom fix recommendations, changes routed through pull requests, and follow-up verification workflows.
  • Source-code testing keeps affected paths and code revisions connected to remediation.

A generated patch still goes through engineering review and appropriate testing. Follow-up assessment evidence informs closure; a proposed diff or a successful build alone does not establish that an exploitable path has been eliminated.

Compare this workflow with the remediation and retest service included in your manual pentest. Record whether developers can reproduce the finding, implement the proposed repair, and verify that the original access or execution path is blocked, along with the effort required from your team.

Measure Ostorlab against your manual pentest provider

Use the reported PoC results as the proposition to test: more validated critical findings, shorter testing time, and lower assessment cost. A useful comparison starts with the same build, targets, accounts, source access, permissions, and exclusions. Agree the assessment window and decide how to handle changes made during testing. Record incomplete engagements and limitations rather than dropping them from the results.

Measure What to record for each provider
Validated findings Counts by an agreed severity rubric, supporting evidence, overlap, unique findings, and duplicate or disputed results. Have the customer security lead adjudicate disagreements.
Delivery time Start when equivalent access is ready; stop at delivery of the usable report. Record setup time, blocked time, and retest turnaround separately.
Total evaluation cost Provider or platform fees, model usage if separately billed, setup, human validation, reporting, retesting, and customer engineering effort. Use the same labor-rate assumptions for both sides.
Remediation usefulness Whether engineering can reproduce the finding, identify the failing control, and verify the repair; record time spent on that handoff.

Before authorizing a PoC, request an itemized quote identifying inclusions, usage limits, overage terms, retest allowance, and the customer's preparation work. Agree delivery dates after scope and access are confirmed. Use those terms and actual effort to determine whether the assessment-cost advantage reported in our completed PoCs translates into lower total cost for your team.

Questions to settle before replacing an existing pentest

Where does Ostorlab fit in our testing program? Use an initial parallel evaluation to decide which application-testing activities it can take over on your scope: authenticated workflow testing, investigation across apps and APIs, and repeat testing after changes. Keep human ownership of scope, business intent, disputed findings, operational decisions, and acceptance of fixes. Retain specialist testing for activities outside the agreed coverage. Use the findings, delivery, cost, and assurance requirements to decide how much of your current manual engagement Ostorlab can replace.

Do we have to provide source code? Ostorlab supports mobile builds, web applications, APIs, and source-code testing. The mobile credential case began with the shipped binary; the signing and logging examples used source access. Agree the assessment mode explicitly. A source-only review cannot prove live backend behavior, and a runtime-only test has different visibility from a source-assisted assessment.

What does our team need to prepare? Supply the build or target URLs, authorized services, role-separated test accounts, representative test data, and relevant API or workflow documentation. For logged-in flows, arrange the required MFA or OTP test setup with the assessment team. Identify an application owner, an operator, and an engineering contact for reproduction and retesting. Confirm preparation effort during scoping.

Where will our code, credentials, and evidence go? Review the Trust Center and on-premises scanning options with your security and procurement teams. Confirm the chosen deployment, model provider, data flows, retention, and access controls before supplying sensitive material; do not assume that every deployment has the same arrangements.

Will the report meet an external assurance requirement? Review a sample report with the party requesting the assessment. Confirm required scope, methodology, tester qualifications or independence, human review, reporting, and retest evidence before changing an existing engagement. Ask Ostorlab to identify the human validation and sign-off included in the proposed service. A technical finding alone does not establish acceptance for every assurance requirement.

Compare Ostorlab with your next manual pentest

Ostorlab's reported advantage over manual pentesting is more critical findings, shorter testing time, and lower assessment cost. The cases show the technical work the platform can perform: investigating credentials across APIs, chaining identity and execution weaknesses, and validating impact with recorded tests. A comparison on your application should establish whether those capabilities improve the results and economics of your current pentest.

Bring one representative application, its connected APIs, and your existing manual pentest scope. Use the scoping discussion to agree:

  1. Inputs: the build or URLs, test accounts and roles, source access if included, documentation, permissions, and exclusions.
  2. Deliverables: a report with reproduced findings and evidence limits, access to the investigation record, proposed remediation, and an agreed cleanup and retest handoff.
  3. Success criteria: validated findings and overlap, usable delivery time, total cost, and engineering effort, using the same definitions for both providers.
  4. Commitment: a written scope, operating plan, delivery dates, itemized quote, and named owners before testing starts.

Book an Ostorlab vs. manual pentest PoC to agree an equivalent scope, success criteria, and commercial terms for your application. Start with the web sample report or mobile sample report if you want to inspect the evidence format first.

Additional technical evidence

The following sections document enrollment authorization, mobile signing, mobile logging, and a separate Active Directory lab assessment. Each describes the test method, observed result, and validation still required.

Enrollment ownership: unauthorized reads and writes; activation remained blocked

In a self-service enrollment assessment, Ostorlab followed a workflow across record retrieval and password creation. An anonymous session could retrieve a tester-controlled record belonging to another principal, obtain a usable CSRF token, and submit password-creation requests against that enrollment. Successful responses and persisted record-version changes documented the unauthorized writes.

The expected boundary. A workflow must establish that the caller may act on the particular enrollment being changed. A CSRF token addresses a different question: whether a request carries the expected browser-session token. Possessing one does not establish ownership of a record identified in the request.

The investigation. The agent compared separate principals, including an anonymous guest session, against records created for the test. It retrieved the foreign enrollment, obtained the session's CSRF handle, submitted a password-creation request targeting that record, and read the record back to inspect the resulting state.

Diagram: enrollment ownership checks and blocked activation
Open full-size diagram

CSRF validation and record authorization answer different questions. A guest session with its own CSRF token could read and change a foreign test enrollment; the activation and login leg did not complete.

Illustrative HTTP sequence · both principals and the enrollment are tester controlled.

# Session A does not own test enrollment B.
GET /example/enrollments/TEST_RECORD_B HTTP/1.1
Cookie: guest=FAKE_SESSION_A

# Obtain FAKE_CSRF_A through the public enrollment flow.
POST /example/enrollments/TEST_RECORD_B/password HTTP/1.1
Cookie: guest=FAKE_SESSION_A
X-CSRF-Token: FAKE_CSRF_A
Content-Type: application/json

{"password":"SYNTHETIC_TEST_PASSWORD"}

GET /example/enrollments/TEST_RECORD_B HTTP/1.1
Cookie: guest=FAKE_SESSION_A

# Article: write accepted; record version changed on readback.
# Final activation and login did not complete.
Step Evidence Boundary assessed
Read a test enrollment from a non-owner session Successful record response Record confidentiality and ownership checks.
Obtain the guest session's CSRF token Token available through the public flow Availability of a valid request token to an anonymous caller.
Submit password creation for the foreign test record Successful creation response Authorization of a state-changing operation.
Read the record again Persisted version changes A durable effect beyond the initial response.
Attempt the final activation and login leg That leg did not complete Limit of the demonstrated attack path.

What the evidence proves. The assessment established cross-principal record access and credential staging on a test enrollment. It also recorded the point where the chain stopped. The final activation and login leg remained blocked in the assessed deployment, so the case does not claim a completed takeover of an active user account.

The remediation direction. Bind each enrollment operation to the authorized principal or to a deliberately designed, narrowly scoped enrollment capability. Check that binding on both reads and writes. Validate the relationships among the record, the caller, and the identity fields being changed. The regression cases should include an owner, another authenticated user, an anonymous session, and a valid CSRF token paired with the wrong record.

The enrollment defect was an authorization failure: the application accepted requests carrying a valid CSRF token without verifying that the session could access or modify the specified record.

Mobile signing: recoverable key; backend acceptance untested

In a mobile source-code PoC, Ostorlab traced an application-wide HMAC signing key reconstructed from two embedded byte arrays. The signature covered a timestamp and a fixed application marker, while the method, path, and request body remained outside the signed input. This was a source-level finding; proving the backend accepted the signature still required a runtime test.

The expected boundary. A request signature can establish only the properties represented by its key and signed message. The review therefore examined how the client obtained its key and exactly which request components entered the signing operation.

The investigation. The agent followed the reconstruction function into the API request builder. Both arrays needed to recover the shared secret were distributed with the client. The API layer then used that reconstructed value to sign the timestamp and application marker before placing the signature in request headers.

Diagram: shared signing-key reconstruction and unsigned request components
Open full-size diagram

The shipped client contained the material required to reconstruct its shared key. The traced signature covered a timestamp and fixed marker; the method, path, and body were absent from the signed input. Backend behavior remained untested.

Illustrative pseudocode · reconstruction and HMAC helpers stand in for the original implementation.

// Both embedded arrays are distributed with the client.
const sharedKey = reconstructKey(embeddedArrayA, embeddedArrayB);

// Simplified representation of the traced signing inputs.
const signedInput = timestamp + APP_MARKER;
const signature = hmac(sharedKey, signedInput);

headers["X-Example-Signature"] = signature;

// request.method is absent from signedInput.
// request.path is absent from signedInput.
// request.body is absent from signedInput.
// The reconstruction algorithm and header name are illustrative.
// Backend acceptance was not established by the source review.
Source trace Security consequence supported by the code
Both reconstruction arrays present in the client The obfuscation did not prevent recovery of the shared key.
Shared key consumed by the request builder The same signing material was reused across the traced call sites.
Timestamp and fixed marker supplied to HMAC Those values were covered by the signature.
Method, path, and body absent from the signed input The signature did not bind those request components.

What the evidence proves. The review established recoverable signing material and the composition of the signed message. It did not establish that bearer authentication or every backend ownership check could be bypassed. The backend was outside this source archive, so those questions belonged in a follow-up runtime assessment.

The remediation direction. Revisit the trust placed in a secret distributed to every client installation. Specify the security purpose of the signature, the identity it represents, the request content it binds, and the server's freshness checks. Keep user and object authorization explicit on the server. Rotate exposed signing material as part of an appropriate migration, while correcting the underlying design.

The source evidence identifies the key-reconstruction code and the signed fields. Runtime testing is still required to determine how the backend validates the signature and whether other controls prevent unauthorized requests.

Mobile logging: reproduced masking gap; live transmission unverified

In a separate Android assessment, Ostorlab traced authentication values from an OpenID result through application logging, a masking function, and telemetry serialization. Local reproduction showed that credential-shaped values survived the filter under unrecognized field names and string formats. The record identified the leakage path and the outstanding runtime checks.

The expected boundary. Authentication material should be excluded or safely redacted before it enters logs. A filter needs to handle the actual serialization used by the application, including structured fields and string representations.

The investigation. The source showed logging on the authentication-success path. One call site serialized a header map containing a cookie value; another logged an authentication result as a string. The masking function recognized a defined set of fields in a particular JSON-like format. The credential-bearing strings fell outside those names or that format.

The local reproduction included positive controls: recognized authorization and refresh-token fields were masked. The problematic cookie and code-shaped strings remained. That distinction established a concrete gap in an otherwise functioning masking mechanism.

Diagram: log masking gaps and unverified telemetry transmission
Open full-size diagram

The same filter masked recognized authorization and refresh-token fields while missing cookie-map and authentication-result strings. The source trace reached telemetry serialization; live credential transmission and replay were not observed.

Runnable local illustration · synthetic credentials and a simplified masking rule.

const mask = text => text.replace(
  /("(?:authorization|refresh_token)"\s*:\s*")[^"]*"/gi,
  '$1[REDACTED]"'
);

const known = '{"authorization":"FAKE_BEARER"}';
const refresh = '{"refresh_token":"FAKE_REFRESH"}';
const cookie = '{Cookie=FAKE_COOKIE}';
const result = 'AuthResult(code=FAKE_AUTH_CODE)';

if (mask(known).includes("FAKE_BEARER")) throw Error("control");
if (mask(refresh).includes("FAKE_REFRESH")) throw Error("control");
if (!mask(cookie).includes("FAKE_COOKIE")) throw Error("gap");
if (!mask(result).includes("FAKE_AUTH_CODE")) throw Error("gap");

// The known fields are masked; the cookie and code survive.
// This reproduces the failure class, not the original filter.

Ostorlab then followed the resulting message into the logging SDK's serialization path. Runtime traffic capture and credential replay were still outstanding, so the article does not describe observed live credential exfiltration or a completed session takeover.

The remediation direction. Remove credential-bearing log statements where possible, then make redaction consistent across structured attributes, serialized headers, and object string representations. Test successful authentication paths as well as errors. Use synthetic secrets in regression tests and assert that neither the queued log event nor its transmitted form contains them.

The assessment identifies the authentication logging call sites, the formats omitted by the masking rule, and the serialization path. These locations define the required code changes and the regression tests for credential redaction.

Separate AD lab: ACL-to-certificate chain and unresolved cleanup

In an Active Directory lab assessment, the agent started with a low-privileged domain user and enumerated the directory's access-control surface. The review covered 3,002 ACL rows across users, groups, computers, and the domain root. It identified a non-inherited WriteOwner ACE that allowed an ordinary user to take ownership of the certificate authority's service account. It was the only ACE in the corpus that gave a non-Tier-0 principal control over a Tier-0 object.

The CA service account was a member of Cert Publishers, held GenericAll on a certificate template, and was Kerberoastable with RC4.

The GenericAll grant on the certificate template was the ESC4 condition: it allowed the agent to modify the template's security settings before requesting a certificate as another principal. The WriteOwner ACE on the service account was the separate entry point into that template-control path. Cert Publishers membership and RC4 Kerberoastability were additional exposure, not prerequisites for the ESC4 step.

The expected boundary. A CA service account and its certificate templates are Tier-0 objects. Ordinary users should not own them, template ACLs should be restricted to the CA and directory administrators, and every issuance should be logged and revocable. A WriteOwner ACE on the CA account is not a routine delegation.

The investigation. The agent seized ownership of the service account, rewrote the DACL to grant itself GenericAll, and controlled the account. It modified the template to allow enrollment, requested a certificate as an administrator, authenticated with that certificate, and replicated krbtgt. It then forged a golden ticket. The misissued administrator certificate remained unrevoked.

Diagram: WriteOwner ACE, ADCS template, certificate, and DCSync path
Open full-size diagram

One non-inherited ACE gave an ordinary user ownership of the CA service account. The agent chained that ownership through an ESC4 template to a certificate and domain replication.

Illustrative execution pseudocode · synthetic names; not real tool syntax.

# Lab: ordinary user -> CA service account -> template -> certificate -> DCSync.
# Names and values are synthetic.

ace = read_ace(target="svc-ca", trustee="user-a")
# One non-inherited WriteOwner ACE in 3,002 ACL rows.

seize_owner(target="svc-ca", as="user-a")
grant_generic_all(target="svc-ca", to="user-a")
reset_secret(target="svc-ca")

template = modify_template("CorpAuthTemplate", enroll="svc-ca")
cert = request_certificate(template, subject="Administrator")
session = authenticate_with(cert)
replicate_krbtgt(session)
forge_golden_ticket()

# The misissued administrator certificate was not revoked.
Step Evidence Boundary assessed
Enumerate ACLs across the directory 3,002 rows; one non-inherited WriteOwner ACE for an ordinary user on the CA service account Whether Tier-0 objects were isolated from ordinary users.
Seize ownership and rewrite the DACL Owner seizure and GenericAll grant reproduced live; writes rolled back byte-equal Whether the ACE was exploitable, not merely present.
Control the CA service account The account was a member of Cert Publishers and held GenericAll on the template Whether the service account's rights reached certificate issuance.
Modify the template and request a certificate ESC4 condition; an administrator certificate was issued Whether template ACLs prevented enrollment as a privileged principal.
Authenticate with the certificate and replicate krbtgt Domain replication and a golden ticket Whether certificate-based authentication reached domain-controller authority.
Check revocation The misissued administrator certificate remained unrevoked Whether the organization could withdraw the credential.

What the evidence proves. The ACL takeover was reproduced live, and the account's rights reached a template the CA would use. The certificate and replication leg is recorded as the agent's critical chain; the misissued certificate was still unrevoked when the assessment ended. This is a lab assessment, not a customer result or comparative benchmark. The unrevoked certificate is an unresolved cleanup item, not evidence of a completed restoration. An equivalent engagement needs a named owner to revoke it and verify the result before accepting cleanup as complete.

Assessment result. Control of the CA service account provided access to a certificate template that could be modified to request an administrator certificate. The recorded sequence connected the initial ACL misconfiguration to certificate-based authentication and domain replication. The lab did not compare automated and manual assessment performance.

The remediation direction. Remove the ACE and review every non-inherited grant on Tier-0 objects. Separate the CA service account from ordinary administration, restrict template ACLs to the CA and directory administrators, disable RC4 for service accounts, require approval and logging for template changes and certificate issuance, revoke misissued certificates, and rotate krbtgt twice. The retest should verify that a low-privileged user cannot own the CA account or modify the template, that DCSync fails, and that forged tickets are rejected after rotation.

An internal-testing report should document the starting identity, affected ACLs, permissions obtained, validation results, unsuccessful tests, and remaining artifacts. Administrators need this information to reproduce the finding, repair the delegation, and verify cleanup within the authorized scope.