QWED
v7.2.2 GitHub 60

Type to search pages, engines and advisories.

    Looking for API details?Search the docs

    GHSA-mv2c-jwm9-pfrq

    Sanctions screening is bypassed by single-character perturbations inside sanctioned names

    Impact

    Sanctions screening in qwed-finance (sanctions_match / normalize_for_screening, used by CrossGuard.verify_swift_with_sanctions and UCPIntegration.verify_iso20022_payment) can be bypassed by changing a single character inside a sanctioned name. A payment to a sanctioned party passes screening when the name is perturbed in ways a human reader — or a payment operator — would still read as the same party.

    Reproduced on v3.0.0 with sanctions list ["EVIL CORP"] and the name in the MT103 :59: beneficiary field:

    Beneficiary name Result
    EVIL CORP blocked (control)
    EV-IL CORP passed
    E.V.I.L. CORP passed
    ÉVIL CORP passed
    EVıL CORP (dotless i) passed
    small-capital letters ᴇᴠɪʟ ᴄᴏʀᴘ passed

    Who is affected: applications that use qwed-finance sanctions screening on SWIFT MT or ISO 20022 messages generated by an LLM or another untrusted source. The npm SDK does not expose these code paths.

    Root cause

    normalize_for_screening maps every non-alphanumeric character to a space, so punctuation inside a word splits it into separate tokens (EV IL), which no longer contain the sanctioned token. Diacritics are not folded, and Latin look-alike letters that NFKC does not fold (small capitals, dotless i) are neither normalized nor flagged by the mixed-script check.

    Patches

    Fixed in qwed-finance 3.0.1 (release). Upgrade with pip install -U qwed-finance==3.0.1.

    normalize_for_screening now:

    • folds diacritics and stray combining marks (NFKD followed by mark removal);
    • maps Latin look-alike letters (small capitals, dotless i) and common Cyrillic/Greek homoglyphs to a Latin skeleton.

    sanctions_match additionally compares separator-free forms in the forward direction, so punctuation or spacing inserted inside a word no longer splits the sanctioned name. Address fragments remain forward-only. Transliterations and true aliases still require alias-structured list data.

    Workarounds

    • Additionally compare names with all non-alphanumeric characters removed (not replaced with spaces).
    • Fold diacritics (NFKD and drop combining marks) and apply a confusables skeleton (Unicode TR39) to both sides before matching, or route any name that changes under these folds to manual review.
    • Do not treat a passed sanctions result from affected versions as a sole control.

    References

    Reproduced on qwed-finance 3.0.0 (bb0cdf3).