Repository navigation
Conversation
DeferredTaskServlet (both javax and jakarta variants) deserialized the task payload through a plain ObjectInputStream with no class filter. The endpoint is registered in every app and its only guard is the X-AppEngine-QueueName header, which the infrastructure attaches to every delivered Task Queue task. Anyone who can create a task in the project (cloudtasks.tasks.create / taskqueue) can therefore have an arbitrary serialized object graph of their choosing deserialized in the app, which is remote code execution when an exploitable gadget class is on the app classpath. Add an ObjectInputFilter to readRequest(): - a default blocklist of well-known deserialization-gadget packages (DEFAULT_SERIAL_FILTER), overridable via the appengine.deferredtask.serialFilter system property; - merged with any JVM-wide jdk.serialFilter so a class rejected by either is rejected. Legitimate DeferredTask payloads are unaffected. Also harden the XML config parsers against XXE: XmlUtils (DocumentBuilderFactory and the schema Validator) and AppEngineWebXmlInitialParse (StAX) now disable DTDs / external entities / external DTD and schema access. These parse appengine-web.xml, queue.xml, cron.xml, dos.xml, etc. Tested: new unit tests for the filter (blocked class rejected, normal class and real DeferredTask allowed) and for XXE (external entity not resolved); existing DeferredTaskServletTest (11) and AppEngineWebXmlInitialParseTest (37) still pass. Verified live on App Engine (see PR): on a stock runtime the gadget payload is fully deserialized (ClassCastException); on this patched runtime it is refused (InvalidClassException: filter status: REJECTED) while normal deferred tasks and push tasks keep working. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Collaborator
Author
|
Superseded by #551 (same change; the branch was renamed, which closed this PR). Continuing there. |
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.
What
Defense-in-depth hardening of input handling in the runtime:
Deferred-task servlet (
DeferredTaskServlet, bothjavaxandjakartavariants): apply an
ObjectInputFilterwhen reading the task payload, with adefault blocklist overridable via the
appengine.deferredtask.serialFiltersystem property and merged with any JVM-wide
jdk.serialFilter. LegitimateDeferredTaskpayloads are unaffected.XML config parsing (
XmlUtilsandAppEngineWebXmlInitialParse): disableDTDs / external entities / external DTD and schema access when parsing
appengine-web.xml,queue.xml,cron.xml,dos.xml, etc.Testing
New unit tests for both changes; existing
DeferredTaskServletTest(11) andAppEngineWebXmlInitialParseTest(37) pass. Verified end-to-end on App Enginethat deferred tasks and push task-queue delivery continue to work with the
change in place.
Rationale and detailed verification shared separately.
🤖 Generated with Claude Code