Coverage area · 2 checks
Code flaws that make phishing work
Phishing targets people, but it leans on flaws in software: a trusted domain that redirects anywhere, an account email that changes without confirmation, a notification email users can fill with their own content. OpenRouting finds those in your code.
Illustrative example of how a finding in this area is reviewed.
Why this area matters
Phishing and credential theft remain among the most common initial access vectors in breach reports. A phishing link that starts on your real domain, then bounces to an attacker's page through an open redirect (CWE-601), is far more convincing than a look-alike domain. Account-recovery and email-change flows without re-verification turn a stolen session into a permanently taken-over account.
These are logic issues scanners only partly see. Semgrep can flag a redirect built from a query parameter; deciding whether it is restricted to local paths, or whether an email change is confirmed, needs someone to read the flow.
What goes wrong in real applications
Open redirects
Redirecting to a URL taken from the request lets phishing links start on your trusted domain and land on someone else's.
Unverified account changes
Changing email, phone or MFA settings without re-authentication or confirmation to the old address lets a briefly stolen session become a permanent takeover.
User-controlled email content
Letting users set the sender name, reply-to or HTML of invitation and notification emails turns your mail system into a phishing relay with your reputation.
Spoofable sender domains
Mail DNS records defined in IaC without SPF, DKIM and an enforcing DMARC policy make it easy to send mail that appears to come from you.
Sample: the risky pattern and the fix
@app.get("/login/continue")
def continue_after_login():
return redirect(request.args.get("next", "/"))
@app.post("/account/email")
@login_required
def change_email():
current_user.email = request.form["email"]
db.save(current_user)
return redirect("/account")@app.get("/login/continue")
def continue_after_login():
target = request.args.get("next", "/")
if not target.startswith("/") or target.startswith("//"):
target = "/" # local paths only
return redirect(target)
@app.post("/account/email")
@login_required
@require_recent_password
def change_email():
send_change_confirmation(current_user, request.form["email"])
notify_previous_address(current_user)
return redirect("/account?email_pending=1")The redirect sends users to any URL in the next parameter, so a link on your domain can end on a phishing page; the email change takes effect immediately with no re-authentication. The fix only allows local paths, requires a recent password, confirms the new address and alerts the old one before anything changes.
Illustrative code, simplified for clarity — not taken from a customer repository.
What OpenRouting checks in your repository
- Redirects and links built from request parameters
- Email, phone, password-reset and MFA flows: re-authentication, confirmation, notification to the old contact
- Transactional email templates that include user-controlled sender names, reply-to or HTML
- SPF, DKIM and DMARC records defined in Terraform or other IaC
Scope and limits
- It doesn't run phishing simulations, train staff or contact anyone — it reviews the code and config attackers would lean on.
- Live DNS records and mail-provider settings outside the repository aren't checked; only records defined in your IaC are.
- Open-redirect and account-flow findings are reviewed by the general and authentication reviewers; there is no dedicated phishing agent.
Coverage areas reflect OpenRouting's check library. Code, secret and infrastructure scanning run today; other areas are rolling out. Scanners surface candidates and a review agent decides whether each one is real — it doesn't promise to find every issue.
Review agents for this area
- Authentication & JWT — Checks that identity, tokens and sessions are actually verified and hardened.
- Access control & authorization — Checks that each sensitive action is authorized for the specific object, not just a logged-in user.
- Cross-site scripting (XSS) — Checks whether untrusted data is rendered into HTML or JavaScript without contextual encoding.
Common questions
Does OpenRouting test my employees?
No. It never targets people. It covers the software side of phishing: the flaws in your product that make a phishing attempt more convincing or more damaging.
Is every redirect with a parameter a finding?
No. Redirects restricted to local paths or an allow-list of hosts are marked as likely false positives, with the reason.