fix(bigframes): world-readable temp zip in create_cloud_function#17522
fix(bigframes): world-readable temp zip in create_cloud_function#17522tswast merged 1 commit intogoogleapis:maingoogleapis/google-cloud-python:mainfrom saddamr3e:cloud-function-source-temp-zipsaddamr3e/google-cloud-python:cloud-function-source-temp-zipCopy head branch name to clipboard
Conversation
|
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. |
There was a problem hiding this comment.
Code Review
This pull request improves security and cleanup when creating cloud functions by ensuring that the generated source code and its zipped archive are both stored within a secure, temporary scratch directory. This prevents a world-readable copy of the user code from being left behind after cleanup. There are no review comments, and I have no additional feedback to provide.
|
@saddamr3e We are missing the CLA. Please sign. |
) Repro against the unpatched `create_cloud_function` archive step: archive_path : /tmp/tmpXXXX.zip # sibling of the 0700 TemporaryDirectory dir removed : True zip remains : True # survives TemporaryDirectory cleanup zip perms : 0o644 world-readable: True `shutil.make_archive(directory, "zip", directory)` appends `.zip` to `base_name`, so the archive lands at `<tempdir>.zip`, a sibling of the temp dir rather than inside it. That copy of the generated cloud function source (which embeds the cloudpickled UDF) is created mode 0644 in the shared system temp directory and is not removed when the `TemporaryDirectory` is cleaned up, so any other local user can read it. Fix keeps the sources in a subdirectory and writes the archive inside the 0700 `TemporaryDirectory`, so it inherits the restrictive permissions and is cleaned up with the rest of the scratch space. - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary)
🤖 I have created a release *beep* *boop* --- ## [2.44.0](bigframes-v2.43.0...bigframes-v2.44.0) (2026-06-25) ### Features * add date functions to `bigframes.bigquery` module ([#17514](#17514)) ([e5d2e35](e5d2e35)) * **bigframes:** add AI TVFs to the pandas bq accessor ([#17402](#17402)) ([ee74e31](ee74e31)) * Experimental transpilation of unannotated python callables ([#17419](#17419)) ([ea9aad9](ea9aad9)) * support gemini-3.x models in loader and update default model to gemini-3.5-flash ([#17557](#17557)) ([3619b29](3619b29)) * support interactive execution of deferred DataFrames in TableWidget ([#17486](#17486)) ([421eebd](421eebd)) ### Bug Fixes * avoid invalid CAST(NULL AS NULL) in SQLGlot compiler ([#17487](#17487)) ([3b79caa](3b79caa)) * **bigframes:** world-readable temp zip in create_cloud_function ([#17522](#17522)) ([e726878](e726878)) * bump @angular/common, @angular/forms, @angular/platform-browser and @angular/router in /packages/bigframes/bigframes/display/table_widget_angular ([#17525](#17525)) ([2f893b1](2f893b1)) * bump langsmith from 0.8.0 to 0.8.18 in /packages/bigframes ([#17518](#17518)) ([f23063f](f23063f)) * bump msgpack from 1.1.1 to 1.2.1 in /packages/bigframes ([#17520](#17520)) ([36b5b7e](36b5b7e)) * bump undici and @angular/build in /packages/bigframes/bigframes/display/table_widget_angular ([#17519](#17519)) ([6fc45e3](6fc45e3)) * handle empty endpoints during cloud function reuse ([#17501](#17501)) ([4f5593a](4f5593a)) ### Documentation * ensure that PlotAccessor is included in the API reference ([#17513](#17513)) ([6febabf](6febabf)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Repro against the unpatched
create_cloud_functionarchive step:shutil.make_archive(directory, "zip", directory)appends.ziptobase_name, so the archive lands at<tempdir>.zip, a sibling of the temp dir rather than inside it. That copy of the generated cloud function source (which embeds the cloudpickled UDF) is created mode 0644 in the shared system temp directory and is not removed when theTemporaryDirectoryis cleaned up, so any other local user can read it.Fix keeps the sources in a subdirectory and writes the archive inside the 0700
TemporaryDirectory, so it inherits the restrictive permissions and is cleaned up with the rest of the scratch space.