Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ jobs:
id: stan
run: |
set +e
vendor/bin/phpstan analyse --error-format=json --no-progress > phpstan.json 2>&1
vendor/bin/phpstan analyse --error-format=json --no-progress > phpstan.json
EXIT_CODE=$?

# Also run for GitHub format
vendor/bin/phpstan analyse --error-format=github --no-progress 2>&1 || true
vendor/bin/phpstan analyse --error-format=github --no-progress || true

ERRORS=$(jq '.totals.file_errors // 0' phpstan.json 2>/dev/null || echo "0")
echo "errors=${ERRORS}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -181,11 +181,11 @@ jobs:
id: psalm
run: |
set +e
vendor/bin/psalm --output-format=json --show-info=false > psalm.json 2>&1
vendor/bin/psalm --output-format=json --show-info=false > psalm.json
EXIT_CODE=$?

# Generate SARIF for GitHub Security
vendor/bin/psalm --output-format=sarif --show-info=false > psalm.sarif 2>&1 || true
vendor/bin/psalm --output-format=sarif --show-info=false > psalm.sarif || true

ERRORS=$(jq 'length' psalm.json 2>/dev/null || echo "0")
echo "errors=${ERRORS}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -242,11 +242,10 @@ jobs:
id: fmt
run: |
set +e
OUTPUT=$(vendor/bin/pint --test --format=json 2>&1)
vendor/bin/pint --test --format=json > pint.json
EXIT_CODE=$?
echo "$OUTPUT" > pint.json

FILES=$(echo "$OUTPUT" | jq '.files | length' 2>/dev/null || echo "0")
FILES=$(jq '.files | length' pint.json 2>/dev/null || echo "0")
echo "files=${FILES}" >> $GITHUB_OUTPUT

if [ $EXIT_CODE -eq 0 ]; then
Expand Down
35 changes: 35 additions & 0 deletions AUDIT-AUTH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Security Audit: Authentication & Authorization

## Authentication Review

### Password Handling
- **Hashing Algorithm:** The application utilizes a custom hashing solution, `LthnHash`, which is explicitly documented as **not suitable for password hashing**. A `grep` search for `password_hash` returned no results, indicating that the application is not using the standard, secure password hashing functions provided by PHP. This represents a critical security vulnerability.
- **Salt Usage:** The `LthnHash` implementation uses a deterministic "salt" generation method, which is not suitable for password hashing. A random salt should be generated for each password.
- **Password Requirements:** No evidence of password complexity requirements was found during this audit.
- **Reset Flow Security:** The password reset flow could not be located and audited.

### Session Management
- **Session Configuration:** The `config/session.php` file is missing from the repository. While the application uses Laravel's session helpers (`config('session.driver')`), the absence of the configuration file means the application is relying on default, potentially insecure, session settings.
- **Session ID Generation:** Without the configuration file, it is not possible to verify the security of the session ID generation.
- **Session Fixation Protection:** It is not possible to confirm that session fixation protection is enabled.
- **Timeout Policies:** Session lifetime and timeout policies cannot be audited.
- **Concurrent Session Handling:** The handling of concurrent sessions cannot be determined.

### Token Security
- **Token Management:** The application uses a decentralized token management strategy. The `MakePlugCommand` command generates "Plugs" that use the `ManagesTokens` trait to handle their own tokens. This means that token security is not centralized, and each "Plug" is responsible for its own token storage, refresh, and revocation.
- **JWT Implementation:** No evidence of JWT implementation was found.
- **Token Storage:** The token storage mechanism is not defined in the `ManagesTokens` trait. It is up to the individual "Plug" to implement token storage. This could lead to inconsistent and insecure token storage practices.
- **Refresh Token Rotation:** Refresh token rotation is not handled by the `ManagesTokens` trait.
- **Token Revocation:** Token revocation is not handled by the `ManagesTokens` trait.

### Multi-factor
- **MFA Implementation:** No evidence of a multi-factor authentication system was found in the codebase.
- **Bypass Vulnerabilities:** Not applicable.
- **Recovery Codes:** Not applicable.

## Authorization Review
- **Access Control Model:** The application uses a custom "action whitelisting" system implemented in the `Core\Bouncer\Gate` directory. This system acts as a pre-authorization layer that checks if a controller action is explicitly permitted before it is executed. It is designed to work in conjunction with Laravel's standard Gate/Policy system.
- **Permission Checks:** Permission checks are centralized in the `ActionGateService`. The `ActionGateMiddleware` intercepts incoming requests and uses the `ActionGateService` to verify that the requested action is on the whitelist.
- **Privilege Escalation:** The risk of privilege escalation is mitigated by the "default-deny" nature of the action whitelisting system. However, the security of this system depends on the proper configuration and maintenance of the whitelist.
- **API Authorization:** The `guarded_middleware` configuration in `config/core.php` indicates that the action gate is applied to `api` routes, but a full audit of all API endpoints is required to ensure complete protection.
- **Resource Ownership:** No evidence of resource ownership checks (to prevent IDOR vulnerabilities) was found in the `Core\Bouncer\Gate` system. This is likely handled by the underlying Laravel Gate/Policy system, which could not be audited.
Loading