-
Notifications
You must be signed in to change notification settings - Fork 0
Enhance embed URL handling and validation system #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: embed-url-handling-pre
Are you sure you want to change the base?
Enhance embed URL handling and validation system #7
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Greptile OverviewConfidence Score: 0/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as External Site
participant JS as embed.js
participant EC as EmbedController
participant TE as TopicEmbed
participant Job as RetrieveTopic Job
participant TR as TopicRetriever
participant PF as PollFeed
participant HTTP as External URL
Client->>JS: Load page with discourse-comments div
JS->>EC: GET /embed/best?embed_url=...
EC->>EC: ensure_embeddable() validates referer host
EC->>TE: topic_id_for_embed(url)
alt Topic exists
TE-->>EC: return topic_id
EC->>EC: Create TopicView with best posts
EC-->>JS: Render embed view
else Topic not found
EC->>Job: enqueue(:retrieve_topic)
EC-->>JS: Render loading view
Job->>TR: new(embed_url).retrieve
TR->>TR: Check invalid_host?
TR->>TR: Check retrieved_recently? (Redis throttle)
alt Feed polling enabled
TR->>PF: execute({})
PF->>HTTP: open(feed_url) [VULNERABLE]
HTTP-->>PF: RSS/Atom feed
PF->>TE: import(user, url, title, content)
end
alt Not in feed or no feed
TR->>TE: import_remote(user, url)
TE->>HTTP: open(url).read [VULNERABLE]
HTTP-->>TE: HTML content
TE->>TE: Readability extraction
end
TE->>TE: absolutize_urls(url, contents)
TE->>TE: Inject footer with URL [XSS VULNERABLE]
TE->>TE: Create/Update Post with raw_html
end
JS->>JS: Listen for postMessage events
EC->>JS: Send discourse-resize message
JS->>JS: Update iframe height
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
27 files reviewed, 4 comments
| def self.import(user, url, title, contents) | ||
| return unless url =~ /^https?\:\/\// | ||
|
|
||
| contents << "\n<hr>\n<small>#{I18n.t('embed.imported_from', link: "<a href='#{url}'>#{url}</a>")}</small>\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: XSS vulnerability: unsanitized URL directly interpolated into HTML. Attacker-controlled url value can inject arbitrary JavaScript.
| contents << "\n<hr>\n<small>#{I18n.t('embed.imported_from', link: "<a href='#{url}'>#{url}</a>")}</small>\n" | |
| contents << "\n<hr>\n<small>#{I18n.t('embed.imported_from', link: "<a href='#{ERB::Util.html_escape(url)}'>#{ERB::Util.html_escape(url)}</a>")}</small>\n" |
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/models/topic_embed.rb
Line: 13:13
Comment:
**logic:** XSS vulnerability: unsanitized URL directly interpolated into HTML. Attacker-controlled `url` value can inject arbitrary JavaScript.
```suggestion
contents << "\n<hr>\n<small>#{I18n.t('embed.imported_from', link: "<a href='#{ERB::Util.html_escape(url)}'>#{ERB::Util.html_escape(url)}</a>")}</small>\n"
```
How can I resolve this? If you propose a fix, please make it concise.| require 'ruby-readability' | ||
|
|
||
| opts = opts || {} | ||
| doc = Readability::Document.new(open(url).read, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: CRITICAL: open() with user-controlled URL enables command injection. Kernel#open interprets pipe characters, allowing arbitrary shell command execution via crafted URLs like |ls.
Use URI.open() or Net::HTTP instead:
uri = URI.parse(url)
response = Net::HTTP.get_response(uri)
doc = Readability::Document.new(response.body, ...)
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/models/topic_embed.rb
Line: 48:48
Comment:
**logic:** CRITICAL: `open()` with user-controlled URL enables command injection. Kernel#open interprets pipe characters, allowing arbitrary shell command execution via crafted URLs like `|ls`.
Use `URI.open()` or `Net::HTTP` instead:
```
uri = URI.parse(url)
response = Net::HTTP.get_response(uri)
doc = Readability::Document.new(response.body, ...)
```
How can I resolve this? If you propose a fix, please make it concise.| return if user.blank? | ||
|
|
||
| require 'simple-rss' | ||
| rss = SimpleRSS.parse open(SiteSetting.feed_polling_url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: CRITICAL: same command injection vulnerability via Kernel#open with admin-configured URL. Use URI.open() or safer HTTP client:
uri = URI.parse(SiteSetting.feed_polling_url)
response = Net::HTTP.get(uri)
rss = SimpleRSS.parse(response)
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/jobs/scheduled/poll_feed.rb
Line: 29:29
Comment:
**logic:** CRITICAL: same command injection vulnerability via Kernel#open with admin-configured URL. Use `URI.open()` or safer HTTP client:
```
uri = URI.parse(SiteSetting.feed_polling_url)
response = Net::HTTP.get(uri)
rss = SimpleRSS.parse(response)
```
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| function postMessageReceived(e) { | ||
| if (!e) { return; } | ||
| if (discourseUrl.indexOf(e.origin) === -1) { return; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Insecure origin validation. indexOf can be bypassed with URLs like https://evil.com?discourse.example.com. Use strict comparison:
| if (discourseUrl.indexOf(e.origin) === -1) { return; } | |
| if (e.origin !== discourseUrl.replace(/\/$/, '')) { return; } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/assets/javascripts/embed.js
Line: 17:17
Comment:
**logic:** Insecure origin validation. `indexOf` can be bypassed with URLs like `https://evil.com?discourse.example.com`. Use strict comparison:
```suggestion
if (e.origin !== discourseUrl.replace(/\/$/, '')) { return; }
```
How can I resolve this? If you propose a fix, please make it concise.
Test 4
Replicated from ai-code-review-evaluation/discourse-greptile#4