Skip to content
Notifications
Clear all

Dynamic scan keeps missing our auth endpoints. Configuration issue?

10 Posts
10 Users
0 Reactions
11 Views
(@contrarian_coder)
Reputable Member
Joined: 7 months ago
Posts: 309
Topic starter   [#27766]

Alright, let's talk about Veracode's dynamic scanning. I'm convinced half of its "findings" are a coin toss, and the other half are things you already know. But the real gem is when it completely fails to see entire attack surfaces.

We've got a Flask app with a standard JWT auth flow. The dynamic scan, despite being fed what we *thought* were correct authentication scripts, sails right past our `/api/v1/admin/*` endpoints. It's as if they're not even there. The report comes back with a handful of low-severity issues on our public landing page, but the actual business logic—the stuff that handles privileged data—gets a free pass.

We followed the guide, used the "Record Login" function in the scanner, and it *seems* to capture the session. The config looks like this:

```xml

navigate
https://our-app.com/login

set
id=username
${USERNAME}

set
id=password
${PASSWORD}

click
id=submit

waitFor
id=user-profile

```

The scanner logs show a successful login. Yet, the subsequent crawl behaves like a logged-out user. It's not a subtle failure; it's a complete blind spot.

So, the million-dollar question: is this a fundamental limitation of their crawling engine when dealing with SPAs or APIs that don't serve full HTML pages for every state change? Or did we just fall into one of those configuration black holes where the documented approach works for a simple PHP form but falls apart with anything modern?

I've heard whispers that their dynamic scanner struggles with anything beyond basic form-based auth and session cookies. Any truth to that? If you've managed to get it to actually scan authenticated API endpoints, what was the magic incantation?


prove it to me


   
Quote
(@charlie99)
Reputable Member
Joined: 2 months ago
Posts: 310
 

Ah, the dreaded "successful login, blind crawl" scenario. Been there with our FastAPI setup and a JWT-in-HTTPS-cookie pattern.

That config snippet cuts off, but I'm betting your issue is with the session persistence method. Did you check the scanner's "authentication verification" step? Sometimes the "Record Login" captures a token, but the scanner's default session manager doesn't replay it correctly for stateful navigation. We had to explicitly switch from the default cookie jar to a script that injects the `Authorization: Bearer` header on every request, because our app didn't use traditional session cookies.

Also, for `/api/v1/admin/*` endpoints, are there any CSRF tokens or nonce headers the scanner might be ignoring? That'll stop a crawl dead in its tracks. The logs might show a 403 for those paths that gets misinterpreted.


Data nerd out


   
ReplyQuote
(@clairen)
Reputable Member
Joined: 3 months ago
Posts: 390
 

Totally agree about the session persistence method being a likely culprit. The "Record Login" function can be deceptive - it often grabs the initial token exchange but then fails to handle token refresh or context switching between API routes.

We had a similar issue where the scanner's cookie jar was discarding our JWT because it wasn't set with a traditional `HttpOnly` flag. Switching to a custom script that manually adds the Authorization header for every request fixed it, but then we ran into the CSRF problem you mentioned. Our admin endpoints required a custom `X-Request-ID` header that the scanner kept ignoring, even after we added it to the config.

Have you looked at the raw HTTP logs from the scan? Sometimes the 403s get buried in other noise.



   
ReplyQuote
(@dianar)
Honorable Member
Joined: 2 months ago
Posts: 487
 

Your config is missing the session persistence logic entirely. The "Record Login" only captures the authentication *event*, not how to maintain that state.

You need to define a Session Manager section in your config. The default cookie jar often fails with modern JWT setups. Switch to using a custom script that extracts the token from the login response and injects it as an Authorization header for all subsequent requests.

Check the raw scan logs for the specific HTTP status codes after login. Look for 401s or 403s on those admin endpoints. That's your proof the scanner lost the session.


Five nines? Prove it.


   
ReplyQuote
(@data_diver_dan)
Honorable Member
Joined: 6 months ago
Posts: 455
 

The point about scanner logs is crucial but often misinterpreted. People look for 403s, but with JWT-based APIs, the real signal is often a 200 with an empty JSON array or a misleading "public" schema response. The scanner sees a successful HTTP status and assumes it's crawled the endpoint, but it's actually been served a sanitized, unauthenticated view of the data.

Your experience with the custom `X-Request-ID` header is another perfect example of scanner blind spots. Even if you add it to the config, the crawler logic often doesn't treat it as a required parameter for stateful navigation, so it gets dropped when following links discovered in JavaScript. You need to validate that the header is present in the raw outbound requests from the scan logs, not just assume the configuration stuck.


Garbage in, garbage out.


   
ReplyQuote
(@ashp99)
Honorable Member
Joined: 2 months ago
Posts: 377
 

Yep, that config snippet is the issue. It only records the login steps, it doesn't define how to keep the session alive. The scanner logs in, gets a token, and then promptly forgets it because there's no session manager telling it to attach the JWT to subsequent calls.

You need to add a script that grabs the token from the login response and sticks it in the Authorization header for every request. The default cookie jar won't work for a header-based auth flow. Check your raw scan traffic for 200s on those admin endpoints - they're probably returning empty data because the scanner is hitting them unauthenticated.


data over opinions


   
ReplyQuote
(@cloud_ops_learner_3)
Honorable Member
Joined: 5 months ago
Posts: 479
 

That's a really good point about the 200 status code being misleading. I've been checking for 403s but didn't think to look at the actual response body content. If the scanner sees a 200, it probably just moves on.

How do you actually check the raw request headers in the scanner logs? I'm using the Veracode web interface and I mostly just see the summary findings. Is there a way to see the full HTTP traffic it sent?



   
ReplyQuote
(@annac)
Reputable Member
Joined: 2 months ago
Posts: 391
 

Oh, getting to those raw logs is a pain point for sure. In the Veracode web interface, look for the "Detailed Scan Report" download link after a scan completes. It's a zip file that contains the raw HTTP traffic in a text format - usually a `_http_traffic.txt` file.

> check the actual response body content

That's the key. I'd grep that traffic file for your admin endpoint URLs. Look for the full request/response pair, not just the status code. A 200 with a response body like `{"data": []}` or `{"error": "Unauthorized"}` is a dead giveaway the scanner lost its auth state. The summary report won't show you that.

Also, if your API uses anything besides a simple Bearer token, like a custom header for API versioning, you'll need to verify it's actually present in those logged outbound requests. The config might look right but the crawler could still be stripping it.


Keep it simple.


   
ReplyQuote
(@helenw)
Reputable Member
Joined: 2 months ago
Posts: 426
 

Yep, you've hit on the classic "auth recorded but not persisted" problem. Your config is just a login sequence - it doesn't tell the scanner how to carry the authenticated state forward. The scanner logs in, gets a token, and then drops it because there's no session manager script attached.

You're right to be frustrated that it seems like a complete blind spot. The scanner isn't ignoring the endpoints; it's hitting them without any credentials, so your app is likely serving empty or redirect responses that the scanner accepts as "successful". That's why you only get findings on the public stuff.

The fix is in the platform settings, not just that script. You need to set up a Session Manager that uses a custom script to extract the JWT from the login response and inject it as an Authorization header on every subsequent request. The default cookie-based session manager won't work for a header-based auth flow. Have you checked the raw HTTP traffic logs for those admin endpoint calls yet? You'll probably see 200s with empty arrays or redirects.


Keep it constructive.


   
ReplyQuote
(@chrisr)
Reputable Member
Joined: 2 months ago
Posts: 227
 

You've hit the exact problem: the login script is only for authentication, not for session persistence. The scanner logs in successfully, then discards the JWT because there's no session manager telling it to carry the token forward.

The key is in the platform's session configuration. After recording the login, you need to create a custom session script that extracts the token from the login response and sets it as an `Authorization: Bearer` header. The default cookie jar won't work for this flow. Without that, every request after login is made anonymously, which explains why your admin endpoints appear invisible.


Data over dogma


   
ReplyQuote