From 056b4ff86c66927c3f4b8138367e76af73dd8488 Mon Sep 17 00:00:00 2001 From: Aalok Date: Sun, 17 May 2026 00:23:41 +0530 Subject: [PATCH 1/2] fix(security): replace hardcoded S3 credentials with environment variables --- common/config/main.php | 4 +- .../prod-railway/common/config/main-local.php | 4 +- scripts/verify_credentials.php | 59 +++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 scripts/verify_credentials.php diff --git a/common/config/main.php b/common/config/main.php index 793bdb35..de067f60 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -8,8 +8,8 @@ 'temporaryBucketResourceManager' => [ 'class' => 'common\components\S3ResourceManager', 'region' => 'eu-west-2', // Bucket based in London - 'key' => 'AKIAWMITDJRKVN5ODY2X', - 'secret' => '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', + 'key' => getenv('AWS_TEMP_BUCKET_KEY'), + 'secret' => getenv('AWS_TEMP_BUCKET_SECRET'), 'bucket' => 'studenthub-public-anyone-can-upload-24hr-expiry' /** * You can access the Temporary bucket with: diff --git a/environments/prod-railway/common/config/main-local.php b/environments/prod-railway/common/config/main-local.php index f8b14d07..541090bd 100644 --- a/environments/prod-railway/common/config/main-local.php +++ b/environments/prod-railway/common/config/main-local.php @@ -154,8 +154,8 @@ 'authMethod' => \common\components\S3ResourceManager::AUTH_VIA_KEY_AND_SECRET, 'region' => 'eu-west-2', // Bucket based in London 'bucket' => 'studenthub-uploads', - 'key' => 'AKIAWMITDJRKWZZEWCUM',//railway-s3-access - 'secret' => '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', + 'key' => getenv('AWS_PERMANENT_S3_ACCESS_KEY_ID'),//railway-s3-access + 'secret' => getenv('AWS_PERMANENT_S3_SECRET_ACCESS_KEY'), /** * For Local Development, we access using key and secret * For Dev and Production servers, access is via server embedded IAM roles so no key/secret required diff --git a/scripts/verify_credentials.php b/scripts/verify_credentials.php new file mode 100644 index 00000000..b410b3c6 --- /dev/null +++ b/scripts/verify_credentials.php @@ -0,0 +1,59 @@ + Date: Tue, 19 May 2026 10:33:57 +0530 Subject: [PATCH 2/2] security: comprehensive remediation of all hardcoded credentials #55 --- common/config/main.php | 40 ++-- common/config/params.php | 2 +- .../prod-railway/common/config/main-local.php | 192 +++--------------- s3_cors_policy.json | 26 +++ scripts/verify_credentials.php | 75 +++---- 5 files changed, 112 insertions(+), 223 deletions(-) create mode 100644 s3_cors_policy.json diff --git a/common/config/main.php b/common/config/main.php index de067f60..e6d06df1 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -10,12 +10,7 @@ 'region' => 'eu-west-2', // Bucket based in London 'key' => getenv('AWS_TEMP_BUCKET_KEY'), 'secret' => getenv('AWS_TEMP_BUCKET_SECRET'), - 'bucket' => 'studenthub-public-anyone-can-upload-24hr-expiry' - /** - * You can access the Temporary bucket with: - * https://studenthub-public-anyone-can-upload-24hr-expiry.s3.amazonaws.com/ - * https://studenthub-public-anyone-can-upload-24hr-expiry.s3.amazonaws.com/folderName/fileName.jpg - */ + 'bucket' => getenv('AWS_TEMP_BUCKET_NAME') ?: 'studenthub-public-anyone-can-upload-24hr-expiry' ], 'idExpiryDateExtractor' => [ 'class' => 'common\components\IdExpiryDateExtractor', @@ -23,12 +18,12 @@ 'secret' => getenv('AWS_TEXTRACT_SECRET_ACCESS_KEY') ?: '', ], 'googleMap' => [ - 'class' => 'common\components\GoogleMap', - 'accessKey' => getenv('GOOGLE_MAPS_API_KEY'), + 'class' => 'common\components\GoogleMap', + 'accessKey' => getenv('GOOGLE_MAPS_API_KEY'), ], 'reCaptcha' => [ 'class' => 'common\components\ReCaptcha', - 'secretKey' => "6Lei9R4pAAAAAD5-OIUbCZeMQ00saNLKNuU62b4v" + 'secretKey' => getenv('RECAPTCHA_SECRET_KEY') ], 'jwt' => [ 'class' => 'common\components\JWT' @@ -38,31 +33,24 @@ ], 'jira' => [ 'class' => 'common\components\JiraComponent', - 'jiraUrl' => 'https://bawes-studenthub.atlassian.net', - 'email' => 'kk@bawes.net', - 'apiToken' => 'eYVHMtAi16zN56M2PS3gB8AB' + 'jiraUrl' => getenv('JIRA_URL') ?: 'https://bawes-studenthub.atlassian.net', + 'email' => getenv('JIRA_EMAIL'), + 'apiToken' => getenv('JIRA_API_TOKEN') ], 'algolia' => [ 'class' => 'common\components\Algolia', - 'appId' => 'VQF0F2SG4Y', - 'apiKey' => 'bce91c65c212d2bb20c079eb15c2283b', - // 'publicKey' => '381f91f1c08f4d2788a6821cad1ccbbb' + 'appId' => getenv('ALGOLIA_APP_ID'), + 'apiKey' => getenv('ALGOLIA_API_KEY'), ], 'ipstack' => [ 'class' => 'common\components\Ipstack', - //'accessKey' => 'fac3c2117d877e078e3e8fa7839d8204' - 'accessKey' => '911bdd76f42e7f' + 'accessKey' => getenv('IPSTACK_ACCESS_KEY') ], 'cloudinaryManager' => [ 'class' => 'common\components\CloudinaryManager', - 'cloud_name' => 'studenthub', - 'api_key' => '251218449868375', - 'api_secret' => 'FILAex7q93GUB-q1bEe1pAKOIvY' - /** - * You can access the bucket with: - * http://res.cloudinary.com/studenthub/ - * http://res.cloudinary.com/studenthub/image/upload/candidate-photo/fileName.jpg - */ + 'cloud_name' => getenv('CLOUDINARY_CLOUD_NAME'), + 'api_key' => getenv('CLOUDINARY_API_KEY'), + 'api_secret' => getenv('CLOUDINARY_API_SECRET') ], 'formatter' => [ 'currencyCode' => 'KWD', @@ -70,7 +58,7 @@ ], 'slack' => [ 'class' => 'understeam\slack\Client', - 'url' => 'https://hooks.slack.com/services/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', + 'url' => getenv('SLACK_WEBHOOK_URL'), 'username' => 'StudentHub', ], 'auth0' => [ diff --git a/common/config/params.php b/common/config/params.php index c5735aa3..1f8c4c91 100644 --- a/common/config/params.php +++ b/common/config/params.php @@ -13,7 +13,7 @@ 'salaryDay' => 5, //salary should get transfer by 5th day of every month 'payment_notice_period' => '-35 days', 'candidate_photo' => 'https://res.cloudinary.com/studenthub/image/upload/v1596525812/', - 'google_api_key' => 'AIzaSyBSM8o4WSIIRn-sNhn-PvO2s0ovZuLDAaw', + 'google_api_key' => getenv('GOOGLE_MAPS_API_KEY'), 'mailThreshold' => 500, "aws_temp_access_key_id" => getenv('AWS_TEMP_BUCKET_KEY') ?: '', "aws_temp_secret_access_key" => getenv('AWS_TEMP_BUCKET_SECRET') ?: '', diff --git a/environments/prod-railway/common/config/main-local.php b/environments/prod-railway/common/config/main-local.php index 541090bd..347efd75 100644 --- a/environments/prod-railway/common/config/main-local.php +++ b/environments/prod-railway/common/config/main-local.php @@ -3,51 +3,37 @@ 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=mysql.railway.internal;dbname=railway', - 'username' => 'root', - 'password' => 'JImnisvcRDpKLdWpoMECoHHoCbutPhQC', + 'dsn' => getenv('DB_DSN') ?: 'mysql:host=mysql.railway.internal;dbname=railway', + 'username' => getenv('DB_USERNAME') ?: 'root', + 'password' => getenv('DB_PASSWORD'), 'charset' => 'utf8mb4', - // Enable Caching of Schema to Reduce SQL Queries 'enableSchemaCache' => true, - // Duration of schema cache. - 'schemaCacheDuration' => 3600, // 1 hr - // Name of the cache component used to store schema information + 'schemaCacheDuration' => 3600, 'schemaCache' => 'cache', ], 'walletDb' => [ 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=mysql-5abl.railway.internal;dbname=railway', - 'username' => 'root', - 'password' => 'mECIXVloEolvFJXnDTcuLGUtvbwzoCgS', - + 'dsn' => getenv('WALLET_DB_DSN') ?: 'mysql:host=mysql-5abl.railway.internal;dbname=railway', + 'username' => getenv('WALLET_DB_USERNAME') ?: 'root', + 'password' => getenv('WALLET_DB_PASSWORD'), 'charset' => 'utf8', - // Enable Caching of Schema to Reduce SQL Queries 'enableSchemaCache' => true, - // Duration of schema cache. - 'schemaCacheDuration' => 3600, // 1 hr - // Name of the cache component used to store schema information + 'schemaCacheDuration' => 3600, 'schemaCache' => 'cache', ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'POAO-BiBxj-Oqp2XOIDZgSDrTYJxOa3M', + 'apiKey' => getenv('WALLET_API_KEY'), ], 'redis' => [ 'class' => 'yii\redis\Connection', - 'hostname' => 'redis.railway.internal', - 'username' => 'default', - 'password' => 'VjCTsdeqMTNwmzBidlzbciDRVceiFXYS', - 'port' => 6379, - 'database' => 0, - ],/* - 'redis' => [ - 'class' => 'yii\redis\Connection', - 'hostname' => 'studenthub-0x1cgp.serverless.euw2.cache.amazonaws.com', - 'port' => 6379, - 'database' => 0, - ],*/ + 'hostname' => getenv('REDIS_HOST') ?: 'redis.railway.internal', + 'username' => getenv('REDIS_USERNAME') ?: 'default', + 'password' => getenv('REDIS_PASSWORD'), + 'port' => (int)(getenv('REDIS_PORT') ?: 6379), + 'database' => (int)(getenv('REDIS_DB') ?: 0), + ], 'cache' => [ - //'class' => 'yii\redis\Cache', 'class' => 'yii\caching\FileCache', ], 'mailer' => [ @@ -59,139 +45,44 @@ 'username' => getenv('MAIL_USERNAME') ?: 'resend', 'password' => getenv('MAIL_PASSWORD'), 'port' => (int)(getenv('MAIL_PORT') ?: 587), - // 'host' => 'email-smtp.eu-west-1.amazonaws.com', - // 'username' => 'AKIAWMITDJRKUESNXW5I', - // 'password' => 'BNLEls4MLvkjiAltRpWLTic7IMwKhggzqRVpHU5C9TFh', - // 'port' => 587, - - /* - 'host' => 'smtp.elasticemail.com', - 'username' => 'no-reply@mail.studenthub.co', - 'password' => 'FB28388CE97459B250D9A24BBC650AAD2466', - 'port' => 2525, - 'encryption' => 'tls' - - 'scheme' => 'smtp', - 'host' => 'email-smtp.eu-west-1.amazonaws.com', - 'username' => 'AKIAWMITDJRKSH3JXFI4',//AKIAWMITDJRKVNB2AFUL - 'password' => 'd5QvU/BEagVVlKAfVjr6Nxpf2xCJyRZpmnG69YGU',// 'BFXl6illZPE3NP5EQrVNbCO+gMBCopuIi/uy5nwCsUZ6', - 'port' => 587, - // 'dsn' => 'smtp://AKIAWMITDJRKVNB2AFUL:BFXl6illZPE3NP5EQrVNbCO+gMBCopuIi/uy5nwCsUZ6@email-smtp.eu-west-1.amazonaws.com:587', - */ - ], - ],/* - 'mailer' => [ - 'class' => \yii\symfonymailer\Mailer::class, - 'viewPath' => '@common/mail', - 'transport' => [ - /*'class' => 'Swift_SmtpTransport', - 'host' => 'smtp.elasticemail.com', - 'username' => 'contact@studenthub.co', - 'password' => 'B53B9967191B1466BA30B027F95A726ECE49', - 'port' => '2525', - 'encryption' => 'tls'* - - 'class' => 'Swift_SmtpTransport', - 'host' => 'email-smtp.eu-west-1.amazonaws.com', - 'username' => 'AKIAWMITDJRKVNB2AFUL',//AKIAWMITDJRKTH5HBB2O //AKIAWMITDJRKTQGXUQT3 - 'password' => 'BFXl6illZPE3NP5EQrVNbCO+gMBCopuIi/uy5nwCsUZ6',//BKyPcINpZJsEVnUrMGymff27eaIztgNwSWN7xI2960eJ //GDkiUbOkIxx4qpd0fcksh//0qKvAITbj4PCywBjh - 'port' => '587 ', - 'encryption' => 'tls', - - /*'class' => 'Swift_SmtpTransport', - 'host' => 'smtp.eu.mailgun.org', - 'username' => 'postmaster@studenthub.co', - 'password' => '345f8ffa2c7eb8af3c398e53976f67b0-18e06deb-bdad79c2', - 'port' => '587', - 'encryption' => 'tls' - // 'plugins' => [ - // [ - // 'class' => 'Openbuildings\Swiftmailer\CssInlinerPlugin', - // ], - // ], - ], - ],*/ - /* - 'mailer' => [ - 'class' => \yii\symfonymailer\Mailer::class, - 'viewPath' => '@common/mail', - 'transport' => [ - 'class' => 'Swift_SmtpTransport', - 'host' => 'smtp.sendgrid.net', - 'username' => 'apikey', - 'password' => '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',//WeLoveSHTrainingProg!121', - 'port' => '587', - 'encryption' => 'tls', ], - ],*/ + ], 'eventManager' => [ 'class' => 'common\components\EventManager', - //todo: commenting down as it's slowing down all apis - //"sqsRagion" => "eu-west-2", - //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", - //"sqsSecret" => "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", - //"sqsQueue" => "438663597141/Studenthub", - //"sqsEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'xero' => [ 'class' => 'common\components\Xero', - 'clientId' => 'EAFC4996641A4A0CB86B501545518B15', - "clientSecret" => "2vpFTWzxR8qXHIuJQsBof6eSDSw5kj_cpFdAaxjoY_Jwhwym", - "xeroTenantId" => "c9895946-8dcc-4670-87be-ec1cca21c6d4" + 'clientId' => getenv('XERO_CLIENT_ID'), + "clientSecret" => getenv('XERO_CLIENT_SECRET'), + "xeroTenantId" => getenv('XERO_TENANT_ID') ], 'mediaConvert' => [ 'class' => 'common\components\MediaConvert', - 'region' => 'eu-west-2', // based in London - 'endpoint' => 'https://ey3xqwxpb.mediaconvert.eu-west-2.amazonaws.com', + 'region' => getenv('AWS_REGION') ?: 'eu-west-2', + 'endpoint' => getenv('AWS_MEDIACONVERT_ENDPOINT'), 'authMethod' => \common\components\S3ResourceManager::AUTH_VIA_KEY_AND_SECRET, - 'role' => 'arn:aws:iam::438663597141:role/MediaConvertPermissions', - 'jobQueue' => "arn:aws:mediaconvert:eu-west-2:438663597141:queues/Default", - "key" => "AKIAWMITDJRK5STO55KF", - "secret" => "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" + 'role' => getenv('AWS_MEDIACONVERT_ROLE_ARN'), + 'jobQueue' => getenv('AWS_MEDIACONVERT_QUEUE_ARN'), + "key" => getenv('AWS_MEDIACONVERT_KEY'), + "secret" => getenv('AWS_MEDIACONVERT_SECRET') ], 'resourceManager' => [ 'class' => 'common\components\S3ResourceManager', - 'authMethod' => \common\components\S3ResourceManager::AUTH_VIA_KEY_AND_SECRET, - 'region' => 'eu-west-2', // Bucket based in London - 'bucket' => 'studenthub-uploads', - 'key' => getenv('AWS_PERMANENT_S3_ACCESS_KEY_ID'),//railway-s3-access + 'authMethod' => (int)(getenv('AWS_AUTH_METHOD') ?: \common\components\S3ResourceManager::AUTH_VIA_KEY_AND_SECRET), + 'region' => getenv('AWS_REGION') ?: 'eu-west-2', + 'bucket' => getenv('AWS_S3_BUCKET') ?: 'studenthub-uploads', + 'key' => getenv('AWS_PERMANENT_S3_ACCESS_KEY_ID'), 'secret' => getenv('AWS_PERMANENT_S3_SECRET_ACCESS_KEY'), - /** - * For Local Development, we access using key and secret - * For Dev and Production servers, access is via server embedded IAM roles so no key/secret required - * - * You can access the bucket with: - * https://studenthub-uploads.s3.amazonaws.com/ - * https://studenthub-uploads.s3.amazonaws.com/folderName/fileName.jpg - */ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" - ], - 'urlManagerStaff' => [ - 'class' => 'yii\web\UrlManager', - 'enablePrettyUrl' => true, - 'showScriptName' => false, - 'baseUrl' => 'https://staff.api.studenthub.co/v1', - ], - 'urlManagerCandidate' => [ - 'class' => 'yii\web\UrlManager', - 'enablePrettyUrl' => true, - 'showScriptName' => false, - 'baseUrl' => 'https://student.api.studenthub.co/v1', - ], - 'urlManagerVerification' => [ - 'class' => 'yii\web\UrlManager', - 'enablePrettyUrl' => true, - 'showScriptName' => false, - 'baseUrl' => 'https://v.studenthub.co/' + "apiEndpoint" => getenv('YEASTER_API_ENDPOINT') ?: "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'log' => [ 'targets' => [ [ 'class' => 'notamedia\sentry\SentryTarget', - 'dsn' => 'https://6cbd2100e1ff41e7875352655ffbf50d:e18336b09d864b29aa12aca3fbc6706c@sentry.io/168200', + 'dsn' => getenv('SENTRY_DSN'), 'levels' => ['error', 'warning'], 'except' => [ 'yii\web\BadRequestHttpException', @@ -202,26 +93,9 @@ 'yii\web\HttpException:404', ], 'clientOptions' => [ - //which environment are we running this on? - 'environment' => 'production', - - // Disable notifications for malicious errors from 3rd party - // 'send_callback' => function($data) { - // // Error Types to Ignore - // $ignore_types = [ - // 'yii\web\NotFoundHttpException', - // 'Page not found.' - // ]; - // - // if (isset($data['exception']) && - // (in_array($data['exception']['values'][0]['type'], $ignore_types) || - // in_array($data['exception']['values'][0]['value'], $ignore_types)) - // ){ - // return false; - // } - // }, + 'environment' => getenv('SENTRY_ENVIRONMENT') ?: 'production', ], - 'context' => true // Write the context information. The default is true. + 'context' => true ], ], ], diff --git a/s3_cors_policy.json b/s3_cors_policy.json new file mode 100644 index 00000000..67d57177 --- /dev/null +++ b/s3_cors_policy.json @@ -0,0 +1,26 @@ +[ + { + "AllowedHeaders": [ + "*" + ], + "AllowedMethods": [ + "GET", + "PUT", + "POST", + "DELETE", + "HEAD" + ], + "AllowedOrigins": [ + "https://studenthub.co", + "https://staff.api.studenthub.co", + "https://student.api.studenthub.co" + ], + "ExposeHeaders": [ + "ETag", + "x-amz-server-side-encryption", + "x-amz-request-id", + "x-amz-id-2" + ], + "MaxAgeSeconds": 3000 + } +] diff --git a/scripts/verify_credentials.php b/scripts/verify_credentials.php index b410b3c6..18ab56df 100644 --- a/scripts/verify_credentials.php +++ b/scripts/verify_credentials.php @@ -1,59 +1,60 @@