| Название | yaojingang GEOFlow commit/2aeec4f449c9fa6790392723150c9151b6a4a337 Cross Site Scripting |
|---|
| Описание | ## 1. XSS in JSON-LD Theme Output
### Root Cause
Frontend theme templates render user-controlled values inside `<script type="application/ld+json">` with raw `{!! json_encode(...) !!}` output and without `JSON_HEX_TAG`. Because `</script>` is not escaped, attacker-controlled input can break out of the JSON-LD block and inject JavaScript.
Relevant code path:
```php
// app/Http/Controllers/Site/HomeController.php
$search = trim((string) $request->query('search', ''));
...
if ($search !== '') {
$pageDescription = $search.' - '.$siteDescription;
}
```
```blade
{{-- resources/views/theme/toutiao-news-20260426/home.blade.php --}}
<script type="application/ld+json">
{!! json_encode($collectionSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) !!}
</script>
```
`$search` influences `$pageTitle` / `$pageDescription`, which are inserted into `$collectionSchema`, then emitted as raw HTML instead of safely escaped JSON for a `<script>` context.
Why `json_encode()` does not make this safe:
- `json_encode()` makes the data valid JSON, but the data is embedded inside an HTML `<script>` element, so HTML parsing rules still apply first.
- The template uses `JSON_UNESCAPED_SLASHES`, so `</script>` is emitted literally instead of as `<\/script>`.
- Once the browser sees a literal `</script>`, it closes the current script block before any JSON semantics matter, and the following attacker-controlled `<script>...</script>` is executed.
Example:
If user input is:
```text
</script><script>alert(document.domain)</script>
```
the rendered page becomes effectively:
```html
<script type="application/ld+json">
{
"description": "</script><script>alert(document.domain)</script>"
}
</script>
```
The browser does not treat this as "safe because it is inside JSON". It first runs the HTML parser for the `<script>` element. As soon as the parser encounters the literal `</script>`, it closes the current JSON-LD block, and the following `<script>alert(...)</script>` becomes a new executable script tag.
This is therefore not a "missing JSON encoding" issue. It is a context-unsafe HTML script embedding issue: valid JSON is still unsafe when it is injected into a raw `<script>` block without escaping the closing tag sequence.
There are two reachable variants:
- Reflected XSS via the public homepage `search` parameter.
- Stored XSS via attacker-controlled article titles rendered on article pages.
### PoC
Open the following URL in the browser:
```text
http://127.0.0.1:38080/?search=%3C%2Fscript%3E%3Cscript%3Ealert(document.domain)%3C%2Fscript%3E
``` |
|---|
| Источник | ⚠️ https://github.com/yaojingang/GEOFlow/issues/60 |
|---|
| Пользователь | iswangxy (UID 99909) |
|---|
| Представление | 17.07.2026 09:01 (1 месяц назад) |
|---|
| Модерация | 30.08.2026 16:44 (1 month later) |
|---|
| Статус | принято |
|---|
| Запись VulDB | 397158 [yaojingang GEOFlow до 2.1.0 JSON-LD Theme HomeController.php Поиск межсайтовый скриптинг] |
|---|
| Баллы | 20 |
|---|