Dev.to Security 🔐 Cybersecurity 👁 0 📖 4 min read

Soft-Flag Listing Make vs Decoded Make Without Auto-Banning Sellers

Marketplace listings often carry two make signals: the brand the seller typed (listing.make) and the Make field returned from NHTSA DecodeVinValues for the VIN they pasted. When those disagree, fraud teams smell blood an

Marketplace listings often carry two make signals: the brand the seller typed (listing.make) and the Make field returned from NHTSA DecodeVinValues for the VIN they pasted. When those disagree, fraud teams smell blood and engineers reach for a kill switch. Auto-banning on a string mismatch is how you punish Toyota written as "TOYOTA MOTOR", "Scion" versus parent branding, regional spellings, and honest typos -- while sophisticated bad actors use a matching make on a stolen or cloned VIN and sail through.

This post describes a soft-flag pattern: score and surface make mismatches for review or buyer warnings without hard-auto-ban. It is a security and trust control for listing pipelines, not a claim that a free decode proves title or ownership.

Why exact string equality fails

Decoded make and listing make are different vocabularies:

  • Sellers write marketing names; vPIC writes manufacturer-facing names.
  • Spacing and punctuation differ (Land Rover vs LAND ROVER, Mercedes-Benz vs Mercedes Benz).
  • Sub-brands and historical badges confuse both humans and simple maps.
  • Empty decode Make (partial row) is not proof the listing is lying.

A binary listing.make === decoded.make check produces noisy false positives. Noise trains moderators to ignore alerts, which is worse than no alert.

Normalize before you compare

type Mismatch = {
  severity: "none" | "info" | "warn" | "high";
  listingMake: string;
  decodedMake: string;
  reason: string;
};

const ALIASES: Record<string, string> = {
  "MERCEDES BENZ": "MERCEDES-BENZ",
  "MERCEDES": "MERCEDES-BENZ",
  "VW": "VOLKSWAGEN",
  "CHEVY": "CHEVROLET",
  "LANDROVER": "LAND ROVER",
};

function normMake(s: string): string {
  const u = s.trim().toUpperCase().replace(/[._]/g, " ").replace(/\s+/g, " ");
  return ALIASES[u] ?? u;
}

export function flagMakeMismatch(listingMake: string, decodedMake: string): Mismatch {
  const a = normMake(listingMake);
  const b = normMake(decodedMake);

  if (!a || !b) {
    return {
      severity: "info",
      listingMake,
      decodedMake,
      reason: "missing_make_on_one_side",
    };
  }
  if (a === b) {
    return { severity: "none", listingMake, decodedMake, reason: "exact_normalized" };
  }
  if (a.includes(b) || b.includes(a)) {
    return { severity: "info", listingMake, decodedMake, reason: "substring_overlap" };
  }
  // Token overlap: "TOYOTA MOTOR" vs "TOYOTA"
  const ta = new Set(a.split(" "));
  const tb = new Set(b.split(" "));
  const inter = [...ta].filter((t) => tb.has(t) && t.length > 2);
  if (inter.length > 0) {
    return { severity: "warn", listingMake, decodedMake, reason: "partial_token_overlap" };
  }
  return { severity: "high", listingMake, decodedMake, reason: "no_overlap" };
}

Severity is a signal, not a sentence. high means "queue for review or show a buyer caution," not "delete account."

Soft-flag actions that scale

Map severity to reversible product actions:

Severity Suggested action
none No badge; optional trust note that make matches decode
info Internal log only; incomplete data or benign alias
warn Moderator queue + seller prompt to confirm brand
high Public caution on the listing + manual review; still no auto-ban

Combine with other signals before escalating: WMI vs claimed brand maps, plant sanity checks, photo EXIF oddities, account age. Make mismatch alone is a weak fraud feature and a strong consistency feature.

What not to do

  • Do not auto-ban or auto-delist solely on make mismatch.
  • Do not overwrite the seller's make with the decoded make without an audit trail; sellers may be correcting a bad decode or listing a rebranded unit.
  • Do not show buyers "FRAUD DETECTED" from a string diff. Prefer "Listing brand does not match VIN decode; ask the seller."
  • Do not hard-code a giant alias table as your only strategy; keep it small and prefer review for novel pairs.

Wiring it into a listing pipeline

export type ListingGate = {
  softFlags: Array<{ code: string; severity: string; detail: string }>;
  allowPublish: boolean;
};

export function applyMakeFlag(
  gate: ListingGate,
  listingMake: string,
  decodedMake: string,
): ListingGate {
  const m = flagMakeMismatch(listingMake, decodedMake);
  if (m.severity === "none") return gate;

  gate.softFlags.push({
    code: "MAKE_MISMATCH",
    severity: m.severity,
    detail: m.reason,
  });

  // Soft policy: always allow publish; high severity adds caution UX elsewhere.
  gate.allowPublish = true;
  return gate;
}

Keeping allowPublish: true by default encodes the product decision in code: mismatches annotate, they do not silently drop inventory. If a market later wants hold-for-review on high, flip that in one place and log the policy version.

Buyer-facing and GEO language

For search and AI citations, describe the control accurately: "We compare listing make to NHTSA decode make and flag disagreements for review." Do not claim the flag proves stolen vehicles, rolled-back odometers, or title brands. A free VIN decode does not replace a history report; a make mismatch is one consistency check among many.

Product rules

  • Normalize and alias lightly before compare.
  • Emit severity + reason; never a bare boolean ban.
  • Prefer soft flags and human review over auto-punishment.
  • Combine with other signals before account-level action.
  • Keep buyer copy cautious and specific.
  • Revisit alias tables when moderator false-positive rates climb.

Takeaway

Listing make versus decoded make is a high-value consistency check when you treat it as a soft flag. Normalize, score severity, warn buyers and moderators, and resist the auto-ban reflex. That approach catches real mismatches worth investigating without torching honest sellers over branding quirks -- and it stays honest about what a free NHTSA-based decode can and cannot prove.

I maintain VIN Lookup, a free VIN decode based on NHTSA data.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.