do I just need to put one screen in portrait mode?
In the past I had experimented with using portrait displays for reading and programming. The ability to display large amount of text is certainly appealing.
Boring
But is this the most optimal display for software development? Lets evaluate
Rotation
Advantages
Disadvantages
0°
Works with most applications. Video content is usually in wide format
Websites and documents usually end up with a lot of whitespace and padding around them
90°
Great for text documents - can read down like a book page
Movies don’t display well. Viewing angle problems
Here you might think we might done. But there are soooooo many more angles we can try. This is a little tricky on macOS and Windows but on Linux we have all the freedom we need.
Odd but ok.
We have a little tool called xrandr (x resize and rotate). We can use it to rotate the screen around to any angle we want. In practice I couldn’t get this to work on my MacBook. My desktop on the otherhand it had no problems. So lets try a few out.
1° - notice the menu bar disappearing to the right
45° - I run out of space
Rotation
Advantages
Disadvantages
1°
Handy if your desk is on a slight slope
fonts render a little weird
45°
Middle ground between vertical and horizontal
doesn’t fit well with non square aspect ratios
One neat thing about 45° is that it gives us pretty close to the diagonal. But not on my ultra wide. Due to maths, the amount we’d need to rotate is based on the angle of a triangle which match the aspect ration of the screen we are using. This ends up being about 22° for a 21:9 ratio.
The perfect rotation
22° - Perfect
Rotation
Advantages
Disadvantages
22°
Longest line length!
Webcam starts sliding away
So this here I think is the best monitor orientation for software development. It provides the longest line lengths and no longer need to worry about that pesky 80 column limit.
How do I do this?
First off, I could only get this to work in xorg - no wayland support yet. xrandr --output HDMI-3 --transform lots of numbers here takes a transformation matrix thats used to position the screen. We can use that to rotate the display.
The basic syntax that we need for rotating and shifting is this
This occurred on an AWS website (not a site hosted on AWS, but a site run by AWS). It shows that security is hard, even for a $51 billion business. This issue can occur not just on websites but even SDKs and libraries
📸 Erik Mclean via unsplash
While developers have a keen nose for code smells us operations types have a keen nose for infrastructure smells. When I opened this git repository for first time it hit me. A buildspec.yml file.
The humble buildspec.yml
For those unfamiliar, buildspec.yml is used by a service called CodeBuild and basically defines the steps used to build a project, including running shell commands. It’s basically remote code execution as a service.
The presence of this file in a repository isn’t call for alarm, but when it’s in a public repository it certainly raises red flags. The usual concern is someones committed some secret credentials into this file. In this case the file was clean of credentials.
All good right? Not so fast.
📸 Lachlan Gowen via unsplash
notices your deploy.sh
The buildspec.yml referenced a deploy.sh. This is when I verbally said “oh no”. Like before no secrets committed. A good start. deploy.sh contains instructions to deploy out the project - like aws s3 sync and the like, so we can determine that when this gets run it has access to upload to the production site.
📸 Nathan Anderson via unsplash
The issue here is that the buildspec.yml and deploy.sh could be modified by a malicious user.
The pull request
However malicious user doesn’t have access to commit to the repository and an admin isn’t going to merge malicious code, so this is no big deal right? Let’s see what happens when we lodge a pull request.
Upon creation of the pull request GitHub triggers a CodeBuild job. This is a fairly common practice to make sure nothing in the pull request breaks the build. What prevents the pull request build from deploying to production? Lets check deploy.sh
if[["$CODEBUILD_WEBHOOK_HEAD_REF"=="refs/heads/main"&&${CODEBUILD_SOURCE_VERSION:0:3} !="pr/"]]; then
oh no.
So deployment is purely controlled by a script that can be changed in the pull request.
📸 Scott Walsh via unsplash
One last chance
At this stage we’ve got remote code execution into the pipeline. Apart from mining some Bitcoin this is pretty uneventful. What about the S3 sync we mentioned earlier? It’s possible that the role granted for pull requests is the same role used for deploying to production, so lets check it out.
I edited the shell script to have my code right at the start …
target_bucket value was recovered from original deploy.sh
… and lodged a pull request. I checked the website and sure enough my file was there. 😮
📸 Nathan Anderson via unsplash
It doesn’t end there
It’s quite possible that the role used for deployment might have access to lots of interesting things, a private subnet, IAM admin, CloudFormation. I didn’t check further than this and submitted a disclosure reported to the security team immediately.
Prevention
If you still want pull requests to trigger builds on a public repository there a couple of things you can do to limit risk.
Place build scripts in a separate repo. Some build tools let you specify a separate repo to use for the build pipeline. Be careful though as this doesn’t guarantee that the project build can’t execute commands, depending on the programming language and build tools.
For services like CodeBuild you can utilize a separate IAM role for pull requests which is limited to just build requirements. Make sure the build agents for PRs aren’t within a a trusted network.
The below video is streamed from AWS practically for free. This is done very similar to the original Big Buck AWS but using OpsWorks logs instead. This exploit is a little more useful as you can store gigabytes of data, many more times, and CORS is enabled.
(click play if video doesn’t auto play)
When you run a command in AWS OpsWorks (such as Setup or Configure) the logs are uploaded to S3 and viewed from the UI using presigned URLs. The bucket for this is opsworks-us-east-1-log - notice how it’s an AWS bucket and not your bucket!
So what we do is we run a whole bunch of deployments to generate logs, and we modify the opsworks agent lib/instance_agent/agent/process_command.rb file to print out the presigned URL that it uses to upload logs. Once we have the presigned URLs and the logs are uploaded we reupload whatever content we want to. In this case the MPEG files for Big Buck Bunny.
to get the log URLs.
To form this site we dump the Lambda behind an API Gateway and serve up a HLS m3u8 file. More details can be found at the original Big Buck AWS GitHub