Repository navigation
Conversation
When the IPQualityScore API answers with success: false — an invalid API
key, an exhausted quota, an unsupported value — RequestHandler.get()
stored the API message in misperrors and then executed a bare raise from
inside the try block, where no exception is active. Python turns that
into RuntimeError("No active exception to reraise"), which the
except (ConnectTimeout, ProxyError, InvalidURL) clause does not match, so
it escaped handler() entirely: the analyst saw an opaque module crash
instead of the message IPQS actually returned. The bare raise now becomes
a module-specific IPQualityScoreError carrying that message, and handler()
catches it around the lookup dispatch and returns misperrors, which is the
error contract MISP expects.
Verified with flake8 on the changed file and the full test suite against a
local modules server: 161 passed, 4 skipped, 5 subtests passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018dfYpyaSZd1nxSRLr8suj8
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BLUF — An IPQualityScore API failure raises an unhandled
RuntimeErrorinstead of a usable error message.RequestHandler.get()inexpansion/ipqs_fraud_and_risk_scoring.pyuses a bareraiseinside atrybody when the API returnssuccess: false, producingRuntimeError: No active exception to reraise, which the surroundingexcept (ConnectTimeout, ProxyError, InvalidURL)does not cover.IPQualityScoreErrorcarrying the API message, raises that instead, and wraps the ip/url/email/phone/username/password dispatch inhandler()with atry/exceptreturningmisperrors.The defect
In
RequestHandler.get(), when the IPQualityScore API responds withsuccess: false, the handler sets the error message and then executes a bareraiseinside thetrybody — not inside anexceptclause:A bare
raisewith no exception currently being handled producesRuntimeError: No active exception to reraise. ThatRuntimeErroris not a member of theexcept (ConnectTimeout, ProxyError, InvalidURL)tuple that wraps this code, so it propagates straight out ofget(), out ofhandler(), and out of the module entirely.Impact
Whenever the IPQualityScore API reports a failure for an enrichment lookup (bad/expired API key, over quota, malformed IOC, etc.), the module crashes with an unhandled
RuntimeErrorinstead of returning the informative error MISP module callers expect. An analyst enriching an attribute sees a generic module crash/traceback instead of the actual reason the IPQS lookup failed, which is unhelpful for triage and makes the failure harder to diagnose.The fix
Introduced a module-level
IPQualityScoreErrorexception carrying the API's error message and raised that instead of the bareraise.handler()'s ip/url/email/phone/username/password lookup dispatch is now wrapped in atry/except IPQualityScoreError: return misperrors, so an API-reported failure now returns the standard MISP module error response instead of crashing. Thefile_query_input_typebranch, which is mutually exclusive with the wrapped branches, was changed fromelifto a separateifto accommodate the newtryblock; behavior for file-type attributes is unchanged.The two other
raisestatements the finding also flagged (:158,:183) were left as-is: they sit insideexcept HTTPError as error:blocks where an exception is genuinely active, so they are correct re-raises, not the described defect.Behaviour change
Before this fix, an IPQS API failure crashed the module with an unhandled
RuntimeError. After this fix, it returnsmisperrorswith the API's error message, which is the module's documented error-reporting contract — this brings the failure path in line with how every other error in this module is already reported, rather than introducing new behavior.Verification
flake8 --extend-exclude=misp_modules/lib/,tests/,website/on the changed file: clean, no output.python -m py_compile misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py: succeeds.161 passed, 4 skipped, 5 subtests passed in 150.44s (0:02:30).MISP module ipqs_fraud_and_risk_scoring (type=expansion) imported).Found during a review of the repository; other findings are being submitted as separate PRs.
🤖 Generated with Claude Code