Harden AI integration per BApp reviewer feedback (v2.1.1) - #6
Merged
Conversation
Three items from the BApp Store automated review:
1. AiClient threading — single-thread executor meant concurrent scan
threads queued on one worker and could time out while still in the
queue rather than during the actual call. Replaced with a bounded
fixed thread pool (4 daemon workers) so concurrent callers are
serviced in parallel and the 2s timeout measures real in-flight
time. shutdown() unchanged (works for any ExecutorService).
2. AiTriage prompt injection — attacker-controlled HTTP content (URL,
headers, up to 400 bytes of body) was concatenated straight into
the user message, so a crafted response could instruct the model to
return SUPPRESS and silently drop a real finding. Now:
- trusted fields (finding name/severity) sit OUTSIDE the untrusted
block; all HTTP-derived content sits inside <http_exchange> tags;
- the system prompt instructs the model to treat tag contents as
data only and never obey instructions within them;
- delimiter tokens are neutralised in the untrusted content so a
forged </http_exchange> can't break out of the block;
- parseVerdict is now strict safe-failure: only a well-formed JSON
object whose verdict is exactly "SUPPRESS" suppresses; anything
else (unparseable, wrong type, prose, markdown-fenced) → KEEP.
Added tolerant {...} extraction for models that fence their JSON.
3. AiFieldDiscovery prompt injection — same structural-delimiter
treatment: method/path/existing-key-names wrapped in <http_context>
tags with a treat-as-data-only instruction and delimiter
neutralisation. (The downstream sanitiseAndDedupe allowlist already
bounded impact; this closes the steering gap.)
Build verified clean. Version bumped to 2.1.1 across pom, banner, CI,
and docs; CLAUDE.md gotcha #3 updated to note the multi-worker
requirement.
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.
Addresses the three items from the BApp Store automated review of the AI integration.
1. AiClient threading (performance correctness)
The single-thread executor meant concurrent scan threads queued on one worker — a thread could hit its 2s timeout while still waiting in the queue, not during the actual call. Replaced with a bounded fixed thread pool (4 daemon workers) so concurrent callers run in parallel and the timeout measures real in-flight time.
shutdown()is unchanged.2. AiTriage prompt injection (security — the serious one)
Attacker-controlled response content was concatenated straight into the prompt, so a crafted server response could instruct the model to return
SUPPRESSand silently drop a legitimate finding. Fixed:<http_exchange>tags.</http_exchange>can't break out.parseVerdictis now strict safe-failure: only a well-formed JSON object whoseverdictis exactlySUPPRESSsuppresses; anything else (unparseable, wrong type, prose, markdown-fenced) → KEEP. Added tolerant{...}extraction for fenced replies.3. AiFieldDiscovery prompt injection
Same structural-delimiter treatment — method/path/key-names wrapped in
<http_context>tags with a data-only instruction and delimiter neutralisation. The downstreamsanitiseAndDedupeallowlist already bounded practical impact; this closes the steering gap.Diff
9 files, +123 / −47. AI layer only — no scan-check detection logic touched.
Test plan
mvn clean packageclean.Releases as v2.1.1. Follow-up to submission extension-portal#439.