Add comprehensive security audit (86 findings across 10 areas)
Secure dev auth with signed tokens, add email support for --user Simplify breakpoint variables, suppress Sass deprecation warnings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ namespace App\RSpade\Commands\Rsx;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Process\Process;
|
||||
use App\RSpade\Core\Debug\Debugger;
|
||||
use App\RSpade\Core\Models\Login_User_Model;
|
||||
|
||||
/**
|
||||
* RSX Route Debug Command
|
||||
@@ -29,7 +30,7 @@ use App\RSpade\Core\Debug\Debugger;
|
||||
* 6. Rotates logs again after test for clean slate on next run
|
||||
*
|
||||
* KEY FEATURES:
|
||||
* - Backdoor authentication: Use --user-id to bypass login and test as any user
|
||||
* - Backdoor authentication: Use --user with ID or email to bypass login
|
||||
* - Plain text error output: Errors returned as plain text with stack traces
|
||||
* - Console capture: JavaScript errors and logs captured (--console for all)
|
||||
* - XHR/fetch tracking: Monitor API calls with --xhr-dump or --xhr-list
|
||||
@@ -55,7 +56,8 @@ use App\RSpade\Core\Debug\Debugger;
|
||||
*
|
||||
* USAGE EXAMPLES:
|
||||
* php artisan rsx:debug /dashboard # Basic route test
|
||||
* php artisan rsx:debug /dashboard --user-id=1 # Test as user ID 1
|
||||
* php artisan rsx:debug /dashboard --user=1 # Test as user ID 1
|
||||
* php artisan rsx:debug /dashboard --user=admin@test.com # Test as user by email
|
||||
* php artisan rsx:debug /api/users --no-body # Headers only
|
||||
* php artisan rsx:debug /login --full # Maximum information
|
||||
* php artisan rsx:debug /api/data --xhr-list # Simple XHR list
|
||||
@@ -127,8 +129,7 @@ class Route_Debug_Command extends Command
|
||||
protected $signature = 'rsx:debug
|
||||
{url? : The URL to debug (e.g., /dashboard, /api/users). Use --examples to see usage examples}
|
||||
{--examples : Show comprehensive usage examples}
|
||||
{--user= : Test as specific user ID (bypasses authentication)}
|
||||
{--user-id= : Alias for --user option}
|
||||
{--user= : Test as specific user ID or email (bypasses authentication)}
|
||||
{--log : Display Laravel error log if not empty}
|
||||
{--no-body : Suppress HTTP response body (show headers/status only)}
|
||||
{--follow-redirects : Follow HTTP redirects and show full redirect chain}
|
||||
@@ -212,9 +213,15 @@ class Route_Debug_Command extends Command
|
||||
$url = '/' . $url;
|
||||
}
|
||||
|
||||
// Get user ID from options
|
||||
$user_id = $this->option('user-id') ?: $this->option('user');
|
||||
|
||||
// Get user ID from options (accepts ID or email)
|
||||
$user_id = $this->option('user');
|
||||
if ($user_id !== null) {
|
||||
$user_id = $this->resolve_user($user_id);
|
||||
if ($user_id === null) {
|
||||
return 1; // Error already displayed
|
||||
}
|
||||
}
|
||||
|
||||
// Get log flag
|
||||
$show_log = $this->option('log');
|
||||
|
||||
@@ -373,11 +380,22 @@ class Route_Debug_Command extends Command
|
||||
}
|
||||
}
|
||||
|
||||
// Generate signed request token for user/site context
|
||||
// This prevents unauthorized requests from hijacking sessions via headers
|
||||
$dev_auth_token = null;
|
||||
if ($user_id) {
|
||||
$dev_auth_token = $this->generate_dev_auth_token($url, $user_id);
|
||||
}
|
||||
|
||||
// Build command arguments
|
||||
$command_args = ['node', $playwright_script, $url];
|
||||
|
||||
|
||||
if ($user_id) {
|
||||
$command_args[] = "--user-id={$user_id}";
|
||||
$command_args[] = "--user={$user_id}";
|
||||
}
|
||||
|
||||
if ($dev_auth_token) {
|
||||
$command_args[] = "--dev-auth-token={$dev_auth_token}";
|
||||
}
|
||||
|
||||
if ($show_log) {
|
||||
@@ -539,7 +557,7 @@ class Route_Debug_Command extends Command
|
||||
|
||||
$this->comment('AUTHENTICATION:');
|
||||
$this->line(' php artisan rsx:debug /admin --user=1 # Test as user ID 1');
|
||||
$this->line(' php artisan rsx:debug /profile --user-id=5 # Alternative syntax');
|
||||
$this->line(' php artisan rsx:debug /admin --user=admin@example.com # Test as user by email');
|
||||
$this->line('');
|
||||
|
||||
$this->comment('TESTING RSX JAVASCRIPT:');
|
||||
@@ -619,4 +637,70 @@ class Route_Debug_Command extends Command
|
||||
$this->line(' • For more details on console_debug: php artisan rsx:man console_debug');
|
||||
$this->line(' • For config options: php artisan rsx:man config_rsx');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve user identifier to user ID
|
||||
*
|
||||
* Accepts either a numeric user ID or an email address.
|
||||
* Validates that the user exists in the database.
|
||||
*
|
||||
* @param string $user_input User ID or email address
|
||||
* @return int|null User ID or null if not found (error already displayed)
|
||||
*/
|
||||
protected function resolve_user(string $user_input): ?int
|
||||
{
|
||||
// Check if input is an email address
|
||||
if (str_contains($user_input, '@')) {
|
||||
$login_user = Login_User_Model::find_by_email($user_input);
|
||||
if (!$login_user) {
|
||||
$this->error("User not found: {$user_input}");
|
||||
return null;
|
||||
}
|
||||
return $login_user->id;
|
||||
}
|
||||
|
||||
// Input is a user ID - validate it exists
|
||||
if (!ctype_digit($user_input)) {
|
||||
$this->error("Invalid user identifier: {$user_input} (must be numeric ID or email address)");
|
||||
return null;
|
||||
}
|
||||
|
||||
$user_id = (int) $user_input;
|
||||
$login_user = Login_User_Model::find($user_id);
|
||||
if (!$login_user) {
|
||||
$this->error("User ID not found: {$user_id}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a signed dev auth token for Playwright requests
|
||||
*
|
||||
* The token is an HMAC signature of the request parameters using APP_KEY.
|
||||
* This ensures that only requests originating from rsx:debug (which has
|
||||
* access to APP_KEY) can authenticate as different users.
|
||||
*
|
||||
* @param string $url The URL being tested
|
||||
* @param int $user_id The user ID to authenticate as
|
||||
* @return string The signed token
|
||||
*/
|
||||
protected function generate_dev_auth_token(string $url, int $user_id): string
|
||||
{
|
||||
$app_key = config('app.key');
|
||||
if (!$app_key) {
|
||||
$this->error("APP_KEY not configured - cannot generate dev auth token");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create payload with request parameters
|
||||
$payload = json_encode([
|
||||
'url' => $url,
|
||||
'user_id' => $user_id,
|
||||
]);
|
||||
|
||||
// Sign with HMAC-SHA256
|
||||
return hash_hmac('sha256', $payload, $app_key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user