# osint-brazuca-regex: Brazilian identifier patterns for triaging large data sets

> osint-brazuca-regex is a collection of regular expressions for the identifiers that are specific to Brazil, CPF, CNPJ, PIX, state tax numbers, voter registration, court process numbers, alongside a general set covering crypto wallets, IP addresses, API tokens and hashes. A scanner applies them to files, folders or standard input with no network access, and the README is careful to say that a match is a format, not a valid document.

**osintbrazuca/osint-brazuca-regex** — Repositório criado com intuito de reunir expressões regulares dentro do contexto Brasil

- Repository: https://github.com/osintbrazuca/osint-brazuca-regex
- Stars: 1,010 · Forks: 87
- Language: Python
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/osintbrazuca-osint-brazuca-regex

## Triage, not detection

The repository is described in Portuguese as a place to gather regular expressions focused on the Brazilian context and on general patterns, and the introduction states the purpose plainly: to help OSINT analysts and researchers filter and identify relevant information during large scale collection and analysis.

The problem it describes is a mundane one that anyone who has processed a leak knows. To find the relevant data you need a search key, which can be an interesting string or specific business documents, and frequently you end up writing context-specific regular expressions yourself or digging through internal documentation to find them.

So the value of the project is not detection. It is the collection of keys, maintained in a place other people can add to.

The scope is large and the structure is by domain. The index in the README covers tools, Brazilian documents, governmental identifiers, cryptocurrencies and wallets, network and infrastructure, credit cards, banking data, Tor and dark web, social networks and messaging, geolocation, vehicles, business and education, complementary documents, international finance, hashes and tokens, API credentials and secrets, databases and containers, private keys and certificates, sensitive patterns and internal URLs, and a final set of generic regexes.

The project is MIT licensed, the primary language is listed as Python, the last push was on 2026-08-26, and there are no GitHub releases, so the dataset is consumed straight from the repository.

## Two datasets, and four categories that live in both

The regexes are maintained in two files, split by context, and the README asks you to use whichever makes sense for your case.

The Brazilian file, osint-brazuca-regex-br.json, holds Brazilian identifiers with 43 categories and 134 regexes: CPF, CNPJ, PIX, the state tax number by state, bank accounts, the driving licence CNH, the voter registration title, court process numbers from CNJ and similar.

The general file, osint-brazuca-regex-geral.json, holds universal patterns with 24 categories and 212 regexes: crypto wallets, IPv4 and IPv6 addresses, domains, URLs, API tokens, hashes, social networks and the rest.

The interesting wrinkle is the note about four categories that exist in both files. creditCard, socialMedia, apiCredentials and vehicles are split, and the split follows the country rather than the domain. The Brazilian parts, which are Elo and Hipercard, WhatsApp with a Brazilian area code, Mercado Pago, Pagar.me, Asaas and the ANTT transport registry, sit in the Brazilian file, and everything else in those four categories sits in the general one.

That is a sensible design for a Brazilian team, because the file they load by default carries everything specific to them, and a team working internationally can load the general file and add the Brazilian parts when they need to.

The sizes are small enough to read, which is the point. 134 and 212 regexes is a working set, not a generated corpus, and a reviewer can look at the whole thing.

## Format is not validity, and the README says so twice

There is a caution block in the README that is the most important sentence in the document for anyone using this in a pipeline.

These expressions check the format, not the check digit. CPF, CNPJ, PIS, CNS, EAN-13 and boleto need the arithmetic check of the check digit on the side of whoever consumes them. A match here is not a valid document, and treating it as confirmed personal data leads to false positives.

That is a precise and useful warning, because the check digit is the whole point of those identifiers. A CPF is eleven digits where the last two are computed from the first nine, so a pattern that matches the shape will match plenty of sequences that were never issued. The same applies to CNPJ, to the PIS and the CNS health record number, and to EAN-13 product codes.

For a threat hunting team, the consequence is straightforward. A regex hit is a lead, and it is a cheap first filter, and the expensive verification step is the check digit arithmetic, which is trivial to implement and is not in this repository.

The same caution applies to the banking and personal categories more generally, where a pattern that matches the format of a number is not evidence that the number exists or belongs to the person whose data you are looking at.

## A scanner with no mandatory dependencies

The tool that comes with the repository is osint_regex_scan.py, described as a scanner that applies the dataset to files, folders or input via standard input. It requires Python 3.12 or newer and has no mandatory dependencies, with the full documentation in tool.md and the optional packages in requirements.txt.

The core having no external dependency is a deliberate design choice, and the requirements file explains it. The core has no external dependency because osint_regex_scan.py and dataset/build.py run on the Python 3.12 standard library alone. The packages listed are optional and only widen what the tool can do, and nothing breaks without them: the scanner keeps working, it just skips PDFs, with a warning about how to enable that, and it uses a simpler encoding detection.

Two commands from that file are worth knowing.

```bash
python3 osint_regex_scan.py --list-extractors
```

That shows what is active in the current environment, which is the fastest way to answer the question of why a PDF was skipped.

And the dataset itself is generated.

```bash
python3 dataset/build.py
```

That script produces the legacy combined file from the two split ones, which is worth explaining because the README describes the legacy file as deprecated while still shipping it.

## The legacy file is generated, and the new consumers should not use it

For a long time there was one file, osint-brazuca-regex.json, with all 346 regexes in it. The README explains that it remains available so that nobody consuming the raw URL is broken, and that it has become a generated artefact produced from the two context files with python3 dataset/build.py. It is deprecated, and new consumers should point at the split files instead.

That is a good migration pattern and it also tells you something about the tooling. The dataset is generated rather than hand-maintained, so the two split files are the source of truth, and the combined file is a compatibility shim with a build step behind it.

The other warning in the same part of the README is the one that matters most for adoption. There is no network. There are no queries, no verifiers and no interaction with external APIs, and all validation is done locally with regex and Python.

For an OSINT tool that is a real property rather than a limitation. A tool that silently validated a CPF against a government endpoint would create a legal problem and a privacy problem, and this one cannot. What you get is a set of patterns and a local scanner, and everything you do with the output is your decision.

The documentation mentions the project logo linking to nuclei, which suggests the intended workflow is to feed the patterns into a template scanner, and the JSON format makes that straightforward.

## Engine compatibility is where the patterns will bite you

The README has an important block about engine compatibility, and it is the detail most likely to cost you an afternoon.

Some expressions use the inline flag (?i) at the start of the pattern and others use lookaround, with the (?=, (?! and (?<! forms. The inline flag works in Python, PCRE and Go, but it is not accepted by the JavaScript RegExp, and in that case you remove the (?i) and pass the i flag when constructing the expression. Lookaround is not supported by RE2, which is the regex engine Go uses.

So the same dataset will not compile everywhere, and the failure mode is a pattern that throws or silently never matches. In JavaScript you get a syntax error on the first inline flag, which is at least loud. In Go, a lookaround pattern fails to compile as a regular expression and you get a different error depending on how it is used.

The practical advice is to treat the dataset as Python and PCRE material, which is where the majority of the tooling in this space lives, and to have a conversion step for anything else. The README tells you exactly what to change in the JavaScript case, and the Go case is a rewrite of the lookaround rather than a flag change, so it needs more thought.

The requirements file has the same flavour of detail, with the note that the legacy PyPDF2 is still accepted by the code but pypdf is the maintained successor, and the comment about pypdf preserving reading order better and being faster on large files, which is the kind of thing that matters when you are scanning a folder of statements.

## Conclusion

osint-brazuca-regex fits a threat hunting or OSINT team that has to triage large volumes of Brazilian data and keeps writing the same CPF and PIX patterns over and over, and who need the scan to run offline on a machine that must not talk to the network. It does not fit a team that needs to confirm a document is genuine, because the patterns deliberately stop at format, and it does not fit a JavaScript or Go pipeline without work, since the inline flags and lookarounds in the set are not portable. Verify three things before you wire the dataset into a pipeline: that your regex engine accepts the patterns as written, that you add the check digit arithmetic the patterns cannot do, and that you read the legacy file with suspicion, because it is a generated artefact that is deprecated while the two split files are the ones new consumers should use.

## FAQ

### What does the osint-brazuca-regex repository contain?

A collection of regular expressions for the Brazilian context and for general patterns, kept in two JSON files by context, plus a scanner, osint_regex_scan.py, that applies them to files, folders or standard input. The Brazilian file holds 43 categories and 134 regexes for identifiers like CPF, CNPJ, PIX, state tax numbers, CNH and voter registration, and the general file holds 24 categories and 212 regexes for crypto wallets, IP addresses, domains, URLs, API tokens and hashes.

### Does a regex match mean the document is valid?

No. The README is explicit that the expressions check the format and not the check digit, so CPF, CNPJ, PIS, CNS, EAN-13 and boleto need the arithmetic check of the verifier digit on the consumer's side. A match is not a valid document, and treating it as confirmed personal data leads to false positives.

### What are the requirements to run the osint-brazuca-regex scanner?

Python 3.12 or newer and no mandatory dependencies, because the scanner and the dataset build script run on the standard library alone. The optional packages widen what it can do: pypdf for PDF text extraction, with the pdftotext binary from poppler-utils preferred, and chardet for encoding detection, with a latin-1 fallback that can swap accents. Run python3 osint_regex_scan.py --list-extractors to see what is active.

### Can I use the regexes in JavaScript or Go?

Not unchanged. Some patterns use the inline (?i) flag and others use lookaround. The inline flag works in Python, PCRE and Go but not in the JavaScript RegExp, where you remove it and pass the i flag instead, and lookaround is not supported by RE2, which is what Go uses.

### What is the legacy osint-brazuca-regex.json file?

The old combined file with all 346 regexes. It is still published so that existing consumers of the raw URL keep working, but it is now a generated artefact built from the two split files with python3 dataset/build.py and is deprecated, so new consumers should point at the Brazilian and general files instead.

## Sources

- [Issues](https://github.com/osintbrazuca/osint-brazuca-regex/issues)
- [License: MIT](https://github.com/osintbrazuca/osint-brazuca-regex/blob/main/LICENSE)
- [osintbrazuca/osint-brazuca-regex on GitHub](https://github.com/osintbrazuca/osint-brazuca-regex)
- [README](https://github.com/osintbrazuca/osint-brazuca-regex/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/osintbrazuca-osint-brazuca-regex
