SAST false positives
Fewer noisy warnings starts with following the data.
A scanner should not make developers chase every risky-looking string. The useful question is simpler: can untrusted data reach a dangerous operation without a safe stop on the way?
What a false positive feels like
A SAST false positive is a warning for code that looks unsafe but is not actually exploitable in that context. It wastes review time and trains developers to ignore the scanner.
The most common cause is missing context. A pattern rule may see a SQL call, a command call, or a template render, but miss whether the value came from a user, passed through a sanitizer, or was safely parameterized.
Unsafe flow: warn loudly
Here, request input moves into a SQL string before execution:
from flask import request
def find_user():
email = request.args["email"]
sql = "SELECT id FROM users WHERE email = '" + email + "'"
return db.execute(sql)
The source is request.args["email"]. The sink is db.execute. There is no
parameterization between them. That is the kind of path a scanner should flag.
Safe path: stay quiet
The safer version keeps SQL structure and user data separate:
from flask import request
def find_user():
email = request.args["email"]
sql = "SELECT id FROM users WHERE email = %s"
return db.execute(sql, (email,))
The value is still user-controlled, but the driver receives it as data, not SQL syntax. A scanner with data-flow and sanitizer context has a better reason to stay quiet here.
Good SAST is not louder. Good SAST gives developers a better reason to trust the warning.
How SiteShadow uses context
SiteShadow combines security rules with taint tracking. It follows input from sources, through helper functions and string operations, toward sensitive sinks such as SQL execution, command execution, template output, redirects, and file paths.
It also recognizes approved sanitizer patterns already used in public SiteShadow copy, including
parameterized queries, parseInt(), shlex.quote(), and
DOMPurify.sanitize(). That does not make every path safe. It gives the scanner more
context before it interrupts a developer.
What to check before trusting any SAST result
- Where did the value come from?
- Can a user control it?
- Did it pass through a sanitizer that is valid for this sink?
- Does it reach SQL, shell, HTML, redirect, file, or model-instruction behavior?
- Does the scanner show the path, or only a suspicious line?
Keep the story concrete
SiteShadow does not need bigger claims here. The story is enough: when a scanner follows the path from source to sink, developers get fewer empty alarms and clearer real risks.