Skip to content

Fix dns-resolving to localip#4214

Merged
ildyria merged 5 commits intomasterfrom
more-ssrf-fixes
Mar 22, 2026
Merged

Fix dns-resolving to localip#4214
ildyria merged 5 commits intomasterfrom
more-ssrf-fixes

Conversation

@ildyria
Copy link
Copy Markdown
Member

@ildyria ildyria commented Mar 22, 2026

Summary by CodeRabbit

  • Security Improvements

    • Photo URL validation now resolves hostnames and blocks targets that resolve to private/reserved IPs or localhost, improving protection against DNS rebinding and updating failure messages accordingly.
  • Version Update

    • Application version bumped to 7.5.2; migration updates stored version and attempts to clear application cache with a safe fallback on failure.
  • Tests

    • Unit tests updated and new cases added to mock DNS resolutions and verify rejection of private/reserved and localhost targets.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: deaa3aed-a10e-4280-a793-b3263b7acf2a

📥 Commits

Reviewing files that changed from the base of the PR and between 9046fe5 and f9e81d7.

📒 Files selected for processing (1)
  • tests/Unit/Rules/PhotoUrlRuleTest.php

📝 Walkthrough

Walkthrough

PhotoUrlRule now accepts an optional DNS resolver, resolves hostnames to A/AAAA records, and validates resolved IPs for private/reserved and localhost addresses via new helpers. A migration bumps the stored version to 7.5.2 and clears cache; tests were updated to inject mocked DNS responses and adjust assertions.

Changes

Cohort / File(s) Summary
DNS Resolution & Validation
app/Rules/PhotoUrlRule.php
Constructor signature changed to accept `\Closure
Migration & Version
database/migrations/2026_03_22_094636_bump_version070502.php, version.md
New migration updates configs row key = 'version' to 070502 in up() and reverts to 070501 in down(); up() attempts Artisan::call('cache:clear') with error handling. version.md value updated from 7.5.17.5.2.
Tests: DNS Injection & Assertions
tests/Unit/Rules/PhotoUrlRuleTest.php
Tests now use a makeRule(?\Closure $dns_get_record) helper to inject DNS responses. Updated expected error messages for private/reserved and localhost cases and added tests covering DNS-rebinding scenarios (resolved to private or loopback IPs).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hop through hosts and fetch their A and AAAA,
I peek at IPs in burrows, sniffing loopback tracks,
Private dens are barred, localhost gets shown the door,
I bump the version, nudge the tests, then skip back for snacks,
Hooray for tidy checks and 7.5.2! 🎉

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 82.35% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ildyria ildyria marked this pull request as ready for review March 22, 2026 09:47
@ildyria ildyria requested a review from a team as a code owner March 22, 2026 09:47
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 650bc952-8b6a-44ac-ba0b-2aa7d8c5e554

📥 Commits

Reviewing files that changed from the base of the PR and between 21cebe2 and 4c0323d.

📒 Files selected for processing (4)
  • app/Rules/PhotoUrlRule.php
  • database/migrations/2026_03_22_094636_bump_version070502.php
  • tests/Unit/Rules/PhotoUrlRuleTest.php
  • version.md

Comment thread app/Rules/PhotoUrlRule.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/Rules/PhotoUrlRule.php (1)

94-109: This only hardens validation, not the actual connect path.

$resolved_ips are discarded after validate(), and the importer still receives the original hostname. Please verify the fetch path pins one of these vetted IPs or re-checks the peer after connect; otherwise a low-TTL rebind can still hit an internal address after this rule passes.

tests/Unit/Rules/PhotoUrlRuleTest.php (1)

188-217: Add an AAAA regression here too.

The new rule has separate DNS_AAAA and IPv6-localhost branches, but the added security tests only drive DNS_A. One AAAA => [['ipv6' => '::1']] case would keep the IPv6 path from regressing unnoticed.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2bb147a9-9240-4ac9-bf23-123970dd346f

📥 Commits

Reviewing files that changed from the base of the PR and between 4c0323d and c4e1020.

📒 Files selected for processing (2)
  • app/Rules/PhotoUrlRule.php
  • tests/Unit/Rules/PhotoUrlRuleTest.php

Comment thread app/Rules/PhotoUrlRule.php
Comment thread app/Rules/PhotoUrlRule.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/Rules/PhotoUrlRule.php (1)

137-150: Consider defensive array key access.

The DNS record arrays are accessed directly via $record['ip'] and $record['ipv6']. While dns_get_record normally returns these keys for valid A/AAAA records, adding defensive checks would prevent potential "undefined array key" notices if the DNS response is malformed or incomplete.

🛡️ Proposed defensive fix
 			$a_records = call_user_func($this->dns_get_record, $host, DNS_A);
 			if ($a_records !== false) {
 				foreach ($a_records as $record) {
-					$ips[] = $record['ip'];
+					if (isset($record['ip'])) {
+						$ips[] = $record['ip'];
+					}
 				}
 			}

 			// Resolve AAAA records (IPv6).
 			$aaaa_records = call_user_func($this->dns_get_record, $host, DNS_AAAA);
 			if ($aaaa_records !== false) {
 				foreach ($aaaa_records as $record) {
-					$ips[] = $record['ipv6'];
+					if (isset($record['ipv6'])) {
+						$ips[] = $record['ipv6'];
+					}
 				}
 			}

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4c15f2cd-5ddd-4f5d-9c5b-de84436e36c5

📥 Commits

Reviewing files that changed from the base of the PR and between c4e1020 and 9046fe5.

📒 Files selected for processing (1)
  • app/Rules/PhotoUrlRule.php

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 22, 2026

Codecov Report

❌ Patch coverage is 89.47368% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.23%. Comparing base (4138667) to head (f9e81d7).
⚠️ Report is 4 commits behind head on master.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@d7415 d7415 left a comment

Choose a reason for hiding this comment

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

Just the one query

Comment thread tests/Unit/Rules/PhotoUrlRuleTest.php Outdated
@ildyria ildyria enabled auto-merge (squash) March 22, 2026 14:20
@ildyria ildyria merged commit 28c5261 into master Mar 22, 2026
44 checks passed
@ildyria ildyria deleted the more-ssrf-fixes branch March 22, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants