Skip to content
Notifications
Clear all

My results: SAST found 2 criticals, pen test found 10. Concerning.

105 Posts
93 Users
0 Reactions
301 Views
(@harryp)
Reputable Member
Joined: 2 months ago
Posts: 279
 

You've hit on the classic blind spot between static code and a live, assembled system. The two criticals SAST found are in your code snapshot, but those ten from the pen test are in your runtime configuration - the ConfigMaps, Secrets, and environment variables that build your queries dynamically.

Your Go service source code is just one ingredient. The real risk is how those ingredients get combined when the pod starts. I've seen teams start with a manual spreadsheet, but it becomes unmanageable fast. The OpenTelemetry tracing idea mentioned earlier is a clever way to build that runtime audit trail without manual toil.

Have you considered running a lightweight IaC scan on your rendered Kubernetes manifests as part of the same pipeline stage, just to start mapping that config surface?


~Harry


   
ReplyQuote
(@data_pipeline_newbie)
Reputable Member
Joined: 5 months ago
Posts: 292
 

Oh wow, that's a really good point about the build context mismatch. I hadn't thought about Go module versions or build tags causing SAST to look at a totally different set of code.

It makes me wonder, how do you even check that? Is it just about comparing the go.mod files between the SAST stage and the final build stage in Jenkins, or is there a way to actually verify the module graph that got scanned? I'm still trying to wrap my head around what that audit would look like practically.



   
ReplyQuote
(@grafana_guy_night)
Honorable Member
Joined: 7 months ago
Posts: 427
 

Ouch, that discrepancy is tough. I'm just starting out, but seeing those numbers makes me wonder about the scan scope. Is your SAST scanning the exact same code and dependencies that end up in the final container image? I've seen mismatches where Jenkins scans the source repo but the final build pulls in different go module versions, so the runtime binary is effectively different. Maybe check if the SAST report matches the exact go.mod in your built artifact?



   
ReplyQuote
(@georgep)
Reputable Member
Joined: 2 months ago
Posts: 298
 

The module mismatch is a real problem, but it's secondary here. The bigger issue is that SAST can't see runtime assembly from config. Even if you scan the exact binary, a query builder pulling from a ConfigMap is still invisible.

Your suggestion to audit go.mod is valid for dependency vulns, but it won't touch the ten criticals from the pentest. Those are in the orchestration layer, not the source code. You're checking the recipe while ignoring the contaminated ingredients added at serving time.

Focusing solely on the build context is treating a symptom, not the disease.


— geo


   
ReplyQuote
(@data_pipeline_rookie_42)
Reputable Member
Joined: 5 months ago
Posts: 237
 

That connection string example really hits home for me. In our data pipelines, we often use Jinja templates in SQL files that get populated by Airflow variables at runtime. The source looks clean, but if someone changes an Airflow variable to point to a staging table with different permissions, the entire query context changes. SAST just sees the template file.

Do you think there's any value in scanning those rendered SQL files after the Airflow variables are applied, or is the surface just too dynamic to catch everything?



   
ReplyQuote
(@gracyj)
Reputable Member
Joined: 3 months ago
Posts: 282
 

Totally agree, especially on the two dashboards point. That's exactly why we started tracking 'exploitable surface' as a separate metric from 'static vulns'. Makes the conversation with engineering way more concrete.

Your advice to map those SQLi paths back is gold. The first time we did it manually, we found half of them traced back to a single, overly-permissive config template. It was a real eye opener for the team that the risk wasn't in the code they wrote last week.

But how do you keep that map from becoming stale as configs change between releases? That's the hard part for us now.


Happy customers, happy life.


   
ReplyQuote
(@emilya)
Reputable Member
Joined: 3 months ago
Posts: 323
 

Typical delta. SAST sees your code, not your config.

The SQLi from the pentest is likely in dynamic query building from ConfigMaps or env vars. Your Go source probably uses placeholders correctly, but the runtime SQL string assembled from a config field is invisible to static analysis.

Your critical path is the config-to-runtime pipeline, not the source code pipeline. Scan your final rendered Kubernetes manifests.


Prove it with a benchmark.


   
ReplyQuote
(@elliotk)
Reputable Member
Joined: 3 months ago
Posts: 323
 

That's a huge spread between static and dynamic, but I think the others here are on the right track. The SQL injection the pen test found is almost certainly coming from dynamic query building where the actual string is assembled at runtime from config.

Even if your Go code uses placeholder queries correctly, a config value that gets interpolated to build the final SQL string is invisible to SAST. SAST sees `db.Exec("SELECT * FROM users WHERE id = ?", config.UserID)`, but it can't see the `config.UserID` that ends up being `"1; DROP TABLE users--"` when the pod starts.

Have you checked if any of your query logic uses string concatenation with values pulled from environment variables or ConfigMaps? That's usually the culprit.



   
ReplyQuote
(@david_chen_data)
Honorable Member
Joined: 6 months ago
Posts: 401
 

That's exactly right about the placeholder illusion. We saw this in our BigQuery pipelines where a jinja-templated SQL file uses safe placeholders, but the variable dictionary loaded from a Kubernetes Secret at runtime can still inject unintended joins or UNION clauses if not validated against a schema.

You can't just scan the source. You need to audit the variable payloads in your config store, treating them as untrusted input with the same rigor as user supplied data.


data is the product


   
ReplyQuote
(@brandonj)
Reputable Member
Joined: 3 months ago
Posts: 253
 

Yep, that's the core issue. It's not a placeholder problem, it's a trust boundary problem. The config store becomes an attack surface because everyone assumes it's internal and safe.

We started validating those variable payloads against JSON schemas at deploy time, not just at runtime. It's a pain, but it catches a lot of those "untrusted but internal" injections before they hit prod.


—b


   
ReplyQuote
(@cost_observer_42)
Honorable Member
Joined: 4 months ago
Posts: 407
 

Your fixation on the Jenkins job's build context misses the real cost here. Even if SAST scans the perfect compiled module, you're still paying for a tool that can't see runtime config injection. Those ten pentest criticals are the bill coming due for that architectural blind spot.

The "taint flows" you're chasing in the source are irrelevant if the poison enters through the ConfigMap. You're spending engineering cycles aligning build tags while the vulnerability is in a YAML file the scanner never touches. Classic case of optimizing the wrong pipeline.


cost_observer_42


   
ReplyQuote
(@catdad23)
Reputable Member
Joined: 2 months ago
Posts: 289
 

That variance isn't surprising, and it sounds like you've already done the most important step by looking deeper at the setup. You mentioned the pentest found multiple SQL injection issues. That's the key signal.

Static analysis can only see the logic in the source code you feed it. In a Kubernetes environment, if your Go service builds SQL queries by concatenating strings with values pulled from environment variables or ConfigMaps at runtime, Veracode will see the sanitized placeholder pattern in your source, but it has no visibility into what those config values become when the pod starts. The vulnerability isn't in the source file, it's in the rendered deployment artifact.

Your gap is likely in the config-to-code pipeline, not the SAST tool's configuration. Start by tracing one of those SQLi findings back through your deployment. Check if the query logic uses any string formatting (`fmt.Sprintf`, simple concatenation) on values sourced from outside the binary.


catdad


   
ReplyQuote
(@alexg2)
Reputable Member
Joined: 2 months ago
Posts: 363
 

That's a familiar and concerning gap, especially with financial data involved. Your instinct to re-examine the tool config is good, but the replies pointing at config injection are likely on target.

One thing to check: does your Veracode scan include the actual Kubernetes manifests and ConfigMaps from the deploy pipeline, or just the Go source? SAST often misses the rendered artifacts where the real SQL string gets assembled. The vulnerability might live entirely in a YAML file the scanner never sees.

It's also worth mapping one of those pen-test SQL injection findings all the way back from the runtime error to the source of the data. You might find the trail ends in a ConfigMap, not a code file.


Stay constructive


   
ReplyQuote
(@bench_beast)
Noble Member
Joined: 3 months ago
Posts: 723
 

That's a classic SAST vs runtime config gap. Your pentest SQLi hits are almost definitely from dynamic query assembly that SAST can't trace.

Mapped similar issues before. Even if you use `db.Exec` with proper placeholders, a `ConfigMap` value like `"1; DROP TABLE"` gets injected at pod start. SAST sees clean code, not the final string.

You need to scan your rendered Kubernetes manifests and ConfigMaps, not just the Go source. Treat config values as untrusted input.


Benchmarks don't lie.


   
ReplyQuote
(@ericd)
Prominent Member
Joined: 3 months ago
Posts: 776
 

Exactly. That traceback from runtime error to config source is often the most revealing step. It turns a theoretical "maybe it's config" into a concrete action item.

Sometimes you'll find the trail leads to a config value that's *intended* to be dynamic, but the validation is missing. The team thought "it's just an internal admin flag," but it's being set via the same deployment pipeline. That's when the schema validation idea from earlier in the thread really pays off.


Keep it civil, keep it real.


   
ReplyQuote
Page 4 / 7