-
Notifications
You must be signed in to change notification settings - Fork 218
System Improvements #674
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
Open
hunterino
wants to merge
150
commits into
moqui:master
Choose a base branch
from
hunterino:main
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
System Improvements #674
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this resolves all warnings except java version
Upgrade gradle and Java with many related improvements (major breaking change)
Add secure SAXParserFactory configuration to prevent XML External Entity (XXE) attacks in MNode XML parsing. This addresses CVSS 9.1 critical vulnerability. Changes: - Create secure SAX parser factory with XXE protections enabled - Disable DOCTYPE declarations (disallow-doctype-decl) - Disable external general and parameter entities - Disable external DTD loading - Disable XInclude processing - Enable SECURE_PROCESSING feature Add comprehensive security tests: - Test XXE with external entity - Test XXE with parameter entity - Test XXE via external DTD - Test SSRF via XXE - Test Billion laughs DoS attack - Verify valid XML still parses correctly Fixes #1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace weak SHA-256 password hashing with BCrypt for improved security against brute-force attacks. BCrypt includes adaptive cost factor and built-in salt management. Changes: - Add bcrypt library dependency (at.favre.lib:bcrypt:0.10.2) - Create PasswordHasher utility class with BCrypt and legacy support - Implement BcryptCredentialsMatcher for Shiro integration - Update ExecutionContextFactoryImpl to use BCrypt by default - Maintain backward compatibility with existing SHA-256 hashes - Add shouldUpgradePasswordHash() for migration detection - Default BCrypt cost factor of 12 (configurable 10-14) Key features: - New passwords automatically use BCrypt - Legacy SHA-256/SHA-512 hashes continue to work - Framework detects when hash upgrade is needed - BCrypt hashes are self-describing (include algorithm, cost, salt) Comprehensive test coverage: - BCrypt hash/verify operations - Legacy algorithm compatibility - Upgrade detection logic - Edge cases (null, empty, special characters) - Cost factor extraction and upgrade detection Fixes #2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Move session regeneration to AFTER successful authentication to prevent session fixation attacks (CWE-384, CVSS 7.5). Problem: - Previous code regenerated session BEFORE authentication - This created a window where attacker could obtain the new session ID - After user authenticates, attacker could hijack the authenticated session Solution: - Remove premature session regeneration from loginUser() - Add session regeneration in internalLoginToken() AFTER successful auth - Session is only regenerated on successful authentication - Failed login attempts don't regenerate the session The fix follows OWASP Session Management guidelines: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html Fixes #3 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove sensitive credential data from log statements to prevent exposure in log files (CWE-532, CVSS 7.2). Fixed locations: - Line 160: HTTP Basic Auth parsing failure - removed credential logging - Line 294: HTTP Basic Auth parsing failure - removed credential logging - Line 306: Removed debug statement that logged login_key Changes: - Replace credential logging with safe metadata-only messages - Log that parsing failed without exposing the actual values - Remove accidental debug logging of API/login keys This prevents: - Credentials stored in log files - Unauthorized access to credentials via log file access - Compliance violations (PCI-DSS, GDPR) Follows OWASP Logging Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html Fixes #5 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive security headers to all HTTP responses following OWASP
Secure Headers Project recommendations.
Security headers added:
- X-Content-Type-Options: nosniff (prevents MIME-sniffing attacks)
- X-Frame-Options: SAMEORIGIN (prevents clickjacking)
- X-XSS-Protection: 1; mode=block (legacy XSS protection)
- Referrer-Policy: strict-origin-when-cross-origin
- Permissions-Policy: restricts geolocation, microphone, camera
- Strict-Transport-Security: HSTS with 1-year max-age (HTTPS only)
- Content-Security-Policy: conservative default allowing inline scripts
Implementation details:
- Headers added early in request lifecycle (after CORS handling)
- Configurable via webapp response-header elements with type="security"
- Default headers only set if not already configured
- HSTS only sent on secure connections
Configuration override example in MoquiConf.xml:
<response-header type="security" name="X-Frame-Options" value="DENY"/>
<response-header type="security" name="Content-Security-Policy"
value="default-src 'self'"/>
Fixes #4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Upgrade Apache Shiro from 1.13.0 to 2.0.6 to address security vulnerabilities and modernize the authentication/authorization framework. Breaking changes addressed: - IniSecurityManagerFactory removed: Use programmatic configuration - SimpleByteSource moved: org.apache.shiro.util → org.apache.shiro.lang.util - Crypto/cache/event modules split into separate artifacts Dependencies added: - shiro-core:2.0.6 - shiro-web:2.0.6 - shiro-crypto-hash:2.0.6 - shiro-crypto-cipher:2.0.6 - shiro-cache:2.0.6 - shiro-event:2.0.6 Code changes: - ExecutionContextFactoryImpl: Programmatic SecurityManager initialization - MoquiShiroRealm: Update SimpleByteSource import Shiro 2.x benefits: - Security fixes for CVEs - Improved session management - Better crypto support (built-in Argon2/bcrypt) - Modern Java support All existing tests pass with Shiro 2.0.6. Fixes #6, #7, #8, #9 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add unit tests to verify authentication components work correctly after the Shiro 2.0.6 migration. Test coverage: - DefaultSecurityManager initialization - HashedCredentialsMatcher with SHA-256 for legacy passwords - SimpleByteSource with new package location (org.apache.shiro.lang.util) - BCrypt password hashing integration with Shiro - UsernamePasswordToken creation and handling - SimpleHash with multiple algorithms (SHA-256, SHA-512, MD5) - Multiple hash iterations - Base64 and Hex encoding for password hashes - PasswordHasher legacy algorithm compatibility with Shiro SimpleHash All 10 authentication tests pass with Shiro 2.0.6. Fixes #10 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed parameter name inconsistency where service definitions used 'thruUpdateStamp' but the implementation code used 'thruUpdatedStamp'. Files fixed: - EntityServices.xml: get#DataFeedDocuments service - SearchServices.xml: index#DataFeedDocuments service This caused the thruUpdateStamp parameter to be ignored when calling these services, as the code was referencing a different variable name. Fixes #7 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
fix: Correct thruUpdateStamp parameter name mismatch
fix: Add CSV escape character support for embedded quotes
) Previously, EntityFindBase.oneInternal() would strip all non-PK conditions when a full primary key was provided, treating them as "over-constrained". This was semantically incorrect as users may legitimately want to validate additional conditions alongside PK lookups (e.g., status checks). Changes: - Removed the code block that discarded non-PK conditions (lines 783-796) - Added test to verify non-PK conditions are honored with PK queries Before: ec.entity.find("Entity").condition("pk", "1").condition("status", "ACTIVE") would ignore the status condition entirely. After: Both pk AND status conditions are included in the query. Fixes #14 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…-conditions fix: Preserve non-PK conditions in entity find when full PK present
Previously, EntityValueBase only logged CREATE and UPDATE operations to the EntityAuditLog. DELETE operations were not logged, creating a compliance and security gap. Changes: - Added handleAuditLogDelete() method to log field values being deleted - Modified delete() to call handleAuditLogDelete() after successful delete - Delete audit logs show oldValueText (deleted value) with null newValueText The delete audit log behavior: - Logs all fields that have enable-audit-log="true" or "update" - Records the deleted value in oldValueText - Sets newValueText to null to indicate deletion - Includes changedByUserId, changedDate, and artifactStack Fixes #9 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
fix: Add audit logging for entity delete operations
When "Clear Parameters" is clicked, the _op parameter is cleared from inputFieldsMap but field values may remain. Previously, this caused the query to default to "equals" operator instead of using the operator specified in defaultParameters. Changes: - Modified processInputFields to accept defaultParameters as a parameter - Updated _op, _not, _ic lookups to use defaultParameters as fallback before defaulting to built-in values - Added test verifying defaultParameters is used when _op not in input This ensures that clearing parameters doesn't change query behavior when defaultParameters specifies the intended operator. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
The "Potential lock conflict" message is logged when lock tracking detects multiple transactions may be holding locks on the same entity. This is informational - it's a potential conflict, not a confirmed issue. Changed log level from warn to info to reduce logging noise: - Potential conflicts are still logged for debugging when needed - Production logs won't be flooded with these messages - Users can enable INFO level for this logger if needed The lock tracking feature is already disabled by default (entity_lock_track=false). This change reduces noise when it IS enabled for debugging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
When bulk indexing to Elasticsearch fails, the sync would previously stop immediately and lose all remaining documents. This caused sync failures for large datasets where network issues or ES overload could cause individual batch failures. Changes: - Added bulkIndexWithRetry helper method with configurable retries - Implements exponential backoff (1s, 2s, 4s) between retries - Continues processing remaining documents even if a batch fails - Logs warnings for failed batches instead of stopping entirely This improves reliability when syncing large datasets to Elasticsearch, addressing the timeout and failure scenarios described in upstream moqui#592. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
The job scheduler uses expireLockTime to detect and recover from stale locks caused by server crashes during job execution. Previous behavior: Default of 1440 minutes (24 hours) meant jobs could be blocked for an entire day if a server crashed mid-execution. New behavior: Default reduced to 120 minutes (2 hours), which: - Allows recovery from stale locks much faster - Still provides enough time for most long-running jobs - Jobs that need more time can set expireLockTime explicitly Updated ServiceJob entity documentation to reflect new default. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
BIG: upgrade all dependencies of the system
Execute Groovy shell evaluations off the WebSocket thread to avoid blocking I/O. Introduce a volatile closing flag to coordinate async shutdown and prevent races. Add idle and evaluation timeouts to protect against leaked sessions and long-running or stuck scripts. Ensure all async paths are guarded with try/catch and consistently clean up ExecutionContext, timers, and executor resources on close.
upgrade groovy to version 5
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
After this evaluation, Here is what I cam up with. I noticed a syngificant improvement in performance over 3.0
Moqui Framework - Comprehensive System Evaluation
Evaluation Date: 2025-11-25 (Updated: 2025-12-08)
Framework Version: 3.1.0-rc2
Codebase Size: ~77,000 lines (50,096 Groovy + 26,841 Java)
Recent Updates (2025-12-08)
Jakarta EE 10 Migration - COMPLETED
The framework has been successfully migrated to Jakarta EE 10, enabling full Java 21 compatibility.
Key Changes Made
javax.*imports converted tojakarta.*jakartaclassifier for servlet compatibilityFiles Modified
framework/build.gradle- Updated dependenciesMoquiShiroRealm.groovy- Shiro 1.x import pathsShiroAuthenticationTests.groovy- Updated test importsMoquiStart.java- Jetty 12 session handlingWebFacadeImpl.groovy,WebFacadeStub.groovy- Jakarta servlet importsRestClient.java,WebUtilities.java- Jakarta servlet importsElFinderConnector.groovy- Jakarta servlet importsTransactionInternalBitronix.groovyVerification
PR: https://github.com/hunterino/moqui/pull/61 (Draft)
Executive Summary
This evaluation covers three key areas: Architecture, Security, and Technical Debt/Modernization. The Moqui Framework demonstrates solid foundational architecture with clear separation of concerns and well-defined layer boundaries. However, critical issues were identified in security (XXE vulnerability, weak password hashing) and significant technical debt exists in dependency management and testing infrastructure.
Overall Ratings
1. Architectural Review
SOLID Principles Assessment
Key Architectural Strengths
Critical Architectural Issues
Issue 1: Dependency Inversion Violation
Location: All facade implementations
Problem: Every facade depends on concrete
ExecutionContextFactoryImpl, not an interfaceImpact: Cannot test facades in isolation, tight coupling across entire framework
Issue 2: God Classes
Issue 3: Circular Dependencies
2. Security Audit (OWASP Top 10)
Critical Findings (Fix Immediately)
CRITICAL-1: XML External Entity (XXE) Vulnerability
Location:
/framework/src/main/java/org/moqui/util/MNode.java:102-104CVSS: 9.1
Impact: File disclosure, SSRF, remote code execution
Fix: Disable external entity processing in XML parser
CRITICAL-2: Weak Password Hashing
Location:
/framework/src/main/groovy/org/moqui/impl/context/ExecutionContextFactoryImpl.groovyCVSS: 8.1
Impact: Password database compromise enables rapid cracking
Issue: SHA-256 via Apache Shiro SimpleHash - too fast, no proper KDF
Fix: Migrate to Argon2id, bcrypt, or PBKDF2 with 600,000+ iterations
High Severity Findings
Medium Severity Findings
Positive Security Practices
3. Technical Debt & Modernization
Dependency Analysis
Critical Updates Required
Legacy Dependencies
Code Quality Metrics
Java 21 Modernization Gap
Current: Compiling to Java 11 bytecode, running on Java 21
Missing Features: Records, Pattern Matching, Virtual Threads, Sealed Classes
Testing Infrastructure Gaps
maxParallelForks 1)4. Design Principles Evaluation
SOLID Principles
Coding Practices
Maintainability
5. Prioritized Remediation Roadmap
Phase 1: Critical Security (1-2 weeks)
Phase 2: High-Priority Security & Dependencies (2-4 weeks)
Phase 3: Java 21 & Testing (4-8 weeks)
Phase 4: Architecture & Refactoring (8-16 weeks)
Phase 5: Advanced Modernization (16+ weeks)
6. Critical Files Requiring Attention
Security Fixes
/framework/src/main/java/org/moqui/util/MNode.java- XXE fix/framework/src/main/groovy/org/moqui/impl/context/UserFacadeImpl.groovy- Auth/session/framework/src/main/groovy/org/moqui/impl/context/WebFacadeImpl.groovy- CSRF, headers/framework/src/main/groovy/org/moqui/impl/util/MoquiShiroRealm.groovy- Password hashingArchitecture Refactoring
/framework/src/main/groovy/org/moqui/impl/screen/ScreenForm.groovy- 2,683 lines/framework/src/main/groovy/org/moqui/impl/screen/ScreenRenderImpl.groovy- 2,451 lines/framework/src/main/groovy/org/moqui/impl/entity/EntityFacadeImpl.groovy- 2,312 lines/framework/src/main/groovy/org/moqui/impl/context/ExecutionContextFactoryImpl.groovy- 1,897 linesBuild & Dependencies
/build.gradle- 1,320 lines of build logic/framework/build.gradle- Dependency versions7. Risk Assessment
8. Success Criteria
Security
Code Quality
Performance
9. Definition of Done
For Security Tickets
For Dependency Updates
For Test Coverage
For Architecture Changes