fix: security & correctness batch — AI ACL, sitemap disclosure, API/CSV columns, forward-compat (#99 #100 #101 #102 #106) #109

Merged
jmiller merged 2 commits from fix/security-correctness-batch into dev 2026-06-29 14:53:42 +00:00
Owner

Second batch from the deep-dive audit. 6 files, all php -l clean.

#99 — AI AJAX endpoint hardening (security)

  • Now requires core.edit/core.create on com_content before generating — previously any authenticated back-end user could trigger outbound paid AI calls.
  • callAiApi: 20s timeout + HTTP status check (throws on non-200) instead of silently returning '' on auth/rate-limit failures.

#100 — Sitemap information disclosure + robustness (partial)

  • Filters to public (guest) view levels — registered/special-access articles are no longer leaked into the public sitemap.xml.
  • Atomic write (temp file + rename) so concurrent saves can't expose a half-written file.
  • Remaining (noted on the issue): per-save throttling and SEF URLs — both higher-risk and deferred.

#101 — Expose newer columns (CSV + REST API)

  • og_video, event_data, recipe_data, custom_schema added to CSV export/import (appended, so existing CSVs still import) and to the API field whitelist.
  • Import validates the JSON fields as arrays/objects and og_video as http(s) — so a CSV import can't re-introduce the #97 scalar-JSON-LD crash.

#102 — Forward-compat (complete)

  • Factory::getLanguage()getApplication()->getLanguage() (4 sites)
  • Joomla\CMS\Filesystem\File/FolderJoomla\Filesystem\* (ImageHelper, ImageGenerator)
  • Repo now has zero Factory::getLanguage() / Joomla\CMS\Filesystem usages.

#106 — partial

  • loadArticle() caches null misses (array_key_exists) — no more per-call re-query.
  • getArticleDate() skips 0000-00-00 dates.
  • ⏸️ Batch-JS premature halt deferred: BatchController::process() always queries offset 0, so a row that fails to insert is re-fetched forever — the created > 0 guard is what prevents an infinite loop. A safe fix needs cursor-based pagination, out of scope for this batch.

Closes #99, #101, #102.

🤖 Generated with Claude Code

Second batch from the deep-dive audit. 6 files, all `php -l` clean. ## #99 — AI AJAX endpoint hardening (security) - Now requires `core.edit`/`core.create` on `com_content` before generating — previously any authenticated back-end user could trigger outbound **paid** AI calls. - `callAiApi`: 20s timeout + HTTP status check (throws on non-200) instead of silently returning `''` on auth/rate-limit failures. ## #100 — Sitemap information disclosure + robustness (partial) - **Filters to public (guest) view levels** — registered/special-access articles are no longer leaked into the public `sitemap.xml`. - **Atomic write** (temp file + `rename`) so concurrent saves can't expose a half-written file. - Remaining (noted on the issue): per-save throttling and SEF URLs — both higher-risk and deferred. ## #101 — Expose newer columns (CSV + REST API) - `og_video`, `event_data`, `recipe_data`, `custom_schema` added to CSV export/import (**appended**, so existing CSVs still import) and to the API field whitelist. - Import **validates** the JSON fields as arrays/objects and `og_video` as http(s) — so a CSV import can't re-introduce the #97 scalar-JSON-LD crash. ## #102 — Forward-compat (complete) ✅ - `Factory::getLanguage()` → `getApplication()->getLanguage()` (4 sites) - `Joomla\CMS\Filesystem\File/Folder` → `Joomla\Filesystem\*` (ImageHelper, ImageGenerator) - Repo now has **zero** `Factory::getLanguage()` / `Joomla\CMS\Filesystem` usages. ## #106 — partial - ✅ `loadArticle()` caches null misses (`array_key_exists`) — no more per-call re-query. - ✅ `getArticleDate()` skips `0000-00-00` dates. - ⏸️ Batch-JS premature halt deferred: `BatchController::process()` always queries offset 0, so a row that fails to insert is re-fetched forever — the `created > 0` guard is what prevents an infinite loop. A safe fix needs cursor-based pagination, out of scope for this batch. Closes #99, #101, #102. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jmiller added 2 commits 2026-06-29 14:53:23 +00:00
fix: security & correctness batch (#99, #100, #101, #102, #106)
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
71a102028d
#99 — AI AJAX endpoint hardening:
- require core.edit/core.create on com_content before generating (was
  reachable by any authenticated back-end user → paid-credit abuse)
- callAiApi: 20s timeout + HTTP status check (throw on non-200) instead of
  silently returning an empty string

#100 — Sitemap information disclosure + robustness:
- filter to public (guest) view levels so registered/special-access
  articles are never written into the public sitemap
- atomic write (temp file + rename) so concurrent saves can't expose a
  half-written sitemap.xml
- (throttling + SEF URLs remain follow-ups, noted on the issue)

#101 — Expose newer columns in CSV + API:
- og_video, event_data, recipe_data, custom_schema added to CSV export/import
  (appended, so existing CSVs still import) and to the REST API field whitelist
- import validates JSON fields as arrays/objects and og_video as http(s)
  (prevents re-introducing the #97 scalar-JSON-LD crash via import)

#102 — Forward-compat (complete):
- Factory::getLanguage() -> getApplication()->getLanguage() (4 sites)
- Joomla\CMS\Filesystem\File/Folder -> Joomla\Filesystem\* (ImageHelper, ImageGenerator)

#106 — partial: loadArticle() now caches null misses (array_key_exists),
getArticleDate() skips 0000-00-00 dates. Batch-JS halt deferred — the
offset=0 design re-fetches failed rows, so the created>0 guard prevents an
infinite loop; a safe fix needs cursor-based pagination in BatchController.
chore(version): pre-release bump to 01.06.04-dev [skip ci]
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 2s
a60ba86b19
jmiller merged commit 377ae2d39e into dev 2026-06-29 14:53:42 +00:00
jmiller deleted branch fix/security-correctness-batch 2026-06-29 14:53:43 +00:00
Sign in to join this conversation.
No Reviewers
Priority -
Type -
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoSuiteOpenGraph#109