Repository navigation
require application/json on tika-server /pipes and /async - #3442
Open
mrdevel2002-ui wants to merge 1 commit into
Open
mrdevel2002-ui wants to merge 1 commit into
mrdevel2002-ui wants to merge 1 commit into
Conversation
Without @consumes both handlers read the tuple JSON under any Content-Type, so a browser can submit one cross-site as a text/plain, form-urlencoded or untyped POST with no CORS preflight. Generated-by: Claude Code
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.
PipesResource.postRmetaandAsyncResource.posthave no@Consumes, so they parse the FetchEmitTuple JSON whatever the request's Content-Type is. That makes/pipesand/asyncreachable by a cross-site request. A page on any origin can callfetch("http://tika:9998/pipes", {method: "POST", mode: "no-cors", body: tupleJson}). The body goes out astext/plain(or untyped, for a Blob body), which is a CORS simple request, so the browser sends it with no preflight. The server then runs the fetch, parse and emit with the operator's fetchers and emitters. For example, it can make an http fetcher request an internal URL, or read a file through a file-system fetcher and write it out through the configured emitter. The attacker can't read the response, but the side effects happen. tika-server has no caller authentication, and the security model relies on keeping it on a trusted network. A browser inside that network gets round that restriction, and DNS rebinding reaches the same calls.Both handlers now declare
@Consumes("application/json"). A cross-originapplication/jsonPOST needs a preflight, which the server won't grant unless the operator configurescors. This is the content type the documented curl examples already send. The trade-off is that a client posting the tuple JSON astext/plain, or with no Content-Type, now gets 415. I chose this over refusing only the safelisted types, because an untyped body is still a simple request. This is the only JSON-body POST route in tika-server. The other POST routes are multipart and behindallowPerRequestConfig, so they are left alone here.testCrossSiteSimpleRequestIsRefusedinTikaPipesTestposts a valid tuple astext/plain, as form-urlencoded and with no Content-Type. It expects 415 each time and checks that nothing was emitted. On main it fails withexpected: <415> but was: <200>. The existing pipes and async tests usedWebClient.postwithout a type, so they now declareapplication/json../mvnw clean installis green for tika-server-core (238 tests) and tika-server-standard (145 tests), including checkstyle, spotless and forbidden-apis../mvnw clean install(tika-server-core and tika-server-standard)Generated-by:per the ASF Generative Tooling Guidancemainbranch