Skip to content

Avoid storing Flickr secret-bearing URLs#46

Merged
glenn-jocher merged 1 commit into
mainfrom
fix-codeql-cleartext-secret
Apr 23, 2026
Merged

Avoid storing Flickr secret-bearing URLs#46
glenn-jocher merged 1 commit into
mainfrom
fix-codeql-cleartext-secret

Conversation

@glenn-jocher

@glenn-jocher glenn-jocher commented Apr 23, 2026

Copy link
Copy Markdown
Member

Summary

  • skip Flickr photos that do not provide url_o instead of constructing fallback URLs with photo["secret"]
  • redact scraper progress output so full image URLs are not logged to stdout
  • sanitize download filenames from URI paths before writing files, dropping query parameters up front
  • update README output/compatibility notes and add regression tests

Security

Addresses CodeQL alert #2: py/clear-text-storage-sensitive-data at utils/general.py.

Tests

  • python -m compileall -q .
  • uv run --with-requirements requirements.txt --with pytest pytest -q
  • git diff --check
  • uvx ruff check --extend-select F,I,D,UP,RUF,FA --target-version py39 --ignore D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012 flickr_scraper.py utils/general.py tests
  • uv run --with-requirements requirements.txt python flickr_scraper.py --search 'honeybees on flowers' --n 1 (expected missing credential path)

🛠️ PR Summary

Made with ❤️ by Ultralytics Actions

🌟 Summary

This PR improves the Flickr scraper’s privacy and safety by only using Flickr-provided original image URLs, skipping incomplete entries, and preventing sensitive URL details from appearing in filenames or console output 🔒📷

📊 Key Changes

  • build_photo_url() now returns only Flickr’s direct url_o value instead of generating fallback image URLs from metadata.
  • Photos missing url_o are now skipped with a clear message: skipped (missing original URL).
  • Console output was simplified from printing full image URLs to safer status-only messages like found or downloaded 🧹
  • Added a new safe_filename_from_uri() helper to sanitize filenames and remove query parameters before saving files.
  • download_uri() now uses the sanitized filename directly, reducing the chance of secrets or tokens being written to disk.
  • README examples and documentation were updated to reflect the new safer behavior.
  • Tests were updated to verify:
    • no fallback URL construction
    • skipped photos without original URLs
    • redacted console output
    • query parameters are removed from saved filenames ✅

🎯 Purpose & Impact

  • Improves privacy and security by avoiding reuse of Flickr metadata fields like secrets in generated URLs or local filenames 🔐
  • Reduces the risk of leaking sensitive information through logs, terminal output, or saved files.
  • Makes scraper behavior more explicit and predictable: if Flickr does not provide an original image URL, the image is skipped rather than guessed.
  • Slightly changes scraping results: some photos that were previously downloadable via constructed fallback URLs will no longer be included.
  • Overall, this makes the scraper safer and cleaner for users, especially in shared environments, automated pipelines, or logged workflows 🚀

@UltralyticsAssistant UltralyticsAssistant added documentation Improvements or additions to documentation enhancement New feature or request priority: medium Normal priority; valuable but not urgent. labels Apr 23, 2026
@UltralyticsAssistant

Copy link
Copy Markdown
Member

👋 Hello @glenn-jocher, thank you for submitting a ultralytics/flickr_scraper 🚀 PR! This is an automated message to help with review readiness—an engineer will assist you soon. Please review the checklist below to help ensure a smooth integration ✨

  • Define a Purpose: Clearly explain the purpose of your fix or feature in your PR description, and link to any relevant issues. Ensure your commit messages are clear, concise, and adhere to the project's conventions.
  • Synchronize with Source: Confirm your PR is synchronized with the ultralytics/flickr_scraper main branch. If it's behind, update it by clicking the 'Update branch' button or by running git pull and git merge main locally.
  • Ensure CI Checks Pass: Verify all Ultralytics Continuous Integration (CI) checks are passing. If any checks fail, please address the issues.
  • Update Documentation: Update the relevant documentation for any new or modified features.
  • Add Tests: If applicable, include or update tests to cover your changes, and confirm that all tests are passing.
  • Sign the CLA: Please ensure you have signed our Contributor License Agreement if this is your first Ultralytics PR by writing "I have read the CLA Document and I sign the CLA" in a new message.
  • Minimize Changes: Limit your changes to the minimum necessary for your bug fix or feature addition. "It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is." — Bruce Lee

For more guidance, please refer to our Contributing Guide. Don't hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀

@UltralyticsAssistant UltralyticsAssistant left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 PR Review

Made with ❤️ by Ultralytics Actions

Good privacy-focused cleanup overall: removing fallback URL construction and redacting CLI output are solid improvements, and the tests cover the intended behavior well. I found two correctness issues to address before merging: safe_filename_from_uri() can reintroduce path separators after decoding, and the new missing-URL guard should handle all falsey url_o values, not just None.

💬 Posted 2 inline comments

Comment thread utils/general.py
.replace("%20", "_")
def safe_filename_from_uri(uri):
"""Return a sanitized filename from a URI path without query parameters."""
filename = unquote(Path(urlsplit(uri).path).name) or "download"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ HIGH: unquote() can reintroduce encoded path separators like %2F and %5C after you've already taken .name. That means a crafted URI such as .../..%2Fsecret.txt can turn into ../secret.txt here, and download_uri() will write outside the target directory or fail by creating nested paths. Decode first, then take the basename again from the decoded path.

Suggested change:

Suggested change
filename = unquote(Path(urlsplit(uri).path).name) or "download"
filename = Path(unquote(urlsplit(uri).path).replace("\\", "/")).name or "download"

Comment thread flickr_scraper.py

for photo in photo_list:
url = build_photo_url(photo)
if url is None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 MEDIUM: This only skips None, but build_photo_url() now returns whatever Flickr provides in url_o. If the API returns an empty string or another falsey value, we'll still append/log it and download_uri() may later try to fetch an invalid URL. Treat any falsey value as missing here.

Suggested change:

Suggested change
if url is None:
if not url:

@glenn-jocher glenn-jocher merged commit d6915b4 into main Apr 23, 2026
2 checks passed
@glenn-jocher glenn-jocher deleted the fix-codeql-cleartext-secret branch April 23, 2026 22:15
@UltralyticsAssistant

Copy link
Copy Markdown
Member

Merged! 🎉 Thanks @glenn-jocher for this thoughtful improvement to the Flickr scraper.

As Benjamin Franklin said, “An ounce of prevention is worth a pound of cure.” This update reflects that perfectly by making scraping safer by default: relying only on Flickr-provided original URLs, skipping incomplete entries, and preventing sensitive URL details from leaking into logs or filenames.

Really appreciate the care put into both the implementation and the test/documentation updates. This makes the tool more private, predictable, and trustworthy for everyone using it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request priority: medium Normal priority; valuable but not urgent.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants