Repository navigation
Improve search validation, date handling, and client-cache headers - #187
Open
afoote-mitre wants to merge 7 commits into
Open
afoote-mitre wants to merge 7 commits into
afoote-mitre wants to merge 7 commits into
Conversation
afoote-mitre
force-pushed
the
af/180-search-consistency
branch
from
October 20, 2026 15:22
ff274f8 to
6d12fdd
Compare
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.
Summary
Address items 1-4 of #180 for
POST /search: consistent error responses, precise page-size validation, consistent boolean inputs, and more useful date formats. Also implement the approved client-cache response policy from item 7 for both search endpoints.The additional missing-CVE-ID warning feature from item 5 has been removed following team review. Item 6 and the remaining parts of item 7 are not being adopted in this PR. The issue should remain open for tracking the team's decisions rather than being automatically closed by this change.
Why These Changes Were Needed
/searchnow consistently returns{ "error": "CODE", "message": "Description" }, using the first error when multiple validations fail. Case-insensitive and trailing-slash route variants use the same shape./webSearcherror handling is unchanged.routes/index.js,routes/index.test.js,api-docs/openapi.test.js,README.md,test/postman/buildCollection.jsRESULTS_PER_PAGE_INT; positive integers above 500 returnMAX_RESULTS_LIMIT. Valid integer strings remain accepted; arrays and booleans are rejected before coercion.routes/index.js,routes/index.test.js,README.md,test/postman/buildCollection.jsknownExploitedanddisputedpreviously rejected string booleans accepted by the other filters. All five accept JSON booleans and lowercase"true"/"false"strings, normalizing strings before downstream checks. Numbers, null, arrays, and other strings remain invalid. Omitted filters retain their existing behavior.routes/index.js,routes/index.test.js,routes/swagger.js,api-docs/openapi.test.js,README.md,test/postman/buildCollection.jsYYYY-MM-DDand timestamps with seconds, an explicit timezone, and up to three fractional-second digits. Date-only starts become midnight UTC; date-only ends include the whole day. Explicit timestamps retain their exact instant. Range ordering is checked after normalization; impossible dates, timezone-less timestamps, leap seconds, and finer precision remain invalid. Applies to publication, modification, SSVC, and KEV boundaries.utils/searchDates.js,utils/searchDates.test.js,routes/index.js,controllers/middleware.js,utils/errors.js, associated tests,routes/swagger.js,README.md/searchand/webSearch, including empty results, now advertiseCache-Control: private, max-age=60. Error and health/readiness responses useno-store.SearchClientCacheMaxAgeSecondschanges the duration; zero or invalid values produceno-store. This provides explicit client guidance without introducing an API result cache or quota counter.utils/clientCachePolicy.js,server.js,controllers/searchController.js, config files,.env.example,README.md,routes/index.js,routes/swagger.js, generated OpenAPI, and associated testsCVE_IDS_NOT_FOUND/CVE_ID_AVAILABILITY_UNVERIFIED. Regression coverage confirms unmatched IDs do not prevent matching records from returning or cause an extra request.controllers/searchController.js,utils/searchQueryBuilder.js, deletedutils/searchCveIdWarnings.jsand its tests,routes/search.integration.test.js,routes/swagger.js,README.md, Postman source/collectionCVE ID Behavior
CVE_IDS_NOT_RETURNEDwarning for pre-1999 IDs remains unchanged. This is separate from the removed feature.Date Input Examples
{ "pubStartDate": "2024-01-01", "pubEndDate": "2024-12-31", "lastModStartDate": "2024-01-01T01:00:00+01:00" }The publication boundaries normalize to
2024-01-01T00:00:00.000Zand2024-12-31T23:59:59.999Z. The modification boundary normalizes to2024-01-01T00:00:00.000Z. All boundaries are inclusive.Client-Cache Behavior
Both search endpoints use POST. Ordinary HTTP caches do not automatically reuse a cached POST response for another POST. Integrators must implement application-level caching keyed by API environment, endpoint, and the complete request body, including filters, scope, sorting, and pagination. The freshness header is a hint, not a requirement that forces clients to cache. No server-side cache, queue, request coalescing, rate accounting, or additional OpenSearch operation is introduced.
Cached results can add up to the configured freshness duration of staleness and do not guarantee indexing freshness or consistency across separately cached pages. Clients should not cache errors or reuse historical quota headers as current accounting. Existing ETags do not add conditional POST/304 behavior.
Deferred or Rejected Items
X-Powered-Byand User-Agent behavior remain unchanged.