Two enrichers return an empty result instead of failing loudly, so the task is reported as succeeded and nothing shows up in the graph.
1. domain_to_dns — dnsx no longer accepts a bare -d
DnsxTool.resolve_domain() builds:
dnsx -d <domain> -a -aaaa -json -silent
Since dnsx 1.2, -d means "bruteforce this domain" and requires a wordlist:
$ docker run --rm projectdiscovery/dnsx -d example.com -a -aaaa -json -silent
[FTL] missing wordlist(w) flag required with domain(d) input
$ echo $?
0
The exit code is 0, so nothing raises — the enricher just returns [] and Celery logs succeeded. From the UI it looks like the domain simply has no DNS records.
Fix: feed the single target on stdin, which is the supported single-target invocation:
sh -c "echo <domain> | dnsx -a -aaaa -json -silent"
DockerTool.launch() gains an optional entrypoint argument so a shell can be placed in front of the image entrypoint. The domain is passed through shlex.quote().
Verified against projectdiscovery/dnsx:latest (v1.2.2):
resolve_domain("<a test domain>") -> ['13.227.138.65', '13.227.138.39', '13.227.138.34', '13.227.138.124']
2. ip_to_fraudscore — Scamalytics API host is per-account
Scamalytics provisions each account on a numbered API node and hands out the full base URL at signup. An account on a different node gets a plain 404 from api12, with the same silent-empty-result outcome. On a live v3 account provisioned on api11:
host
result
the account's own node
200 + full JSON
api12
404 Not Found
Fix: read the host from a SCAMLYTICS_API_HOST secret / env var, defaulting to api12 so existing deployments are unchanged.
Notes
No behaviour change for anyone already working: the Scamalytics default is preserved, and the dnsx change only alters how the single target is passed.
Happy to split this into two PRs, add tests, or make the dnsx change use a different mechanism if you prefer — just say the word.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/reconurge/flowsint/pull/200
**Author:** [@Topman3579](https://github.com/Topman3579)
**Created:** 7/27/2026
**Status:** ✅ Merged
**Merged:** 7/28/2026
**Merged by:** [@dextmorgn](https://github.com/dextmorgn)
**Base:** `main` ← **Head:** `fix/dnsx-stdin-and-scamalytics-host`
---
### 📝 Commits (1)
- [`ebda0f4`](https://github.com/reconurge/flowsint/commit/ebda0f4c4981cf437ee0da5d597ec4bd19a96ba2) fix(enrichers): dnsx stdin input + configurable Scamalytics API host
### 📊 Changes
**3 files changed** (+23 additions, -7 deletions)
<details>
<summary>View changed files</summary>
📝 `flowsint-enrichers/src/flowsint_enrichers/ip/to_fraudscore.py` (+7 -2)
📝 `flowsint-enrichers/src/tools/dockertool.py` (+7 -3)
📝 `flowsint-enrichers/src/tools/network/dnsx.py` (+9 -2)
</details>
### 📄 Description
Two enrichers return an empty result instead of failing loudly, so the task is reported as succeeded and nothing shows up in the graph.
## 1. `domain_to_dns` — dnsx no longer accepts a bare `-d`
`DnsxTool.resolve_domain()` builds:
```
dnsx -d <domain> -a -aaaa -json -silent
```
Since dnsx 1.2, `-d` means *"bruteforce this domain"* and requires a wordlist:
```
$ docker run --rm projectdiscovery/dnsx -d example.com -a -aaaa -json -silent
[FTL] missing wordlist(w) flag required with domain(d) input
$ echo $?
0
```
The exit code is **0**, so nothing raises — the enricher just returns `[]` and Celery logs `succeeded`. From the UI it looks like the domain simply has no DNS records.
**Fix:** feed the single target on stdin, which is the supported single-target invocation:
```
sh -c "echo <domain> | dnsx -a -aaaa -json -silent"
```
`DockerTool.launch()` gains an optional `entrypoint` argument so a shell can be placed in front of the image entrypoint. The domain is passed through `shlex.quote()`.
Verified against `projectdiscovery/dnsx:latest` (v1.2.2):
```
resolve_domain("<a test domain>") -> ['13.227.138.65', '13.227.138.39', '13.227.138.34', '13.227.138.124']
```
## 2. `ip_to_fraudscore` — Scamalytics API host is per-account
The host is hardcoded:
```python
requests.get(f'https://api12.scamalytics.com/v3/{api_username}/?key={api_key}&ip={ip.address}')
```
Scamalytics provisions each account on a numbered API node and hands out the full base URL at signup. An account on a different node gets a plain **404** from `api12`, with the same silent-empty-result outcome. On a live v3 account provisioned on `api11`:
| host | result |
|---|---|
| the account's own node | `200` + full JSON |
| `api12` | `404 Not Found` |
**Fix:** read the host from a `SCAMLYTICS_API_HOST` secret / env var, **defaulting to `api12`** so existing deployments are unchanged.
## Notes
- No behaviour change for anyone already working: the Scamalytics default is preserved, and the dnsx change only alters how the single target is passed.
- Happy to split this into two PRs, add tests, or make the dnsx change use a different mechanism if you prefer — just say the word.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/reconurge/flowsint/pull/200
Author: @Topman3579
Created: 7/27/2026
Status: ✅ Merged
Merged: 7/28/2026
Merged by: @dextmorgn
Base:
main← Head:fix/dnsx-stdin-and-scamalytics-host📝 Commits (1)
ebda0f4fix(enrichers): dnsx stdin input + configurable Scamalytics API host📊 Changes
3 files changed (+23 additions, -7 deletions)
View changed files
📝
flowsint-enrichers/src/flowsint_enrichers/ip/to_fraudscore.py(+7 -2)📝
flowsint-enrichers/src/tools/dockertool.py(+7 -3)📝
flowsint-enrichers/src/tools/network/dnsx.py(+9 -2)📄 Description
Two enrichers return an empty result instead of failing loudly, so the task is reported as succeeded and nothing shows up in the graph.
1.
domain_to_dns— dnsx no longer accepts a bare-dDnsxTool.resolve_domain()builds:Since dnsx 1.2,
-dmeans "bruteforce this domain" and requires a wordlist:The exit code is 0, so nothing raises — the enricher just returns
[]and Celery logssucceeded. From the UI it looks like the domain simply has no DNS records.Fix: feed the single target on stdin, which is the supported single-target invocation:
DockerTool.launch()gains an optionalentrypointargument so a shell can be placed in front of the image entrypoint. The domain is passed throughshlex.quote().Verified against
projectdiscovery/dnsx:latest(v1.2.2):2.
ip_to_fraudscore— Scamalytics API host is per-accountThe host is hardcoded:
Scamalytics provisions each account on a numbered API node and hands out the full base URL at signup. An account on a different node gets a plain 404 from
api12, with the same silent-empty-result outcome. On a live v3 account provisioned onapi11:200+ full JSONapi12404 Not FoundFix: read the host from a
SCAMLYTICS_API_HOSTsecret / env var, defaulting toapi12so existing deployments are unchanged.Notes
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.