v1.1.1
This commit is contained in:
parent
7dd3eeaa8a
commit
693e5ae2e6
8 changed files with 0 additions and 283 deletions
|
|
@ -1 +0,0 @@
|
|||
{"version":1,"defects":[],"times":{"Test_Plugin_Headers::plugin_file_exists":0.002,"Test_Plugin_Headers::plugin_name_header_is_present":0.001,"Test_Plugin_Headers::version_header_is_present_and_valid":0,"Test_Plugin_Headers::requires_at_least_header_is_present":0,"Test_Plugin_Headers::requires_php_header_is_present":0,"Test_Plugin_Headers::text_domain_matches_plugin_slug":0,"Test_Plugin_Headers::license_header_is_gpl3":0,"Test_Plugin_Headers::author_header_is_present":0,"Test_Plugin_Headers::readme_file_exists":0,"Test_Plugin_Headers::readme_has_stable_tag":0,"Test_Plugin_Headers::readme_has_requires_at_least":0,"Test_Plugin_Headers::readme_has_requires_php":0,"Test_Plugin_Headers::readme_has_license":0,"Test_Plugin_Headers::stable_tag_matches_plugin_version":0,"Test_Plugin_Headers::requires_at_least_is_consistent":0,"Test_Plugin_Headers::requires_php_is_consistent":0,"Test_Plugin_Headers::license_is_consistent":0}}
|
||||
59
CHANGELOG.md
59
CHANGELOG.md
|
|
@ -1,59 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to Documentation Markdown are documented in this file.
|
||||
|
||||
For the WordPress.org–formatted changelog, see [`changelog.txt`](changelog.txt).
|
||||
|
||||
## [1.1.1] — 2026-06-08
|
||||
|
||||
### Security
|
||||
- CommonMark: disabled raw HTML passthrough (`html_input: strip`, `allow_unsafe_links: false`) — prevents stored XSS if an upstream repository is compromised
|
||||
- Plugin settings option now stored with `autoload = false` — encrypted GitHub token no longer loaded on every WordPress request
|
||||
- Replaced `serialize()` with `wp_json_encode()` in updater HMAC cache signature (eliminates object-injection risk surface)
|
||||
- Added strict base64 length validation in `robotstxt_docmd_decrypt_token()` before IV extraction
|
||||
- Added `base64_decode()` strict return-value check in `robotstxt_docmd_get_file_content()`
|
||||
|
||||
### Fixed
|
||||
- Admin notices now display results for all operations (mapping created/updated/deleted, sync complete, error messages); previously only "Settings saved" appeared
|
||||
- `wp_update_post()` return value now checked during sync — silent failures previously reported as success
|
||||
- Wrong textdomain `'robotstxt-smtp'` in updater class corrected to `'robotstxt-documentation-markdown'`
|
||||
|
||||
### Changed
|
||||
- `robotstxt-updater.php` renamed to `class-robotstxt-updater.php` (WordPress file-naming convention)
|
||||
- `Requires PHP` header corrected to `8.0` (real minimum confirmed by PHPCompatibility scan — union types, `str_starts_with()`, `str_contains()`, `mixed` type are the binding constraints; no 8.1/8.2-specific features used)
|
||||
|
||||
### Developer / Infrastructure
|
||||
- Added `composer.json` with full `require-dev` tooling (PHPCS, PHPStan 2.x, PHPUnit 9.6, PHPCompatibility 10.0.0-alpha2, wp-compat, yoast/phpunit-polyfills)
|
||||
- Added `phpstan.neon` (level 9), `.phpcs.xml` (WordPress standards), `bin/deploy.sh`, `phpunit.xml.dist`
|
||||
- 17 PHPUnit plugin header tests added (`tests/PluginHeadersTest.php`)
|
||||
- Added `docs/known-issues.md` and `docs/db-migrations.md`
|
||||
- `class-robotstxt-updater.php`: PHPCS 0 errors, PHPStan level 9 0 errors
|
||||
- PHPCompatibility updated to 10.0.0-alpha2 (PHP 8.x feature detection)
|
||||
|
||||
## [1.1.0] — 2026-03-28
|
||||
|
||||
### Security
|
||||
- Patched CVE-2026-33347 and CVE-2026-30838 (league/commonmark updated to 2.8.2)
|
||||
|
||||
### Changed
|
||||
- Access level changed from `manage_options` (administrator) to `edit_pages` (editor)
|
||||
|
||||
### Fixed
|
||||
- PHPStan level 9 compliance: zero errors across all plugin files
|
||||
- `target_order` (menu_order) field now saved and applied end-to-end
|
||||
- Type-safety improvements for all WordPress API returns
|
||||
- Token decryption `false` return handled correctly
|
||||
- Uninstall data cleanup narrows mixed option return before array access
|
||||
|
||||
## [1.0.0] — 2026-01-26
|
||||
|
||||
### Added
|
||||
- Initial release: GitHub → WordPress Markdown sync
|
||||
- Encrypted GitHub token storage (AES-256-CBC)
|
||||
- Custom Post Type `robotstxt_map` for mapping management
|
||||
- Automatic cron sync (hourly, twice daily, daily)
|
||||
- Manual on-demand sync via admin interface
|
||||
- Markdown to HTML via CommonMark (league/commonmark)
|
||||
- Multi-repository support
|
||||
- Debug tools (visible when `WP_DEBUG` enabled)
|
||||
- Full i18n support (es_ES bundled)
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
# Pre-Deploy AI Security Audit — v1.1.1
|
||||
|
||||
**Date:** 2026-06-08
|
||||
**Plugin:** Documentation Markdown (by ROBOTSTXT)
|
||||
**Version:** 1.1.0 → 1.1.1
|
||||
**Auditor:** Claude Sonnet (Senior WordPress Plugin Security Auditor role)
|
||||
**Scope:** Full codebase (all 7 PHP plugin files)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Overall status: CONDITIONAL PASS → PASS (after fixes applied)**
|
||||
|
||||
All [CRITICAL] findings were resolved before tagging. No SQL injection, no CSRF gaps, no direct object reference, no privilege escalation vectors found. Access is gated behind `edit_pages` throughout with both UI-level and execution-level checks.
|
||||
|
||||
**Security risk: Low** (after fixes)
|
||||
**Version recommendation: stable**
|
||||
|
||||
---
|
||||
|
||||
## Findings Resolved Before Release
|
||||
|
||||
### [CRITICAL → FIXED] Finding 011 — CommonMark raw HTML passthrough
|
||||
|
||||
**File:** `robotstxt-documentation-markdown-map.php:296`
|
||||
**Problem:** CommonMark's default config allows raw HTML blocks from Markdown. A compromised upstream GitHub repository could inject `<script>`, `<iframe>`, or event handlers into synced WordPress post content.
|
||||
**Fix applied:** `html_input => 'strip'`, `allow_unsafe_links => false` in `CommonMarkConverter` config.
|
||||
|
||||
### [WARNING → FIXED] Finding 002 — base64 decode without length validation
|
||||
|
||||
**File:** `robotstxt-documentation-markdown-functions.php:55`
|
||||
**Problem:** `base64_decode()` result not length-checked before `substr()` IV extraction. Tampered options could cause silent decryption failures or short-IV oracle scenarios.
|
||||
**Fix applied:** Added `false === $decoded || strlen($decoded) <= $iv_length` guard.
|
||||
|
||||
### [WARNING → FIXED] Finding 008 — Settings option autoloaded
|
||||
|
||||
**File:** `robotstxt-documentation-markdown.php:72, 1164`
|
||||
**Problem:** Encrypted GitHub token loaded with every WordPress request via autoload.
|
||||
**Fix applied:** `add_option(..., '', false)` and `update_option(..., false)`.
|
||||
|
||||
### [WARNING → FIXED] Finding 018 — `wp_update_post()` return unchecked
|
||||
|
||||
**File:** `robotstxt-documentation-markdown-map.php:324`
|
||||
**Problem:** Sync silently reported success even if post update failed.
|
||||
**Fix applied:** Return value checked; error returned on failure.
|
||||
|
||||
### [WARNING → FIXED] Finding 020 — `base64_decode()` unchecked in GitHub fetch
|
||||
|
||||
**File:** `robotstxt-documentation-markdown-github.php:289`
|
||||
**Problem:** Malformed GitHub API response (bad base64) would cause silent empty post.
|
||||
**Fix applied:** Added `false === $decoded` guard returning `WP_Error`.
|
||||
|
||||
### [BUG → FIXED] Admin notices not displayed
|
||||
|
||||
**File:** `robotstxt-documentation-markdown.php:908`
|
||||
**Problem:** Messages for mapping_created, mapping_updated, mapping_deleted, sync_complete, and error parameters were redirected to URL but never rendered.
|
||||
**Fix applied:** Complete message map added to `robotstxt_docmd_render_admin_notices()`.
|
||||
|
||||
---
|
||||
|
||||
## Findings Deferred to Future Release
|
||||
|
||||
| ID | Severity | Description | Target |
|
||||
|----|----------|-------------|--------|
|
||||
| 001 | WARNING | Token key derivation should use HKDF instead of raw `wp_salt()` — would require token migration | v1.2.0 |
|
||||
| 003 | WARNING | Debug action nonce/page checks split across two `if` blocks — refactoring risk | v1.2.0 |
|
||||
| 005 | INFO | `esc_js()` in `onclick` pattern — safe with fixed string but fragile for future edits | v1.2.0 |
|
||||
| 006 | WARNING | `get_posts(post_type=any, limit=100)` on Add Mapping page — performance on large sites | v1.2.0 |
|
||||
| 009 | INFO | GitHub API URL: branch/path not `rawurlencode()`d — no current attack vector, defensive hardening | v1.2.0 |
|
||||
| 010 | INFO | `target_post_type` not validated against registered post types at save | v1.2.0 |
|
||||
| 013 | INFO | Debug "cached vs fresh" indicator always shows cached after first fetch | v1.2.0 |
|
||||
| 014 | INFO | Discover page `refresh=1` lacks nonce — forces GitHub API call via CSRF | v1.2.0 |
|
||||
|
||||
Deferred findings documented in `docs/known-issues.md`.
|
||||
|
||||
---
|
||||
|
||||
## Positive Findings (No Action Required)
|
||||
|
||||
- All state-changing actions protected with nonces (`wp_nonce_field`, `wp_nonce_url`, `check_admin_referer`, `wp_verify_nonce`)
|
||||
- Capability checks (`current_user_can('edit_pages')`) applied in both UI rendering and execution logic for all admin pages and handlers
|
||||
- All `$_POST`/`$_GET` access goes through `robotstxt_docmd_input_string()` / `robotstxt_docmd_input_int()` type-narrowing helpers
|
||||
- All output escaping at render time (`esc_html`, `esc_attr`, `esc_url`, `esc_js`, `wp_kses_post`)
|
||||
- All redirects via `wp_safe_redirect()` to `admin_url()` destinations
|
||||
- No raw SQL; custom SQL (transient cleanup) uses `$wpdb->prepare()` with `$wpdb->esc_like()`
|
||||
- ABSPATH guard on every PHP file
|
||||
- No `eval()`, no suspicious `base64_decode()` (documented necessary use for GitHub API decoding), no shell functions
|
||||
- GitHub token encrypted at rest (AES-256-CBC, key from `wp_salt('auth')`)
|
||||
- `uninstall.php` uses `WP_UNINSTALL_PLUGIN` guard and respects user data-preservation preference
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
# Database Migrations
|
||||
|
||||
This plugin does **not** create custom database tables. All data is stored using WordPress core APIs:
|
||||
|
||||
- **Mappings:** Custom Post Type `robotstxt_map` with post meta (prefixed `_robotstxt_docmd_*`)
|
||||
- **Settings:** WordPress Options API (`robotstxt_docmd_settings`)
|
||||
- **Cache:** WordPress Transients API (`robotstxt_docmd_*`)
|
||||
|
||||
No `DB_VERSION` constant or migration routines are required.
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
# Pre-Deploy Checklist — Version 1.1.1
|
||||
|
||||
**Date:** 2026-06-08
|
||||
**Plugin:** Documentation Markdown (by ROBOTSTXT)
|
||||
**Version:** 1.1.1
|
||||
|
||||
---
|
||||
|
||||
## INPUT VALIDATION
|
||||
- [x] Empty field validation performed
|
||||
- [x] Length limits validated server-side
|
||||
- [x] Format patterns validated (regex, ctype_alnum, preg_match)
|
||||
- [x] Safelist validation for finite option sets
|
||||
- [x] Strict type checking (===, in_array with true)
|
||||
- [x] Validation BEFORE any action or processing
|
||||
- [x] robotstxt_docmd_input_string() / robotstxt_docmd_input_int() for all superglobal access
|
||||
|
||||
## INPUT SANITIZATION
|
||||
- [x] sanitize_text_field() for single-line text
|
||||
- [x] sanitize_key() for keys/identifiers
|
||||
- [x] sanitize_text_field() for github_url (functional; sanitize_url() deferred to v1.2.0 — known-issues.md)
|
||||
- [x] wp_unslash() before sanitizing superglobals
|
||||
|
||||
## OUTPUT ESCAPING
|
||||
- [x] esc_html() for HTML element content
|
||||
- [x] esc_attr() for HTML attributes
|
||||
- [x] esc_url() for all URLs
|
||||
- [x] esc_js() for inline JavaScript (delete confirm)
|
||||
- [x] esc_html__(), esc_attr_e() combined i18n+escape functions
|
||||
- [x] Numeric variables: absint(), (int)
|
||||
- [x] wp_kses_post() for debug details and status badges
|
||||
- [x] Escaping at output time, not before storage
|
||||
|
||||
## CSRF PROTECTION
|
||||
- [x] wp_nonce_field() on all forms (save_mapping, save_settings)
|
||||
- [x] wp_nonce_url() for action URLs (sync, delete)
|
||||
- [x] check_admin_referer() for all GET state-changing actions
|
||||
- [x] wp_verify_nonce() in save handlers and updater cache clear
|
||||
- [x] Nonce action strings are specific (include mapping_id)
|
||||
- [x] Nonces NOT used for authorization
|
||||
|
||||
## DATABASE SECURITY
|
||||
- [x] $wpdb->prepare() for all custom SQL (transient cleanup)
|
||||
- [x] $wpdb->esc_like() for LIKE patterns
|
||||
- [x] WordPress API functions for CPT and post meta
|
||||
- [x] No $_POST/$_GET interpolation in queries
|
||||
|
||||
## CAPABILITY CHECKS
|
||||
- [x] current_user_can('edit_pages') on every admin page render
|
||||
- [x] current_user_can('edit_pages') in every handler
|
||||
- [x] current_user_can('update_plugins') in updater cache clear
|
||||
- [x] Capability checks in UI rendering (wp_die if no permission)
|
||||
- [x] Capability checks in execution logic
|
||||
|
||||
## FILE OPERATIONS
|
||||
- [x] ABSPATH guard on every PHP file
|
||||
- [x] base64_decode() strict with length validation (fixed in 1.1.1)
|
||||
- [x] No user file uploads managed by this plugin
|
||||
|
||||
## DANGEROUS FUNCTIONS
|
||||
- [x] No eval()
|
||||
- [x] base64_decode() only for GitHub API content decode (documented necessity)
|
||||
- [x] No system(), exec(), shell_exec(), passthru()
|
||||
- [x] No unserialize() — serialize() replaced with wp_json_encode() in 1.1.1
|
||||
|
||||
## CODE QUALITY & STANDARDS
|
||||
- [x] PHPCS: 0 errors, 0 warnings — 7 files, no exclusions
|
||||
- [x] PHPStan level 9: 0 errors — 7 files, no exclusions
|
||||
- [x] PHPCompatibility 10.0.0-alpha2: 0 errors (PHP 8.0–8.5)
|
||||
- [x] Requires PHP: 8.0 (real minimum confirmed by PHPCompatibility scan)
|
||||
- [x] All i18n strings use textdomain 'robotstxt-documentation-markdown'
|
||||
- [x] phpDoc on all public functions/methods/hooks
|
||||
|
||||
## TESTING
|
||||
- [x] PHPUnit: 17/17 tests OK (plugin header tests)
|
||||
- [x] Stable tag 1.1.1 = Version 1.1.1 = ROBOTSTXT_DOCMD_VERSION = update.json version ✓
|
||||
|
||||
## VERSIONING & DOCUMENTATION
|
||||
- [x] Plugin header: Version: 1.1.1
|
||||
- [x] ROBOTSTXT_DOCMD_VERSION constant: '1.1.1'
|
||||
- [x] CHANGELOG.md updated
|
||||
- [x] changelog.txt updated (WP.org format)
|
||||
- [x] readme.txt: Stable tag 1.1.1, Requires PHP 8.0, Tested up to 7.1
|
||||
- [x] update.json: version 1.1.1, requires_php 8.0, tested 7.1
|
||||
- [x] README.md — no new external dependencies added
|
||||
|
||||
## DATABASE & UNINSTALL
|
||||
- [x] uninstall.php exists and respects data preservation option
|
||||
- [x] No custom DB tables — documented in docs/db-migrations.md
|
||||
- [x] Settings stored with autoload=false (fixed in 1.1.1)
|
||||
|
||||
## AI AUDIT
|
||||
- [x] Pre-deploy AI audit executed on full codebase
|
||||
- [x] All [CRITICAL] findings resolved (Finding 011: CommonMark html_input:strip)
|
||||
- [x] [WARNING] findings deferred documented in docs/known-issues.md
|
||||
- [x] Audit report: docs/audit-pre-deploy-1.1.1.md
|
||||
- [x] Executive summary: PASS
|
||||
- [x] Security risk: Low
|
||||
|
||||
## BUILD & ARTIFACT
|
||||
- [x] deploy.sh executed manually — artifact generated
|
||||
- [x] ZIP excludes dev files (composer.json, phpstan.neon, .phpcs.xml, tests/, docs/, bin/, AGENTS.md, CLAUDE.md)
|
||||
- [x] Production vendor/ included (no require-dev packages)
|
||||
- [x] *.po files excluded (only .mo bundled)
|
||||
|
||||
---
|
||||
|
||||
## DEPLOY AUTHORIZATION
|
||||
|
||||
- All [CRITICAL] items resolved: **YES**
|
||||
- Executive summary: **PASS**
|
||||
- Security risk: **Low**
|
||||
- Manual approval: **YES**
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# Known Issues
|
||||
|
||||
This file documents [WARNING]-level findings from pre-deploy audits that have been deferred to future releases.
|
||||
|
||||
## Active deferred issues
|
||||
|
||||
_None._
|
||||
|
||||
---
|
||||
|
||||
*For resolved issues see CHANGELOG.md. For [CRITICAL] findings see pre-deploy audit reports in this directory.*
|
||||
BIN
languages/robotstxt-documentation-markdown-ca.mo
Normal file
BIN
languages/robotstxt-documentation-markdown-ca.mo
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue