Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Application Security

DAST Scanning: How It Works & What It Finds

DAST scanning probes your live web app for vulnerabilities source code analysis misses. Learn how DAST works, what it finds and how to run one in CI/CD.

Offensive360 Security Research Team — min read
DAST scan DAST scanning dynamic application security testing DAST tools web application security testing DAST vs SAST automated security testing authenticated DAST scan DAST CI/CD web application vulnerability scanner

A DAST scan — Dynamic Application Security Testing — attacks your live web application the same way a security researcher would: by sending crafted HTTP requests, observing responses, and inferring whether vulnerabilities exist from the application’s behavior. Unlike SAST tools that read source code, DAST tools need a running application and have no visibility into the code at all.

This makes DAST fundamentally complementary to static analysis. DAST finds vulnerabilities that only appear at runtime — authentication flaws, misconfigured HTTP headers, business logic issues, and injection vulnerabilities that manifest only when the application is processing real requests. SAST finds vulnerabilities that only appear in code — hardcoded secrets, insecure code patterns, and complex data flows that a running-application test cannot reliably trigger.

This guide explains exactly how DAST scanning works, what it detects, how to configure it for authenticated applications, and how to integrate it into your CI/CD pipeline.


How a DAST Scan Works

A DAST scan proceeds in three phases:

Phase 1: Crawling (Discovery)

The DAST scanner crawls the application to discover its attack surface. For traditional server-rendered applications, this works like a search engine spider — following links, submitting forms, and mapping all reachable URLs.

For modern Single-Page Applications (SPAs) built with React, Angular, or Vue, crawling requires executing JavaScript. Many DAST tools include a headless browser (Chromium) for this purpose — without it, they can’t discover endpoints rendered dynamically by client-side code.

The crawler builds a list of:

  • All discovered URLs and API endpoints
  • All input parameters (URL parameters, form fields, headers, JSON request bodies)
  • Authentication-required vs. publicly accessible endpoints
  • File upload forms and API endpoints

Phase 2: Active Scanning (Attack Phase)

The scanner systematically tests every discovered input parameter with attack payloads. For SQL injection, it sends payloads like ' OR '1'='1 and '; DROP TABLE users;-- and observes whether the response contains database errors, timing differences, or data that shouldn’t be accessible.

For each vulnerability class, the scanner uses different detection methods:

SQL injection detection:

  • Error-based: does the application return a database error when special characters are injected?
  • Boolean-based: does the application return different content when AND 1=1 vs. AND 1=2 is appended?
  • Time-based: does the application delay responding when ; WAITFOR DELAY '0:0:5'-- is injected?

XSS detection:

  • Sends reflection probes (<script>alert(1)</script>, "><img src=x>) and checks whether the payload appears unencoded in the response
  • Checks JavaScript contexts separately from HTML contexts

SSRF detection:

  • Sends URL parameters pointing to internal hosts (http://169.254.169.254/) and out-of-band callbacks (requests to an attacker-controlled domain) to detect server-side request execution

Security header checks:

  • Examines every response for missing or misconfigured headers (Content-Security-Policy, Strict-Transport-Security, X-Frame-Options, etc.)

Phase 3: Analysis and Reporting

The scanner correlates responses to identify confirmed vulnerabilities, assigns severity levels (Critical, High, Medium, Low), maps findings to CWE and OWASP categories, and generates a report with:

  • The exact request that triggered the finding
  • The response that confirms the vulnerability
  • A remediation recommendation
  • References to OWASP, CWE, and relevant secure coding guidelines

What DAST Scanning Detects

DAST scans are particularly effective at finding runtime vulnerabilities:

Injection Vulnerabilities

DAST detects injection vulnerabilities by observing the application’s response to crafted input. This includes:

  • SQL injection — DAST can detect error-based, boolean-based, and time-based SQLi by injecting payloads and analyzing response differences
  • Command injection — payloads like ; sleep 5 and | id are injected into parameters that may pass values to shell commands
  • LDAP injection, XPath injection, NoSQL injection — via dedicated payload sets for each injection type
  • Server-Side Template Injection (SSTI) — injecting template syntax ({{7*7}}, ${7*7}) and checking whether the application evaluates it

Cross-Site Scripting (XSS)

DAST scans check for:

  • Reflected XSS — input parameters that reflect user content back to the browser without encoding
  • Stored XSS — input that is stored (comments, profiles, messages) and later rendered to other users
  • DOM-based XSS — requires a browser-capable crawler that executes JavaScript; checks whether JavaScript sinks (innerHTML, eval()) receive attacker-controlled input

Broken Authentication

  • Session tokens that are predictable or too short
  • Login forms without brute force protection (rate limiting, account lockout)
  • Session tokens transmitted in URLs (visible in server logs and Referer headers)
  • Session tokens not rotated after login (session fixation vulnerability)
  • Logout functionality that doesn’t invalidate the server-side session
  • Multi-factor authentication bypass possibilities

Broken Access Control

  • Horizontal privilege escalation (IDOR) — accessing another user’s resource by modifying an object ID in a request parameter or API path
  • Vertical privilege escalation — accessing admin functions as a regular user by directly requesting privileged endpoints
  • Mass assignment — POST requests that modify fields not intended to be user-controllable (e.g., setting your own role=admin)

Security Misconfiguration

  • Missing HTTP security headers (Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy)
  • Verbose error messages that disclose stack traces, internal file paths, or database structure
  • Debug endpoints left enabled in production (/debug, /actuator/*, /.git/, /.env)
  • Directory listing enabled on the web server
  • TLS configuration issues (TLS 1.0/1.1 enabled, weak cipher suites, missing HSTS)

CORS Misconfiguration

DAST tools can detect:

  • Access-Control-Allow-Origin: * on authenticated endpoints
  • Reflected-origin CORS policies (any origin is allowed)
  • Access-Control-Allow-Credentials: true combined with wildcard or reflected origins

For a detailed explanation of CORS misconfiguration attack chains, see CORS Wildcard Risk.

Server-Side Request Forgery (SSRF)

DAST detectors send URL values pointing to internal hosts, cloud metadata endpoints (http://169.254.169.254/latest/meta-data/), and out-of-band callback URLs. If the server makes a request to the attacker-controlled domain, SSRF is confirmed.


What DAST Scanning Cannot Detect

Understanding DAST’s limitations is as important as knowing its strengths:

Hardcoded secrets — DAST has no access to source code. API keys, passwords, and tokens embedded in code are invisible to a running-application scanner. Use SAST for this.

Complex second-order injection — DAST can sometimes detect second-order SQL injection if it can trigger the trigger step, but it often misses the stored-then-triggered pattern because the injection and execution happen in different requests across sessions.

Business logic flaws — automated DAST tools struggle with application-specific logic. Workflow bypass (skipping step 2 in a 3-step process), price manipulation in e-commerce flows, and race conditions in financial operations require manual testing or sophisticated custom scripts.

Code-level vulnerabilities — insecure cryptographic algorithm choices, insecure deserialization patterns, and weak session token generation in code cannot be observed from HTTP responses alone.

This is why DAST and SAST are complementary: each catches what the other misses.


Authenticated vs. Unauthenticated DAST Scans

An unauthenticated DAST scan only tests the portion of your application accessible without logging in. For most applications, this is a small fraction of the total attack surface. Authenticated scanning is essential for finding the vulnerabilities that matter most.

Configuring Authentication for DAST

Form-Based Authentication (session cookies)

Most DAST tools support recording a login sequence (using a Selenium-style script or Burp Suite macro) that the scanner replays to obtain a session cookie before scanning:

# Example authentication configuration (Offensive360 DAST)
auth:
  type: form
  login_url: https://staging.example.com/login
  username_field: email
  password_field: password
  credentials:
    username: scanner@example.com
    password: ScannerPassword123!
  success_indicator: "Dashboard"  # String present in authenticated response
  logout_indicators:
    - "Sign in"
    - "Log out"

Token-Based Authentication (JWT / Bearer)

For REST APIs that use JWT or API key authentication:

# Bearer token authentication
auth:
  type: bearer_token
  token_url: https://api.example.com/auth/login
  token_request_body:
    email: scanner@example.com
    password: ScannerPassword123!
  token_path: $.data.token  # JSONPath to the token in the response
  header_name: Authorization
  header_prefix: "Bearer "

OAuth 2.0

For applications using OAuth 2.0, configure the scanner with client credentials and the authorization endpoint. Most enterprise DAST tools support OAuth 2.0 client credentials flow and authorization code flow with PKCE.

Session Maintenance

A DAST scan can take 1–4 hours for medium-size applications. During that time, session tokens may expire. Configure your scanner with:

  • Session renewal: re-authenticate when the session expires
  • Session detection: a URL pattern or response string that indicates the session is no longer valid
  • Logout detection: URLs that invalidate the session (avoid scanning /logout directly)

Setting Up DAST in CI/CD

Running DAST in your CI/CD pipeline gives you continuous security coverage — every deployment is automatically tested before it reaches production.

Code commit → SAST scan (blocks on Critical) → Build & deploy to staging
  → DAST scan against staging (blocks on Critical/High)
  → Deploy to production

DAST runs against the staging environment, not production, for two reasons:

  1. Active scanning (injecting payloads) can cause side effects in production (unwanted emails, database entries, rate limiting triggers)
  2. You want to catch vulnerabilities before they reach production

GitHub Actions Integration

name: DAST Security Scan

on:
  push:
    branches: [main, develop]

jobs:
  dast:
    runs-on: ubuntu-latest
    needs: deploy-staging  # Run after staging deployment completes

    steps:
      - name: Wait for staging deployment
        run: sleep 30  # Allow time for deployment to stabilize

      - name: Run DAST Scan
        env:
          O360_API_KEY: ${{ secrets.O360_API_KEY }}
          STAGING_URL: ${{ secrets.STAGING_URL }}
        run: |
          # Start DAST scan against staging environment
          SCAN_ID=$(curl -s -X POST https://api.offensive360.com/scan/dast \
            -H "X-API-Key: $O360_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "target": "'"$STAGING_URL"'",
              "auth": {
                "type": "form",
                "loginUrl": "'"$STAGING_URL"'/login",
                "username": "scanner@test.com",
                "password": "'"${{ secrets.DAST_SCAN_PASSWORD }}"'"
              },
              "scope": "'"$STAGING_URL"'/*"
            }' | jq -r '.scan_id')

          echo "SCAN_ID=$SCAN_ID" >> $GITHUB_ENV

      - name: Wait for scan completion
        run: |
          while true; do
            STATUS=$(curl -s \
              -H "X-API-Key: $O360_API_KEY" \
              "https://api.offensive360.com/scan/$SCAN_ID/status" | jq -r '.status')

            echo "Scan status: $STATUS"
            [ "$STATUS" = "completed" ] && break
            [ "$STATUS" = "failed" ] && exit 1
            sleep 30
          done

      - name: Check results and enforce policy
        run: |
          CRITICAL=$(curl -s \
            -H "X-API-Key: $O360_API_KEY" \
            "https://api.offensive360.com/scan/$SCAN_ID/summary" | jq '.critical')

          HIGH=$(curl -s \
            -H "X-API-Key: $O360_API_KEY" \
            "https://api.offensive360.com/scan/$SCAN_ID/summary" | jq '.high')

          echo "Critical: $CRITICAL, High: $HIGH"

          if [ "$CRITICAL" -gt "0" ]; then
            echo "❌ Deployment blocked: $CRITICAL critical vulnerabilities found"
            exit 1
          fi

          if [ "$HIGH" -gt "0" ]; then
            echo "⚠️ Warning: $HIGH high-severity vulnerabilities found"
            # Optionally block on High findings too
          fi

GitLab CI Integration

dast-scan:
  stage: test
  needs: [deploy-staging]
  image: alpine:latest

  variables:
    TARGET_URL: $STAGING_URL

  before_script:
    - apk add --no-cache curl jq

  script:
    - |
      SCAN_ID=$(curl -s -X POST https://api.offensive360.com/scan/dast \
        -H "X-API-Key: $O360_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{"target":"'"$TARGET_URL"'"}' | jq -r '.scan_id')

      # Poll until complete
      while true; do
        STATUS=$(curl -s -H "X-API-Key: $O360_API_KEY" \
          "https://api.offensive360.com/scan/$SCAN_ID/status" | jq -r '.status')
        [ "$STATUS" = "completed" ] && break
        sleep 30
      done

      # Fail on critical findings
      CRITICAL=$(curl -s -H "X-API-Key: $O360_API_KEY" \
        "https://api.offensive360.com/scan/$SCAN_ID/summary" | jq '.critical')

      [ "$CRITICAL" -gt "0" ] && exit 1 || exit 0

  only:
    - main
    - develop

Scoping a DAST Scan Correctly

Incorrect scope is the most common cause of poor DAST results.

Include

  • All application URLs within your domain
  • API endpoints under your control (same domain or known subdomains)
  • Authenticated areas (with valid session credentials)

Exclude

  • Third-party services (payment gateways, CDN assets, OAuth providers)
  • Logout and password-reset endpoints that would break the session
  • Bulk data export endpoints that would generate massive data
  • Notification endpoints that would send emails to real users
  • Administrative destructive actions (delete all users, wipe database)

Scope configuration example

scope:
  include:
    - "https://staging.example.com/*"
    - "https://api.staging.example.com/*"
  exclude:
    - "https://staging.example.com/logout"
    - "https://staging.example.com/admin/reset-all"
    - "https://staging.example.com/api/notifications/send"
    - "*.cloudfront.net"
    - "*.stripe.com"
    - "*.googleapis.com"

DAST Scan Performance Considerations

A full authenticated DAST scan of a medium-size application (50–200 endpoints) typically takes 1–4 hours. For faster CI/CD feedback, consider:

Tiered scanning:

  • PR/push scan (10–15 min): Scan only changed endpoints and critical high-risk paths (login, payment, admin)
  • Nightly full scan (1–4 hours): Complete scan of all authenticated endpoints with full payload sets
  • Release scan (2–6 hours): Exhaustive scan with all enabled plugins before major releases

Parallel scanning: If your staging environment can handle the load, configure the scanner to run multiple probe threads simultaneously. Most enterprise DAST tools allow configuring the number of concurrent requests.

Incremental scanning: Some tools track which endpoints changed between scans and only re-test those. This can dramatically reduce scan time for applications with stable core functionality and frequent changes to specific modules.


Benchmarking Your DAST Scanner

Before running a DAST scanner against your production environment, test it against a known-vulnerable application to validate it works:

  1. Run OWASP Juice Shop in Docker: docker run --rm -p 3000:3000 bkimminich/juice-shop
  2. Point your DAST scanner at http://localhost:3000/ with valid credentials
  3. Compare results against Juice Shop’s score board at http://localhost:3000/#/score-board
  4. Verify key detections: SQL injection in search, XSS in product reviews, broken access control on admin endpoints

A scanner that misses obvious SQL injection and XSS in Juice Shop’s well-known vulnerable endpoints will miss similar patterns in your real application.

For Java-stack teams, WebGoat is a better benchmark (docker run -it -p 8080:8080 webgoat/webgoat). See our guide to setting up vulnerable web applications for testing.


DAST vs. SAST: Which Do You Need?

The answer is both — they find fundamentally different vulnerability classes:

CapabilityDASTSAST
No source code required
Detects runtime misconfigurations
Detects hardcoded secrets
Integrates with development workflow⚠️ Staging only✅ Pre-commit, PR
Detects second-order SQLi⚠️ Sometimes✅ Full taint analysis
Detects missing security headers⚠️ Limited
Detects authentication flaws⚠️ Limited
False positive rateMediumLow (taint analysis)
Time to first resultHours (need running app)Minutes (scan from code)

For a detailed comparison, see DAST vs. Penetration Testing and SAST vs. DAST.


Common DAST Scanning Mistakes

Scanning without authentication. An unauthenticated scan only covers public-facing endpoints — typically 10–20% of a real application’s attack surface. Most critical vulnerabilities (IDOR, broken access control, SQL injection in protected API endpoints) require authentication to reach.

Including logout in the scan scope. If the scanner hits your logout endpoint, it invalidates its own session and the rest of the scan runs unauthenticated. Always exclude logout from the scan scope.

Scanning production directly. Active scanning generates abnormal traffic patterns and can cause side effects: triggering rate limiting, sending notifications, creating database records, or causing service instability. Always scan staging first.

Not verifying the scanner found the known vulnerabilities. Before trusting any scanner on your production application, verify it can find known vulnerabilities in a test application like Juice Shop or DVWA. A scanner that misses obvious SQL injection in a deliberately vulnerable application will miss similar patterns in production.

Treating all findings equally. Prioritize findings by severity and confirmability. A confirmed SQL injection (where the scanner demonstrated actual data extraction) is far more urgent than a “potential” open redirect with low confidence.


Frequently Asked Questions

How long does a DAST scan take?

A typical full authenticated DAST scan takes 1–4 hours for applications with 50–200 unique endpoints. Very large applications (1,000+ endpoints) can take 8–12 hours. Incremental scans focused on changed endpoints take 15–30 minutes. Scan time depends on the number of endpoints, the number of input parameters per endpoint, and the network latency to the target.

Can DAST scanning break my application?

Active DAST scanning injects malicious payloads into your application and is intentionally disruptive. It can trigger rate limiting, create unwanted database records, send unintended emails, and occasionally cause application errors. This is why you always scan staging, not production. Configure your scan to exclude destructive endpoints and sensitive notification paths.

What is the difference between DAST and a penetration test?

DAST is automated testing that systematically covers known vulnerability classes by injecting payloads and analyzing responses. A penetration test is manual testing by a skilled security researcher who can reason about application-specific logic, chain vulnerabilities together, and find novel attack paths. DAST provides breadth and consistency; penetration testing provides depth and creativity. See DAST vs. Penetration Testing for a full comparison.

Does DAST work on REST APIs and GraphQL?

Yes, with proper configuration. REST APIs require configuring authentication headers (Bearer token, API key) and providing an OpenAPI/Swagger specification so the scanner knows the expected input formats. GraphQL requires configuring the scanner to use the GraphQL introspection endpoint and to submit queries rather than URL parameters. Most enterprise DAST tools support both.

How often should I run DAST scans?

At minimum: on every deployment to staging (automated in CI/CD). For higher-risk applications: daily scheduled scans with overnight full-depth scans. For regulated environments (PCI-DSS, HIPAA): quarterly full authenticated scans with documented results for compliance evidence. The goal is to catch regressions before they reach production.


Getting Started with DAST

The fastest way to start DAST scanning:

  1. Benchmark your scanner — start with Juice Shop or DVWA to confirm the scanner actually works before running it on real applications
  2. Configure authentication — set up form-based or token-based authentication so the scanner can test protected endpoints
  3. Define scope carefully — include all application endpoints, exclude third-party services and destructive operations
  4. Integrate into staging deployment — trigger a DAST scan automatically after every staging deployment

Offensive360’s DAST scanner is included in the same platform as our SAST engine — no separate tool to purchase or integrate. It supports form-based, JWT, OAuth 2.0, API key, and custom script authentication, with native integrations for GitHub Actions, GitLab CI, Jenkins, and Azure DevOps.

Offensive360 DAST performs authenticated dynamic scanning for injection vulnerabilities, broken authentication, CORS misconfigurations, and 100+ other runtime vulnerability classes across web applications and REST APIs.

Offensive360 Security Research Team

Application Security Research

Find vulnerabilities before attackers do

Run Offensive360 SAST and DAST against your applications and get a full vulnerability report in minutes.