Closing an "open" AWS API - amazon-web-services
I've built an API using AWS ElasticBeanstalk with integrated EC2 + Postgres RDS, and secured the endpoints with OAuth 2.
I received an email from an independent security auditor with a picture that they were able to gain access to production ENV variables. The ENV variables are managed through Elastic Beanstalk's configuration.
Here's a snippet of the picture they shared, in which they clearly have access to the ENVs:
I'm curious how they were able to view these sensitive env variables.
You are publishing an API on port 80 via PHP with no firewalling or access control.
You are running debugbar on a production site.
Basically, debugbar has very kindly included all of your environment variables in your HTML page.
<head></head><body style="margin-bottom: 38px;">Welcome to the Spywatch Lex Staging API ver 1.0<link rel="stylesheet" type="text/css" property="stylesheet" href="//3.95.51.53/_debugbar/assets/stylesheets?v=1586742726"><script type="text/javascript" src="//3.95.51.53/_debugbar/assets/javascript?v=1586742726"></script><script type="text/javascript">jQuery.noConflict(true);</script>
<script type="text/javascript">
var phpdebugbar = new PhpDebugBar.DebugBar();
phpdebugbar.addTab("messages", new PhpDebugBar.DebugBar.Tab({"icon":"list-alt","title":"Messages", "widget": new PhpDebugBar.Widgets.MessagesWidget()}));
phpdebugbar.addIndicator("time", new PhpDebugBar.DebugBar.Indicator({"icon":"clock-o","tooltip":"Request Duration"}), "right");
phpdebugbar.addTab("timeline", new PhpDebugBar.DebugBar.Tab({"icon":"tasks","title":"Timeline", "widget": new PhpDebugBar.Widgets.TimelineWidget()}));
phpdebugbar.addIndicator("memory", new PhpDebugBar.DebugBar.Indicator({"icon":"cogs","tooltip":"Memory Usage"}), "right");
phpdebugbar.addTab("exceptions", new PhpDebugBar.DebugBar.Tab({"icon":"bug","title":"Exceptions", "widget": new PhpDebugBar.Widgets.ExceptionsWidget()}));
phpdebugbar.addTab("views", new PhpDebugBar.DebugBar.Tab({"icon":"leaf","title":"Views", "widget": new PhpDebugBar.Widgets.TemplatesWidget()}));
phpdebugbar.addTab("route", new PhpDebugBar.DebugBar.Tab({"icon":"share","title":"Route", "widget": new PhpDebugBar.Widgets.VariableListWidget()}));
phpdebugbar.addIndicator("currentroute", new PhpDebugBar.DebugBar.Indicator({"icon":"share","tooltip":"Route"}), "right");
phpdebugbar.addTab("queries", new PhpDebugBar.DebugBar.Tab({"icon":"database","title":"Queries", "widget": new PhpDebugBar.Widgets.LaravelSQLQueriesWidget()}));
phpdebugbar.addTab("emails", new PhpDebugBar.DebugBar.Tab({"icon":"inbox","title":"Mails", "widget": new PhpDebugBar.Widgets.MailsWidget()}));
phpdebugbar.addTab("auth", new PhpDebugBar.DebugBar.Tab({"icon":"lock","title":"Auth", "widget": new PhpDebugBar.Widgets.VariableListWidget()}));
phpdebugbar.addIndicator("auth.name", new PhpDebugBar.DebugBar.Indicator({"icon":"user","tooltip":"Auth status"}), "right");
phpdebugbar.addTab("gate", new PhpDebugBar.DebugBar.Tab({"icon":"list-alt","title":"Gate", "widget": new PhpDebugBar.Widgets.MessagesWidget()}));
phpdebugbar.addTab("session", new PhpDebugBar.DebugBar.Tab({"icon":"archive","title":"Session", "widget": new PhpDebugBar.Widgets.VariableListWidget()}));
phpdebugbar.addTab("request", new PhpDebugBar.DebugBar.Tab({"icon":"tags","title":"Request", "widget": new PhpDebugBar.Widgets.VariableListWidget()}));
phpdebugbar.setDataMap({
"messages": ["messages.messages", []],
"messages:badge": ["messages.count", null],
"time": ["time.duration_str", '0ms'],
"timeline": ["time", {}],
"memory": ["memory.peak_usage_str", '0B'],
"exceptions": ["exceptions.exceptions", []],
"exceptions:badge": ["exceptions.count", null],
"views": ["views", []],
"views:badge": ["views.nb_templates", 0],
"route": ["route", {}],
"currentroute": ["route.uri", ],
"queries": ["queries", []],
"queries:badge": ["queries.nb_statements", 0],
"emails": ["swiftmailer_mails.mails", []],
"emails:badge": ["swiftmailer_mails.count", null],
"auth": ["auth.user", {}],
"auth.name": ["auth.name", ],
"gate": ["gate.messages", []],
"gate:badge": ["gate.count", null],
"session": ["session", {}],
"request": ["request", {}]
});
phpdebugbar.restoreState();
phpdebugbar.ajaxHandler = new PhpDebugBar.AjaxHandler(phpdebugbar);
phpdebugbar.ajaxHandler.bindToXHR();
phpdebugbar.setOpenHandler(new PhpDebugBar.OpenHandler({"url":"http:\/\/3.95.51.53\/_debugbar\/open"}));
phpdebugbar.addDataSet({"__meta":{"id":"1d34aa80b5b5d635d1fb5842750a3165","datetime":"2020-10-29 15:01:14","utime":1603983674.769273,"method":"GET","uri":"\/1.0","ip":"86.191.207.60"},"php":{"version":"7.2.19","interface":"apache2handler"},"messages":{"count":0,"messages":[]},"time":{"start":1603983674.682,"end":1603983674.769287,"duration":0.08728718757629395,"duration_str":"87.29ms","measures":[{"label":"Booting","start":1603983674.682,"relative_start":0,"end":1603983674.767149,"relative_end":1603983674.767149,"duration":0.08514904975891113,"duration_str":"85.15ms","params":[],"collector":null},{"label":"Application","start":1603983674.68708,"relative_start":0.005079984664916992,"end":1603983674.769289,"relative_end":1.9073486328125e-6,"duration":0.08220911026000977,"duration_str":"82.21ms","params":[],"collector":null}]},"memory":{"peak_usage":4194304,"peak_usage_str":"4MB"},"exceptions":{"count":0,"exceptions":[]},"views":{"nb_templates":0,"templates":[]},"route":{"uri":"GET 1.0","middleware":"cors","uses":"Closure {#132\n class: \"App\\Providers\\RouteServiceProvider\"\n this: App\\Providers\\RouteServiceProvider {#106 \u2026}\n file: \"\/var\/app\/current\/app\/Http\/routes.php\"\n line: \"22 to 25\"\n}","namespace":"App\\Http\\Controllers","prefix":"\/1.0","where":[],"file":"app\/Http\/routes.php:22-25"},"queries":{"nb_statements":0,"nb_failed_statements":0,"accumulated_duration":0,"accumulated_duration_str":"0\u03bcs","statements":[]},"swiftmailer_mails":{"count":0,"mails":[]},"auth":{"name":"Guest","user":{"guest":true}},"gate":{"count":0,"messages":[]},"session":{"_token":"j8Z5CzG5Laiomm5HyeJM7ZmKCP14llKHn6wyORkW","PHPDEBUGBAR_STACK_DATA":"[]","_previous":"array:1 [\n \"url\" => \"http:\/\/3.95.51.53\"\n]","flash":"array:2 [\n \"old\" => []\n \"new\" => []\n]"},"request":{"format":"html","content_type":"text\/html; charset=UTF-8","status_text":"OK","status_code":"200","request_query":"[]","request_request":"[]","request_headers":"array:8 [\n \"host\" => array:1 [\n 0 => \"3.95.51.53\"\n ]\n \"user-agent\" => array:1 [\n 0 => \"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10.13; rv:81.0) Gecko\/20100101 Firefox\/81.0\"\n ]\n \"accept\" => array:1 [\n 0 => \"text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,*\/*;q=0.8\"\n ]\n \"accept-language\" => array:1 [\n 0 => \"en-US,en;q=0.5\"\n ]\n \"accept-encoding\" => array:1 [\n 0 => \"gzip, deflate\"\n ]\n \"connection\" => array:1 [\n 0 => \"keep-alive\"\n ]\n \"cookie\" => array:1 [\n 0 => \"laravel_session=eyJpdiI6IjZxK0NmeFJRSjJwbE5JbDdPS0h1VWc9PSIsInZhbHVlIjoiUFVoYUxXSnlOanJFSWg2SHNsYWlZK2Z6SlR2aFFtcGEzM21xWUJWckJFTDZFdmVGd2l4S01cL3FRWkFjejNDZzNhbXJTdlR3WWtxWUZidW9vT2puV2lBPT0iLCJtYWMiOiI0MTRlN2U4YTgxNmJjMWE0YWNlNjMzYjc2YWI3ZmVmOGY3MmVkYWUwZWZhMDJmMmU4ZTg2NTljNGQ4OTBjY2M0In0%3D\"\n ]\n \"upgrade-insecure-requests\" => array:1 [\n 0 => \"1\"\n ]\n]","request_server":"array:99 [\n \"REDIRECT_APP\" => \"https:\/\/staging.spywatchlex.com\"\n \"REDIRECT_APP_ENV\" => \"staging\"\n \"REDIRECT_MAIL_USERNAME\" => \"postmaster#mg.spywatchlex.com\"\n \"REDIRECT_MAILGUN_DOMAIN\" => \"postmaster#mg.spywatchlex.com\"\n \"REDIRECT_APP_KEY\" => \"******\"\n \"REDIRECT_DB_HOST\" => \"aa1czcdcnsnpmyq.cuqlyug9ccbu.us-east-1.rds.amazonaws.com\"\n \"REDIRECT_QUEUE_DRIVER\" => \"sync\"\n \"REDIRECT_MAIL_PORT\" => \"2525\"\n \"REDIRECT_OAUTH_TTL\" => \"86400\"\n \"REDIRECT_SESSION_DRIVER\" => \"file\"\n \"REDIRECT_TWITTER_CALLBACK_URL\" => \"https:\/\/staging.spywatchlex.com\"\n \"REDIRECT_DB_USERNAME\" => \"Growler\"\n \"REDIRECT_EMAIL_BASE_URL\" => \"https:\/\/staging.spywatchlex.com\"\n \"REDIRECT_DB_CONNECTION\" => \"pgsql\"\n \"REDIRECT_CACHE_DRIVER\" => \"file\"\n \"REDIRECT_APP_DEBUG\" => \"true\"\n \"REDIRECT_MAIL_PASSWORD\" => \"******\"\n \"REDIRECT_MAILGUN_SECRET\" => \"******\"\n \"REDIRECT_DB_DATABASE\" => \"spywatch-lex\"\n \"REDIRECT_DB_PASSWORD\" => \"******\"\n \"REDIRECT_RDS_PORT\" => \"5432\"\n \"REDIRECT_RDS_HOSTNAME\" => \"aa1czcdcnsnpmyq.cuqlyug9ccbu.us-east-1.rds.amazonaws.com\"\n \"REDIRECT_RDS_USERNAME\" => \"Growler\"\n \"REDIRECT_RDS_DB_NAME\" => \"ebdb\"\n \"REDIRECT_RDS_PASSWORD\" => \"******\"\n \"REDIRECT_PHP_MEMORY_LIMIT\" => \"512M\"\n \"REDIRECT_PHP_MAX_EXECUTION_TIME\" => \"60\"\n \"REDIRECT_PHP_DISPLAY_ERRORS\" => \"Off\"\n \"REDIRECT_PHP_COMPOSER_OPTIONS\" => \"\"\n \"REDIRECT_PHP_ALLOW_URL_FOPEN\" => \"On\"\n \"REDIRECT_PHP_ZLIB_OUTPUT_COMPRESSION\" => \"Off\"\n \"REDIRECT_PHP_DOCUMENT_ROOT\" => \
You get the picture. It's a small mercy the passwords are somewhat redacted.
Steps to reproduce:
load your landing page
click "view source"
expand the <script type="text/javascript">...</script> block.
Please do several things.
change your passwords.
remove this API from the public internet
uninstall phpdebug from your production api
spend some time familiarizing yourself with how to actually secure PHP and AWS.
Sorry if this comes across as abrasive, but I don't even KNOW php and I found this in five minutes.
Related
Failed to connect to importexport.amazonaws.com port 443
Any body knows how to solve this Error message after trying to convert the image to ami Note (I already try to import via command line and it's working good) I'm trying to convert image from row to ami using laravel 8 Here is the information 1.) "aws/aws-sdk-php": "^3.231" 2.) php 8 3.) my code to process the conversion public function startConversion(string $s3DiskImageName, string $description): void{ $client = ImportExportClient::factory(array( 'credentials' => array( 'key' => config('filesystems.disks.s3.key'), 'secret' => config('filesystems.disks.s3.secret'), ), 'region' => config('filesystems.disks.s3.region'), 'version' => 'latest' )); $bucket = config('filesystems.disks.s3.bucket'); $client->createJob([ 'JobType' => 'Import', 'ValidateOnly' => false, 'Manifest' => json_encode([ [ 'Description' => "$s3DiskImageName - $description", 'Format' => 'raw', 'Url' => 's3:://'.$bucket .'/'.$s3DiskImageName ] ]) ]); } Thanks in advance!
Problems with waiters AWS PHP SDK3
I'm trying to change instance type but since I have updated to SDK3 this script fails. I don't know what I'm doing wrong with waiters. $client = new Ec2Client(self::getCredentials()); $client->stopInstances(array( 'InstanceIds' => $instanceIds, )); $client->waitUntil('stopped', [ 'InstanceId' => $instanceId, ]); $client->ModifyInstanceAttribute(array( 'InstanceId' => $instanceId, 'Attribute' => 'instanceType', 'Value' => $instanceType )); $client->startInstances(array( 'InstanceIds' => $instanceIds, )); $client->waitUntil('running', [ 'InstanceId' => $instanceId, ]);
I finally found the solution. The problem was that InstanceId param was wrong... You have to use an array of instaces Ids. $client->waitUntil('InstanceStopped', [ 'InstanceIds' => array($instanceId), ]); $client->waitUntil('InstanceRunning', [ 'InstanceIds' => array($instanceId), ]);
runInstances() in AWS SDK PHP 3.0 returns blank after successful launch of an instance
Following this, I used runInstances method like the following to launch and instance: $new_instance_config = array( 'DryRun' => false, 'ImageId' => AMI_ID, 'MinCount' => 1, 'MaxCount' => 1, 'InstanceType' => 't1.micro', 'Placement' => array( 'AvailabilityZone' => AVAILABILITY_ZONE, ), 'Monitoring' => array( 'Enabled' => false, ), 'NetworkInterfaces' => array( array( 'SubnetId' => SUBNET_ID, 'DeviceIndex' => 0, 'AssociatePublicIpAddress' => true, 'DeleteOnTermination' => true, 'Groups' => unserialize(SECURITY_GROUP_IDS) ) ) ); $res = $this->ec2Client->runInstances($new_instance_config); echo json_encode($res); However this only prints blank object {} even though if I login to the AWS console, I can see the instance launched. I need to access some information like the AMI ID of the launched instance. Am I missing something?
See Modeled Responses Try: $res['Instances'] or $res->get('Instances')
Calabash: Get state of toggle switch
I am trying to get the state of a toggle switch in my native app. This is the query of the switch itself, when ON: query "Switch id:'quadrant_buzz'" and its results [ [0] { "class" => "android.widget.Switch", "tag" => nil, "description" => "android.widget.Switch{29ddf658 VFED..C. ........ 877,0-1017,81 #7f10017f app:id/quadrant_buzz}", "id" => "quadrant_buzz", "text" => "", "visible" => true, "rect" => { "height" => 81, "width" => 140, "y" => 1303, "x" => 877, "center_x" => 947, "center_y" => 1343 }, "enabled" => true, "contentDescription" => nil }] This is the result of the query when the switch is OFF: [ [0] { "class" => "android.widget.Switch", "tag" => nil, "description" => "android.widget.Switch{29ddf658 VFED..C. ........ 877,0-1017,81 #7f10017f app:id/quadrant_buzz}", "id" => "quadrant_buzz", "text" => "", "visible" => true, "rect" => { "height" => 81, "width" => 140, "y" => 1213, "x" => 877, "center_x" => 947, "center_y" => 1253 }, "enabled" => true, "contentDescription" => nil }] I am unsure how to check for its on/off state. When I tap/touch the switch, nothing changes in the returned query. The only difference I see is the center-y. Is there something in the Calabash Api for this? Thanks
Looking up the documentation for a Switch widget on Android developers it is the method "isChecked". http://developer.android.com/reference/android/widget/Switch.html Therefore you can find this value in Calabash by invoking query("Switch id:'quadrant_buzz'", :isChecked) You could also used just :checked in Calabash.
The isChecked works. irb(main):001:0> query("android.widget.Switch",:isChecked) [ [0] true ]
Custom images not working in new gmaps4rails v2
Migrate gmaps4rails v1 to v2 (great gem!). But i cannot get the custom marker images only the default one. output code: handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){ markers = handler.addMarkers([{"lat":43.3851,"lng":12.3856,"picture":{"picture":"/assets/house.png","width":"32","height":"32"},"title":"blablabla"} controller #locations = Location.where(:region => #region.id) #hash = Gmaps4rails.build_markers(#locations) do |location, marker| marker.lat location.latitude marker.lng location.longitude marker.infowindow location.description marker.picture({ "picture" => "/assets/house.png", "width" => "32", "height" => "32" }) marker.json({:title => location.description}) end If you look ate the output the code works...but i don't see the custom marker house.png. Am i doing something wrong here? Security issue? Thanks..remco
You're simply not following the doc/examples, use: marker.picture({ "url" => "/assets/house.png", "width" => "32", "height" => "32" })