Repository navigation
Release 4.7.0 - #330
Release 4.7.0#330
Conversation
Threat-intel reports print indicators defanged (hxxps[:]//evil[.]com, 127[.]0[.]0[.]1). The server looks URLs up by an exact hash and stores a submitted URL verbatim, so a defanged value silently missed a search or became a broken URL artifact. Add polyswarm_api.refang (refang_text, is_network_ioc, refang_ioc) and a refang_iocs=True constructor flag. When on, the client refangs the URL/domain/IP inputs of search_url, search_by_metadata (ips/urls/domains, never the free-form query), search_by_ioc, check_known_hosts, the known-host writes, and every URL submission path. Live values are sent unchanged; refang_iocs=False sends inputs verbatim. The rules, gate and case table are shared with other PolySwarm clients; test/fixtures/refang_cases.json is kept byte-identical across them.
Python's case-insensitive flag folds Unicode (U+212A KELVIN SIGN matched "k", so "evil[.]Kom" was refanged), \s/\S cover Unicode whitespace, and "$" matches before a trailing newline - all unlike the other clients that implement the same contract. Spell letters as explicit [aA] classes, use the ASCII whitespace set, trim only that set, and fullmatch the network-IoC pattern. The shared case table grows to 39 cases pinning these.
submit already skipped the refang for preprocessing type qrcode, whose argument names an image file rather than a URL; sandbox_file did not, so a file called qr[.]png was sent as qr.png. Pin both paths on both transports, cover the async opt-out of the known-host writes and the bare-string form of the list arguments, and put the httpx_kwargs paragraph back under the constructor block in the contract spec.
…the architecture specs
…g_iocs on the async constructor
A default-on refang changes what the write paths store (known-host rows, URL submissions), which the versioning table only allows in a major. With refang_iocs=False as the default the new keyword is purely additive; the CLI opts in through its own option. Also read the QR preprocessing type with .get() in submit, as sandbox_file already does, and cover the uploaded URL content on both transports with its opt-out twin.
The QR branch handed the path string to from_content, so the upload body was the text of the path and the server failed the task as an unrecognised image. Read it with from_path, as submit does. Also point refang.py's docstring at its spec section instead of repeating it, and say the case-table pin guards only its own copy.
A respx test on both clients asserts the S3 PUT body is the image and the create body names its unrefanged basename; the spy-based tests could not see the uploaded body. Also fix the two spec sentences that still described the path being passed on as content.
The reverse IOC search answers bare sha256s, so a caller that wants to show the matching artifacts has to fan out one metadata search per hash. The server gains an opt-in `with_artifacts` that returns each artifact's metadata-search row instead; this exposes it on both clients as an optional keyword. - Absent or False sends nothing new: every existing call, including one with no search term, builds exactly the request it did before and yields the same IOC/sha256 items. - True sends `with_artifacts=1` and parses the rows with `Metadata`, the resource `search_by_metadata` already yields. An int, not a bool: the session renders bools as 'True', which the server's boolean parser refuses. The row parse is covered by a respx body on both transports because the e2e stack does not serve the parameter yet; recording the live pass is parked in specs/99-open-questions.md. Builder and pass-through tests pin the request shape on both clients, including that a bare call is still sent unchanged.
… 400 rule The with_artifacts rows carry the server's include set, which also keeps scan.first_scan.created and hash.ssdeep/tlsh, so first_seen, ssdeep and tlsh are populated. The endpoint table and docstring now list that set as the server's, and state the refusal precisely: with_artifacts=True and no term is a 400; without the flag a bare call behaves as before. The respx fixture mirrors the set exactly and asserts the populated fields plus one that falls outside it. The new test module is listed in the testing spec.
The CLI client adopts `search_by_ioc(with_artifacts=)` in the paired change set and expresses that as `polyswarm_api>=4.7.0`. develop already declares 4.6.0 for a surface that does not include this keyword, so the floor needs the next version up; a floor cannot name a version this repo has not declared, so the bump lands here, in the feature PR (AGENTS.md's standing exception). Minor: one new optional keyword whose default preserves today's request, so no existing call changes behaviour. Bumped with bump-my-version; the emitted string is a clean `4.7.0`. The `with_artifacts=True` path needs a server that supports the parameter, so this repo releases only after that server leg is deployed, and before the CLI.
…t invariant 6 Invariant 6 said version bumps never go in feature PRs, which contradicts AGENTS.md's standing exception and the bump this change carries. It now names the exception: when a sibling resolves this repo from source by branch name and raises its floor to the new surface's version, the clean X.Y.0 bump lands in the feature PR.
fix: sandbox_file reads a QR-code image instead of uploading its path
|
Release PR checks out against AGENTS.md: develop → master, version is a clean
Nothing else needs action. The |
Release 4.7.0
hxxps[:]//evil[.]com,1.2.3[.]4) are refanged before requests are built, mirroring the portal'srefangIocrule for rule (sharedrefang_cases.json).sandbox_fileQR fix (fix: sandbox_file reads a QR-code image instead of uploading its path #328): a QR-code image is read instead of uploading its path.search_by_ioc(with_artifacts=)(feat: search_by_ioc(with_artifacts=) returns artifact metadata rows #329): opt-in; returns artifact metadata rows instead of bare sha256s. Omit it and every call is unchanged.4.6.0 was declared on develop but never published; this release supersedes it.
Why this release is on the critical path
polyswarm-cli4.6.0 pinspolyswarm_api>=4.7.0. This release has to publish before the CLI's.Requires
with_artifactson/v3/ioc/search). Without it the flag is ignored upstream and callers get sha256 strings.Deploy steps