Skip to content

CWE-115: Misinterpretation of Input

Overview

This guidance helps you interpret and remediate findings from DAST (Dynamic Application Security Testing) tools. The scanner detected that the application processed input through multiple parsing/decoding stages without consistent normalization, allowing attackers to bypass security controls by exploiting differences in how components interpret the same data. DAST tools identify this by:

Detection Methods:

  • Double Encoding: Submitting double-encoded payloads that bypass validation:
    • %252e%252e%252f → first decode: %2e%2e%2f → second decode: ../
    • %253Cscript%253E → first decode: %3Cscript%3E → second decode: <script>
  • Charset Confusion: Testing multiple character encodings (UTF-7, UTF-8, ISO-8859-1) to bypass filters:
    • UTF-7 XSS: +ADw-script+AD4-alert(1)+ADw-/script+AD4- interpreted as <script>alert(1)</script>
    • Overlong UTF-8: %C0%AE%C0%AE%C0%AF decoded as ../
  • Parser Differentials: Exploiting differences between validation logic and execution logic:
    • URL parsed differently by framework vs. backend (path normalization inconsistencies)
    • XML/JSON parsing differences between validation library and processing library
  • Canonicalization Bypasses: Testing path normalization inconsistencies:
    • /.///./etc/passwd/etc/passwd
    • /images/../../../etc/passwd if .. handled differently at each stage
  • Unicode Normalization: Submitting Unicode variations (NFKC, NFKD) that normalize to dangerous characters

HTTP Evidence:

  • Successful attacks after double-encoding where single-encoded payload was blocked
  • Different application behavior for semantically equivalent inputs (e.g., /etc/passwd vs. /etc////passwd)
  • Error messages revealing multi-stage processing ("Invalid input after decoding", "URL normalization failed")
  • Bypasses visible in logs showing different representations at different processing stages
  • Successful path traversal with %252e%252e%252f while ../ and %2e%2e%2f are blocked
  • XSS execution via UTF-7 when UTF-8 payloads are filtered

Scanner Behavior: OWASP ZAP and PortSwigger Burp test encoding variations systematically, submitting payloads in multiple character sets and encoding levels. They test canonical equivalence bypasses (e.g., /.// vs. /) and analyze whether validation and execution stages handle input consistently. Detection relies on observing different security outcomes for semantically equivalent inputs.

Analyzing the Dynamic Scan Result

What the DAST Scanner Found

When reviewing your security scan results, you'll see:

HTTP Request Details

  • URL and endpoint that triggered the finding
  • HTTP method (GET, POST, etc.)
  • Query parameters or form data with test payloads
  • Request headers and body content

HTTP Response Evidence

  • Response showing the vulnerability manifestation
  • Evidence of improper handling or injection
  • Runtime behavior indicators

Attack Vector

  • Which parameter or input is vulnerable
  • Type of exploitation possible
  • Context where the vulnerability appears

Example:

  • %252e%252e%252f decoded twice becomes ../
  • Input validated before decoding but used after decoding

Mapping DAST Findings to Source Code

Find the Vulnerable Endpoint

Use the HTTP request URL to locate the code:

# Search for the URL path in your codebase
grep -r "/api/endpoint" src/
grep -r "route.*endpoint" src/

Locate the Route Handler

Common patterns to search for:

  • Python Flask/Django: @app.route('/api/endpoint'), path('endpoint/', ...)
  • Node.js Express: app.get('/api/endpoint', ...), router.get('/api/endpoint', ...)
  • Java Spring: @GetMapping("/api/endpoint"), @RequestMapping("/api/endpoint")
  • ASP.NET: [Route("endpoint")], MapRoute("endpoint", ...)
  • PHP: $_GET['param'], route definitions in routing files

Find the Parameter Handling

Search for the vulnerable parameter name:

# Find where the parameter is accessed
grep -r "request.args.get('param')" src/     # Python Flask
grep -r "req.query.param" src/               # Node.js
grep -r "@RequestParam.*param" src/          # Java Spring
grep -r "Request.QueryString['param']" src/  # ASP.NET
grep -r "$_GET['param']" src/                # PHP

Trace to Vulnerable Operation

Look for where the parameter is used in:

  • Sensitive operations (database queries, commands, file access)
  • Output rendering or response construction
  • Authentication or authorization checks

Remediation

Core principle: Normalize and canonicalize all untrusted input once, consistently, and before validation or use, so it cannot be interpreted differently by different components or processing stages.

  • Decode input before validation (never after)
  • Enforce a single canonical encoding (e.g., UTF-8)
  • Avoid validating one representation and using another
  • Ensure proxies, frameworks, and app code use the same decoding rules

Verification and Follow-Up Testing

After applying the fix:

Reproduce the Vulnerability

# Use curl to replay the exact request
curl "http://localhost:3000/api/endpoint?param=value"

# Or use browser DevTools Network tab to copy as cURL

Re-run DAST Scanner

Run your dynamic scanner again on the fixed endpoint to confirm remediation.

Additional Resources