Top Reasons To Use Mozilla Firefox 🔥🦊 Right Now – Part 2

Like many of my friends during the late 2000s, I embarked on my internet journey with Firefox. It started with Firefox being the only browser that could reliably resume downloads in the event of a power outage, which were frequent in my part of India, and that was very useful with a slow internet connection that gave me 10KB/s on a good day.

A few years later I learned about free and open source software, and started thinking of the internet as a public resource and a great equalizer of access to knowledge and opportunity. Firefox was a very natural fit in this newly discovered world of mine.

Around 8 years ago, I published top reasons why you should start using Mozilla Firefox right now documenting the various reasons why Firefox should be the browser of choice for anyone who desires a safe, private and customizable web browsing experience.

Since I’m now part of the organization that I’ve so long revered, I thought an update to the original post is appropriate, and started listing some reasons why Firefox is still my browser of choice today.

I am slightly biased towards Firefox, but in my defense that’s hardly ever changed.


Features that enhance your web experience

One of the reasons people love Firefox is its customizability. The functionality can be extended using Addons and for the truly adventurous, Firefox’s UI is customizable using a bit of custom CSS. Given how personal web browsing is and how much time we spend using a browser, a bit of customization can go a long way.

Powerful Adblocking with uBlock Origin

TL;DR from Ghostery

With enforcement of Manifest V3, Google dramatically limits capabilities of browser extensions. It removes access to powerful APIs that allowed us to provide innovation in privacy protection. Being subjected to those constraints, we have to re-invent the way our extensions operate. Intended or not, Manifest V3 takes choice away from users, exposing them to new threats. Manifest V3 is ultimately user hostile.

https://www.ghostery.com/blog/manifest-v3-the-ghostery-perspective

Ads are the de facto way of monetization on the internet, and many creators rely on it for making a living on the internet. However, since there’s so much money to be made through harvesting data for targeting ads, internet ad companies try to “spy” on people across the internet learning more and more about their browsing habits to show them the most relevant ads.

Many people face a dilemma of having to choose between giving back to the content creators they’ve come to love and depend upon, and not being okay with third party companies looking at their browsing habits all over the internet.

Tools like uBlock Origin prevent “cross site tracking” and block ads and other annoyances from loading on webpages saving bandwidth and energy, and enabling a fast and pleasant web experience.

uBlock Origin also allows enabling ads on certain websites, which is something we should definitely do to support digital creators we rely upon for news, knowledge and entertainment.

Note that online advertising can be both effective and useful, without being creepy as this page from DuckDuckGo describes.

Further reading:

Picture-in-Picture

Picture-in-picture mode detaches the currently playing video on many video streaming websites like YouTube, enabling you to watch a football game while reading an article on Wikipedia all in a resizable little window that can be moved around.

Multi-Account Containers

Want to keep work, social media and finance related websites all separate but don’t want to bother having two browsers or separate web history? Multi-Account containers help you do exactly that.

Now you can browse Facebook in one “container”, access your banking apps on another and keep your work and personal email logged into a third and fourth container. Yes, logged into two Google accounts from the same browser.

None of the websites in one container “see” the websites open in another, either directly or with third party cookie based tracking.

Tree Style Tabs

You’d have to pay me to have me move back to the old way of using browser tabs and you’d fail. They’re that good. Seriously.

Tabs arranged in a “tree” shape

Look maa, no Tabs bar!

Tree Style Tabs give you a quick way to visually see the which tab something came out of, essentially answering the question of “how did I even reach here?” when you are 6 levels down in a Wikipedia rabbit hole about deep sea internet cables or something.

P.S. Annie is one of my favorite creators on the internet. Go follow her page @depthsofwikipedia on Instagram for weird Wikipedia content.


Better privacy controls for all

Because privacy is a fundamental right and most people prefer not having third parties snooping over their shoulders as they browse the internet.

Total Cookie Protection

Firefox rolled out total cookie protection earlier this year which creates separate “cookie jars” for websites preventing cross domain tracking using shared cookies.

Image from Mozilla

Enhanced Tracking Protection & Breach Monitoring

Firefox protects you from malice on the internet. It also does a good job at reporting the protections.

Enhanced Tracking Protection dashboard

Breach monitoring alerts you if your email address was involved in any data leaks across the internet.

Breach Monitor dashboard

Bonus section

This section will have weird things by design.

Custom CSS

As mentioned earlier, Firefox’s UI elements are made with web technologies like CSS. A bit of custom CSS goes a long way into making the Browser look exactly the way you want. A popular workflow is hiding the Tabs bar and relying on Tree Style Tabs for inter-Tab navigation.

Logo 🦊

This is very personal (that is, even more than the rest of this article), but I’m very fond of the Firefox logo. And as we’ve seen in the past, many people feel very strongly about the Fox in the logo so I’m not alone in feeling that way.

Firefox Developer Edition

I use the Firefox Developer Edition as my work browser. It is really good if you work with frontend web technologies like CSS or JavaScript. Debugging CSS or JavaScript on the Developer Edition is a joy, and I was especially impressed at how good it was with Grids.


In closing

If you had asked me 8 years ago why I recommend Firefox, I’d have gone on a long rant about how Firefox is one of the only two major non-Chromium based browsers, and the only one supported by a non-profit that fights to keep the web open and inclusive; That Firefox is built and maintained with the help of thousands of volunteers and open web enthusiasts and so on.

Today I would just say I recommend it because it is a great browser. It is also all of the above if you care, but if all you care about is the best web experience, Firefox will serve you just fine.

Go give the Fox a try! Thank you for reading.

Featured image credits: https://unsplash.com/photos/ZHS3j0_Y_KM

Twenty-seven 🎂

I turned 27 a month ago. I’ve not written a birthday post in a while (last time was turning 24, three years ago) so decided to write something for this one. Not that 27 is a special year or anything (well, I guess it is (un)special in the sense that it only comes once in a lifetime). However I do somehow feel 27 is a round number.

It is hard to explain, but I think I’m at the line that separates an early adult and a full real adult. It’s complicated, and I feel like neither to be very honest.

This year was quite exciting, from settling into my new role at CareerFoundry as a web & security engineer, to traveling around a bit, to getting my dream flat in the NeukĂślln district of Berlin (only to lose it six months later, but hey, not everything has to work out :), to getting my dream job at Mozilla, it has been a really happening year.

I’m really looking forward to this year. New job, new apartment, new part of the city, new technologies to learn and master. So much to be excited about. I decided to write more starting on my birthday, and I’ve been seeing good progress in the last month and a half since then. I’ll document my note-taking habit in an article about Obsidian soon.

My hope for the next one year is to get some stability into my life which got a bit rough in H2. Also hope to do well at work and life in general, but we’ll see that.

Currently I’m into this game called Life is Strange and have been listening to sound tracks from it. I play chess around once or twice per day, and sometimes paint.

Work takes up most of my time, but that’s expected and I’m really enjoying the new learnings coming my way. Overall, life’s good. I’ll go into more detail regarding some of the things I’m up to in separate articles.

Thank you for reading!

office space at evening time with some desks and postit notes

6 Lessons learned during my time at CareerFoundry

I started working at CareerFoundry (“CF”) in January 2019. Ever since then, I’ve changed in many ways. Change is inevitable and we have very limited control over it. In fact, I think that that only tiny bit of control we have over it is the kind of change we’d like to see in ourselves.

One way to dictate positive change is by being curious about new environments and people, embracing new and often uncomfortable situations with an open mind.

Getting hired at CF carved a way to some of my most cherished memories, meaningful relationships and enabled me to pursue the hobbies and interests I always wanted to pursue and be the person I always wanted to be.

It also brought me to the beautiful city of Berlin that had space for me and my eccentricities.

I’ve met some amazing people at CF — people who’ve guided me, mentored me, praised me and then schooled me when I needed it. People who’ve shaped the person you see in me, the person I see in myself.

Inspiration for this article

The inspiration for this article came from a thought I had.

I was visualising our old office at KĂśpenicker Straße and thinking of my first day. I walked from Heinrich-Heine-Straße U-Bahn all nervous, not sure how I’ll feel about working in a new country with new people. I was scared.

I started imagining my current self; the one who has worked at CF for nearly 4 years, on my last day walking down the stairway, meeting my younger self walking up the stairway on his first day.

The young me asks if I have any tips for him that’d help his CF journey.

This is the article I’d send him.

Lesson #1 – Gratitude makes everything better, so does kindness

I admit that it was strange standing in a circle hearing everyone thank one another in my first week at CF. But I got used to it. Some time later I understood the idea itself. 

In a world of ever-increasing needs and wants, gratitude makes us look back at what we already have and feel good about it. The Friday gratitude forced us to look back and remember something good that someone did that helped us in some way. Not just remember, but also announce it.

It is like social-engineering happiness into people, pushing them to look at the beauty in the world. With practice, I got more and more comfortable thanking people and telling them I appreciate them.

Kindness is another quality that I found in abundance during my time at CF. The lengths people went to—to support one another, to assume the best of intentions and to help each other grow—was incredible. I’m a recipient of much of that kindness myself. 

Like with gossiping and complaining, gratitude and kindness are just habits. The more we practice them, the easier it becomes to do it the next time. 

The more we are exposed to any of them, the more we reciprocate it to others. Hence it becomes easier to find people who exhibit the same. It is a beautiful self-sustaining cycle.

Lesson #2 – Growth mindset, or the idea of unlocking new skills with practice

Growth mindset is simply believing that many skills can be learned and improved upon by regular practice and timely feedback as opposed to being born with an innate capacity to do them.

The first time I heard about growth mindset was through one of Martin’s Monday morning speeches. It made sense, but it was only after applying it to many of the skills I wanted to pick up that I understood how powerful a simple change to a way of thinking can be.

I got into many hobbies after that, learned fun skills and gained many friends due to the hobbies. It changed my way of looking at everything and made me more curious.

I’ve gamified the whole experience of knowing absolutely nothing about something, then learning more and more about it, practising, getting feedback and improving, and then magically being able to do it — something that I’d have deemed impossible a short while ago.

Lesson #3 – Good people with good intentions are the overwhelming majority

There was a rant post on Reddit about how Berlin is changing for the worse, and there was this following reply to that post. I thought it was really well written.

You leave a megaphone in a public space, and mostly as**oles pick it up to yell thinly veiled hatred in it. No one cares, except for the other assholes in the megaphone line, who cheer for the bile and can’t wait to be cheered in return. But then, when I picked the megaphone and asked for help, I found help. And when I picked up the megaphone and offered some, I found people to help. The regular people are here. They just aren’t ranting or cheering the rants.

– reddit r/berlin

It isn’t news to anyone that negativity spreads much faster than positivity, and social media only amplifies that. As a result of this, it is very easy to be cynical of everything and everyone.

What I’ve learned at CF is that most people are just like me. 

  • They will do good if given a chance. 
  • They’ll help if they can. 
  • They’ll get out of the way if told they or their actions are causing hurt

One of Martin’s Monday morning speeches was about assuming the best of intentions. I thought it was appropriate as most people have good intentions most of the time, so it makes a lot of sense to have that as our default stance.

Lesson #4 – Rules can be made up to come together with others, do good and spread happiness

Another important lesson I’ve learned at CF goes hand in hand with an amazing video I watched about Optimistic Nihilism from this youtube channel called Kurzgesagt. The premise of the video was that if the universe doesn’t have any purpose, then we get to dictate its purpose; our purpose.

An extension to that idea is creating arbitrary rules for ourselves that help us do more of what we love. At CF, many people are givers. They love doing something for others. 

So why wait for a special yearly holiday to cook for others? Just make up a couple of things like Soup Kitchen and Breakfast Thursdays to enable anyone who loves cooking for others to do it.

And why wait for Thanksgiving to thank someone when we could just thank them every Friday in our Friday Gratitude.

And why wait to take that new colleague of ours and the rest of the team to the best burger joint when you could just have Burger Fridays every Friday.

Convenient, eh?

Honestly, Burger Fridays is my most missed tradition at CF. I’d have also proposed a Donnerstag Döners but Covid had other plans.

Lesson #5 – Company culture is just the people of CF

Recently I watched this speech titled “This is water” by David Wallace in which Mr. Wallace tells us the importance of being aware of the most obvious things around us.

It made me think of this phrase “company culture” and wonder what it is. When I joined CF, I remember trying to fit into the culture. Before I knew it, I was interviewing people who were seeing me and judging the culture of the company. I went from trying to fit in, to defining what the culture at CF was. All of us did.

I then realised something interesting. Since “CF” itself is a virtual entity that only exists in our shared minds, CF’s culture is just how we perceive the rest of CF. In that sense, each and everyone at CF is playing a part in defining the culture of CF at that moment. When someone joins, they bring something new to the table. When someone leaves, they take something away. 

CF’s culture is as dynamic as the people it is made up of and suddenly, “How will we keep the culture at CF the same?” — a question that gets asked a lot whenever we speak of hiring — automatically turns into “How will we hire the kind of people we’d like representing CF?”, and I think that is a more useful question.

Lesson #6 – There’s more to life than just work

My first day at CF was 14th of January, 2019. I was busy setting up my laptop and various company accounts, and reading some documentation. At around 6.30pm, Megan came to my table and said “that’s enough for the first day — go home now”. I looked around and almost everyone had already left.

This was strange to me. It was still a couple of hours till dinner time. Why not just keep working and go straight to dinner?

You see, I didn’t have leisure time in my vocabulary back then. It was always doing something. Working, eating, sleeping, coding, studying. Something. 

I grew up with a hustle-culture mindset where if I’m not working 10 hours a day and coding in my free time, I’d not consider myself “ambitious” and probably not “make it”. Berlin and CF changed all of that.

All of a sudden, I had at least a couple of hours every day, and two full days of weekend when I wasn’t expected to keep working. I could do something else. But what? 

Anything.

I started pursuing hobbies that weren’t career related or would ever be monetized. I started biking and playing chess, painting and playing music or just sitting by the canal doing absolutely nothing. 

It is nice to not have to constantly think of free time as wasted time, and I have CF and Berlin to thank for this huge change in my way of thinking and living my life.

Thank you, dear friends

I am grateful for everything I’ve learned from the people at CF. It has made me a different and, in my opinion, better version of myself, and I can’t thank you all enough. I’ll pay it forward wherever I end up in life.

All the best – Abhi!

Crossposted from Linkedin

Puzzle Time – Distance To Horizon

A couple of months ago I was on a flight and had a thought: How far is the horizon at this very moment?

I got my notebook and pen out and tried to solve this using only the knowledge I had, since there was no internet anyway. Of course, many assumptions were made as were convenient for the calculation.

I planned on checking my answer once I landed. If you want to attempt it, stop reading here and come back later when you have a solution. Unfortunately for me, I made a little error subtracting between two big numbers and got a completely wrong answer.

Assumptions

I assumed the following

  • Perfect visibility, no degradation due to atmosphere
  • Earth is a perfect sphere with a radius of 6400km
  • Aeroplane flying at an altitude of 10km

Solution

Thanks to the assumptions, the problem reduces to primary school geometry problem and is trivial to solve once visualized clearly on a piece of paper.

Using Pythagoras Theorem we know how to calculate the third side of a right angled triangle give the first two. We also know that a tangent to a circle (the line of sight from an aeroplane) meets the circle in a way that it is perpendicular to the radius drawn from the point of contact.

Combining the two pieces of knowledge, the problem can be trivially arranged as follows

(R + r)² = R² + Dh²

Where

  • R is the radius of the earth (in Kilometers)
  • r is the distance of the aeroplane from the surface of the earth (in Kilometers)
  • Dh is the distance to the horizon

Rearranging, we get

Dh² = (R + r)² – R²

Expanding the (a + b)² equation

Dh² = R² + 2Rr + r² – R²

Dh² = 2Rr + r²

Taking square root on both sides

Dh = √(2Rr + r²)

Substituting the values

Dh = √(2*6400*10 + 10²)

Dh = √(128000 + 100)

Dh = √(128100)

Dh = 357.9

Distance to horizon is about 358 kilometers when the aeroplane is at an altitude of 10 kilometers. Now looking at the map while sitting in a flying aeroplane is a lot more insightful as I can guess which cities I’m looking at outside the window.

That’s it for this little post. Thank you for reading!

Cross Site Scripting (XSS), Cross Site Request Forgery (CSRF) And Server Side Request Forgery (SSRF)

XSS, CSRF (or XSRF) and SSRF are common vulnerability in modern web applications where an attacker tries to imitates either a legitimate client to an unsuspecting server or a legitimate server to another unsuspecting server. The basic underlying principle behind each of these attack remains the same; performing action on behalf of a legitimate entity. Let’s look at each of them in a bit more detail and learn about how to protect our web applications against each of them.

XSS (Cross Site Scripting)

XSS or Cross Site Scripting occurs when an attacker manages to execute malicious script code in a victim’s browser as the victim. Browsers store a lot of sensitive information in them. Some of this information is used to identify a user on a website.

A script loaded from a website can access information stored on your browser through that website, which is how sessions work in your browser. That’s how Facebook or any other website knows to show you your personalized information and not someone else’s.

XSS occurs if an attacker gets control over the scripts running in your browser. If they can execute code, they can steal your login credentials and trick you into installing malware on your computer.

There are different kinds of XSS attacks and they depend on where the payload is stored.

Reflected XSS

A reflected XSS vulnerability occurs when a piece of data from a URL is reflected back into the website code unsanitized and can be injected into. This can be a result of a GET or a POST request, and it is especially severe as an unauthenticated GET request as that URL can be shared on social media and anyone clicking on it gets compromised.

Remediation of reflected XSS – Sanitization of all user inputs before passing it back into the view

Stored XSS

A stored XSS vulnerability occurs when a web application stores an XSS attack payload without sanitizing it and then displays it back to the same user or a different user. A notable recent example is British Airways website getting compromised and exposing sensitive data including credit card information of 380,000 transactions.

Remediation of stored XSS – It is the same as with reflected XSS: Sanitization of all user inputs before storing the data in the database.

DOM based XSS

Unlike reflected/stored XSS, a DOM based XSS occurs only on the client’s side. This can be a result of a user typing in a string into an input field that gets parsed and executed as code. An attacker can trick a user to paste a string into their browser which will execute due to insecure parsing and compromise a user’s credentials.

Remediation against DOM based XSS – Display text as text, and nothing else. Instead of element.innerHtml use element.innerText or element.textContext to ensure the data displayed back to a user is purely text.

CSRF (Cross Side Request Forgery)

CSRF occurs when a malicious website makes a request to a legitimate server through an unsuspecting victim.

Web applications communicate with clients through HTTP requests. When a request is made, the browser attacks all information that it knows about the website along with the request, including login/authentication credentials (called cookies).

If the web server doesn’t have protective measures, a request made through a legitimate website and an attacker’s website look exactly the same (or they can be forged to look the same). As a result, an attacker can make a request telling the victim’s bank to transfer $100 to the attacker’s account, and since the request is made through the attacker’s browser, the bank’s server will process it as a legitimate request.

Remediation of CSRF – CSRF can be easily prevented by requiring any unsafe request to validate itself using a valid CSRF token that can only be found in the website’s code and changes on every use. Additionally, authentication/login cookies can be marked as sameSite only, such that any third party website making the request doesn’t contain the sensitive authentication cookies.

SSRF (Server Side Request Forgery)

SSRF is similar to CSRF, but instead of an compromised client making a request to an unsuspecting server, here a compromised server makes a request to itself or another unsuspecting server.

Since a server might be a privileged node in the network, the attacker can make the server access and return sensitive information or perform privileged actions that the attacker’s account wouldn’t allow.

SSRF can also be used to trigger code execution in servers where the vulnerability can be exploited using the privileges of the server itself.

Remediation of SSRF – Any outgoing request needs to be explicitly allowed from the application by maintaining an allowlist of domains and servers a given server can connect to. The scope of these requests should be made as narrow as possible.

In conclusion

I hope that was an interesting quick read on one of the most common vulnerabilities in modern web application. Injection and SSRF are two of OWASP’s top 10 for 2021, so it is definitely worth looking into them and protecting our web applications from potential vulnerabilities.

Read more on OWASP top 10 here: https://owasp.org/www-project-top-ten/

Thank you for reading

nginx blocking malicious request

Setting Up ModSecurity + OWASP Core Rule Set + Nginx On AWS EC2

ModSecurity is a web application firewall. It can protect your web application from preying eyes of vulnerability scanners and attackers. It is extremely customizable, and when paired with OWASP’s Core Rule Set, covers quite a lot of web technologies and frameworks.

In this article, we’ll set up ModSecurity on an AWS EC2 Server running Nginx web server.

Table of contents

Set up Nginx on Ubuntu server

For this tutorial, we’re using AWS LightSail’s Ubuntu image. Choose any instance size depending on your requirements. I’ll choose a 40$ / Month instance with 8GB RAM and 2vCPUs just so that the compilation of ModSecurity is faster.

Once the instance is created, log into the instance with SSH and update packages

$ apt update && apt upgrade -y

Install Nginx

$ sudo apt install nginx

Check what version of Nginx did we get from our package manager. This will be used when compiling Nginx later.

$ nginx -v

I got the following output:

nginx version: nginx/1.18.0 (Ubuntu)

To make sure the webserver is successfully installed and running, simply visit the IP address of the server. It should look something similar to this:

Set up ModSecurity

First we’ll need to install compilation and other dependencies.

$ sudo apt-get install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev git

Next we’ll clone the ModSecurity repository into the /opt directory

$ cd /opt && sudo git clone --recursive https://github.com/SpiderLabs/ModSecurity && cd ModSecurity

Next we run the build script

$ sudo ./build.sh

Next we’ll run the compile script that will fetch all the dependencies for the compilation

$ sudo ./configure

It is possible that this command fails and reports you of any dependencies that are still missing. You can simply google them with “install XYZ on Ubuntu” and run the configure command again. Ideally it will just exit without any errors.
Next we start with the actual compilation of ModSecurity

$ sudo make

A reason why I didn’t go with the smallest server was that this step is resource intensive and could take 15 minutes or more depending on your server’s CPU and memory.

If all went through, we can now install ModSecurity

$ sudo make install

If all went through without any errors, we have ModSecurity installed.

Set up ModSecurity <-> Nginx connector

We start off by downloading ModSecurity-Nginx and Nginx source code. Note that the version of Nginx in the next command must match the version installed on our system. For me, that’s 1.18.0 but it could be different for you.

$ cd /opt && git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
$ cd /opt && sudo wget http://nginx.org/download/nginx-1.18.0.tar.gz

Untar the Nginx source. Replace the Nginx version in the next command if needed.

$ sudo tar -xvf nginx-1.18.0.tar.gz

Next, we need to grab configure arguments. For that, run the nginx command with a capital ‘V’ flag.

$ nginx -V
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-7KvRN5/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Note the “configure arguments” in the command’s output. We need to build modsecurity with these arguments.

$ sudo ./configure --add-dynamic-module=../ModSecurity-nginx <paste configure args here>

For example, here’s what I’ll run:

$ sudo ./configure --add-dynamic-module=../ModSecurity-nginx --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-7KvRN5/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Don’t copy the above command. You must use the configure arguments supplied by your installation of Nginx.

Next we build the modules

$ sudo make modules

This is a compilation step and may take a little while (a minute or so) to complete. The final step here is to copy the compiled modules to a place from where we can reference them from our Nginx config.

$ sudo mkdir /etc/nginx/modules
$ sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules

Loading ModSecurity module in Nginx

Simply add the following line to the nginx config file at /etc/nginx/nginx.conf outside any block.

load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;


Set up OWASP Core Rule Set

OWASP’s Core Rule Set is a set of rules that cover most common frameworks and technologies as well as cover signatures for common web application attack payload. It is a good place to start if you don’t want to write custom rules for many common attacks.

First, we’ll clone the modsecurity-crs repository

$ sudo git clone https://github.com/coreruleset/coreruleset /opt/coreruleset

Then we’ll rename the crs-setup config file

$ sudo mv /opt/coreruleset/crs-setup.conf.example /opt/coreruleset/crs-setup.conf

Activate the default exclusion rule file.

sudo mv /opt/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /opt/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

Next we create a place for coreruleset to live within /etc/nginx and copy some additional config files.

$ sudo mkdir -p /etc/nginx/modsec
$ sudo cp /opt/ModSecurity/unicode.mapping /etc/nginx/modsec
$ sudo cp /opt/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf

Next we create a config file that will include our main ModSecurity config file and CRS setup files.

$ sudo touch /etc/nginx/modsec/main.conf

And add the following lines to the config file.

Include /etc/nginx/modsec/modsecurity.conf
Include /opt/coreruleset/crs-setup.conf
Include /opt/coreruleset/rules/*.conf

Finally, we reference this main.conf file from our Nginx config.

$ sudo vim /etc/nginx/sites-available/default

And add the following line within the server block.

modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;


Turn ModSecurity “on” and test XSS payload

So far, we’ve configured everything but if we restart Nginx now, it won’t filter attacks but only detect them since the default operating mode of ModSecurity is to only log malicious requests. To change that, let’s open the file /etc/nginx/modsec/modsecurity.conf and change the line

SecRuleEngine DetectionOnly

to

SecRuleEngine On

For our changes to go live, we’ll need to restart Nginx.

$ sudo systemctl restart nginx

Let’s test our ModSecurity installation. Open your browser and send a sample payload in the GET parameter. It doesn’t have to be a real parameter, but just something that can trigger an XSS filter.

http://[server-ip]/index.html?xss-payload=<script>alert(1)</script>

That’s ideal. ModSecurity is working and blocking seemingly malicious requests to our web server. Now any application that sits behind our web server will be protected against many generic web application attacks, even OWASP Top 10 thanks to OWASP’s CoreRuleSet.

In conclusion

It isn’t the most straightforward of installations, but it isn’t very difficult either. The hard part, however, starts here and it is to get rid of all false positives and tweak the installation such that it fits the needs of your specific web application. Depending on how complex an application you’re trying to protect, it can be fairly time consuming.

I’ll write an article on how to tweak the parameters of ModSecurity and make it fit our needs in the future in a separate article.

That’s it for this article, thank you for reading!

WordPress Security Checklist: How To Secure Your WordPress Website

WordPress has been powering my blog since the start of last year. In fact, migrating my Jekyll template to WordPress was one of the highlights of my new year 2021 and I’m very happy that I did, although I didn’t publish as much as I had hoped for. Fortunately, I’ve learned a lot more about WordPress over the course of a year than when I started. In this short primer, I hope to go into a bit more depth on how to securely run a self hosted WordPress website.

Prerequisites

Before we get started, there are a few things that we need to make sure we have to

  • Self hosted WordPress installation with SSH access
  • Administrator account to set up plugins

Table of contents

  1. Keep plugins to the minimum and up to date
  2. Fix file permissions
  3. Two-Factor Authentication
  4. Set up auto banning of failed logins
  5. Enable regular backups
  6. Disable XML-RPC
  7. Disable file editing in WordPress admin
  8. Use a Web Application Firewall
  9. Don’t forget the usual web security measures

1. Keep plugins to the minimum and up to date

I wish I could just sticky something like this on top of most of my articles, but most people trying to attack our websites don’t have the time or resources to develop and use 0days. They use existing exploits out in the wild and some of these exploits can be months old, if not more. WordPress core and plugin authors can only do so much more than promptly releasing patches for security vulnerabilities that they find.

So then it is up to us as site admins to make sure we patch as soon as is feasible. Having worked on many large codebases, I know automatic updating isn’t always possible or even desirable, but having an eye on the changelog can definitely help not get compromised.

I’d also recommend a web security helper plugin that sends alert emails when it detects outdated plugins / themes / core.

2. Fix file permissions

During development, many files and directories permissions are way too open to make it easy to set up the website and all plugins. In production, however, the permissions can be dialed down a notch to prevent anyone with any access on the server to take over the whole website.

Similarly, attackers typically upload shell code using the uploads functionality, and if code execution is disabled in the directory, we make it harder for this attack to succeed.

A detailed guide on setting file permissions can be found on official WordPress documentation: https://wordpress.org/support/article/changing-file-permissions/

3. Two-Factor Authentication

Administrator accounts have many powers on a WordPress website, and a compromised administrator account can lead to uploading of PHP shell code leading to command execution and server compromise.

To make sure admin accounts are extra secure, enforce 2FA on all administrator accounts. This can be done by any 2FA or login security plugin on the WordPress plugin store.

4. Set up auto banning of failed logins

Since WordPress doesn’t ship with any builtin way of auto-banning failed login attempts, we have to rely on plugins like WordFence. WordFence will need to be configured with options to block login attempts after a certain number of failed attempts.

WordFence can also help you disable execution in upload directories, block IP addresses making malicious requests and much more.

5. Enable regular backups

While we can take preventive measures against mishaps, we can never be sure. Hence it is imperative that the website is backed up regularly. Backing up can be done at multiple places. The database can be backed up separately from the static assets and files. There are many plugins, like WPVivid, that help you fine tune what gets backed up and where it gets stored. It is always nice if you can afford an external backup location, like AWS S3.

The hosting provider might also have ways of backing up the website. For example, AWS Lightsail has daily instance snapshots which backs up the entire disk.

6. Disable XML-RPC

If you don’t use plugins that rely on XML-RPC or using the WordPress mobile app, it is wise to disable XML-RPC which removes another widely used attack surface by attackers. Many plugins allow the disabling of XML-RPC, including the aforementioned WordFence.

7. Disable file editing in WordPress admin

Disable editing of files from WordPress admin as that’s almost never a good idea, especially if you can achieve the same using more secure methods like SSH. To disable file editor, simply add

define( 'DISALLOW_FILE_EDIT', true );

to your wp-config.php file.

8. Use a Web Application Firewall

A firewall plugin like Sucuri or WordFence can identify attack signatures and block malicious requests. Many also include IP address block lists that prevent known malicious IP addresses from reaching your WordPress website.

For more control, there’s ModSecurity. ModSecurity needs to be installed alongside the web server and it can detect and block known attack signatures for not just WordPress but just about any popular web framework. It does require a deeper technical know how to setup and maintain ModSecurity, and a plugin might work be a better approach for most people.

9. Don’t forget the usual web security measures

A WordPress website is, at the end of it all, a website. While there are WordPress specific ways of hardening a WordPress installation, there is also a whole plethora of best practices that apply to every website, including the WordPress ones.

  1. Use HTTPS – SSL/TLS certificates are free, and usually come by default with many hosting providers and CDNs. Don’t forget to turn it on and enforce it in strict mode.
  2. Use appropriate security headers – Headers tell the browser how to handle your website’s content. Many client side attacks can be mitigated by using the right set of headers. A detailed list of useful headers can be found on OWASP’s website: https://owasp.org/www-project-secure-headers
  3. Use CAPTCHA on login page – to prevent bot submissions and more sophisticated bruteforce attacks, enforce a CAPTCHA like reCaptcha on login page. WordFence supports this out of the box (needs an API key from Google).
  4. Handle user input with care when using a custom theme – when using a custom theme that accepts user input in the form of query parameters to show filtered content, the regular best practices around user generated input has to be followed. Embedding user input in output can lead to Cross Site Scripting, while passing it straight to the database can lead to SQL Injection.

In conclusion

I hope that was useful. If you have any questions around WordPress or suggestions to improve this article, feel free to reach out to me via email. Thank you for reading!

Perfect 100/100 PageSpeed Score With WordPress

A long time ago I worked on a theme called Elementary for my Jekyll blog. The goal was simple, to create a website that just works, and works fast. In fact, I’ll just paste the line from the readme of the GitHub repository.

This is my personal blog’s Jekyll template that I’ve been optimizing for performance, accessibility, usability, readability and simplicity in general.

I personally do not approve of personal blogs bloated with hundreds of kilobytes of trackers and analytics code, and hence, this is an attempt at creating something that I’d be comfortable with using on my website.

The goal was accomplished. I managed to get a perfect score on many of the pages. But I wanted to write more and while on the go, and plaintext editing on phones is a pain. Then the other problem was to add it to git and push it. In short, working with a static blog from an Android phone wasn’t easy.

That’s when I moved to WordPress. I ported the theme to Elementary-WordPress, which is essentially the same theme but in a WordPress shell. It worked really well, but the problem was all the bloat that WordPress sends to the frontend. For a while I didn’t care enough. I was still serving a fast website, albeit with Jquery, emojis and other code that wasn’t getting used anywhere else.

Today, that changed. I finally took some time to optimize the website and got back my perfect 100/100 PageSpeed score. Here’s how I did it.

Table of contents

  1. Disable jQuery
  2. Disable wp-embed
  3. Disable block library CSS
  4. Disable emoji
  5. Serve fonts from same domain
  6. Use font-display: optional property
  7. Use an in-memory page cache like Memcached
  8. Fix conflicting cache strategies
  9. Use a CDN for asset delivery
  10. TODO: Inline all CSS and Javascript

Disable jQuery

If your website isn’t ancient, there’s a good chance you’re not using it. If some plugin you’re using is using jQuery, consider alternatives. It will save you ~30KB and an HTTP request. Adding the following to the functions.php should do it.

function jquery_dequeue() { 
  wp_deregister_script( 'jquery' );
}
add_action( 'wp_enqueue_scripts', 'jquery_dequeue' );

Disable wp-embed

The following snippet from this answer needs to be added to functions.php

function wp_embed_dequeue() {
  wp_deregister_script( 'wp-embed' );
}
add_action( 'wp_footer', 'wp_embed_dequeue' );

Disable block library CSS

*Sigh* This goes into the functions.php

function remove_wp_block_library_css(){
  wp_dequeue_style( 'wp-block-library' );
}
add_action( 'wp_enqueue_scripts', 'remove_wp_block_library_css' );

Disable emoji

I found some nice code to disable a whole bunch of unnecessary actions from this guide here: https://kinsta.com/knowledgebase/disable-emojis-wordpress/#2-disable-emojis-in-wordpress-with-code

Serve fonts from same domain

If you’re not super keen on using the smart browser detection functionality that Google Fonts offers and are happy only supporting modern browsers, simply downloading the font files and linking them with @font-face can save an additional DNS and HTTP request.

Use font-display: optional property

I’m using font-display: optional; CSS property on my @font-face and it pushed my PageSpeed score over the top. Essentially it prevents the CLS, or Cumulative Layout Shift metric of Core Web Vitals from getting affected due to page shifting due to slow loading of font files.

Read more about it here: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display

Use an in-memory page cache like Memcached

Building pages to serve the users is expensive as it involves the database, but isn’t something that needs to be done for every visitor visiting the same page. A plugin like W3 Total Cache coupled with a Memcached instance (could be running on the same server as the website) could enable caching of pages among other resources in memory, reducing the load on the server and improving performance for cache-hit pages.

memcached

Fix conflicting cache strategies

I’m using W3 Total Cache plugin that helps minify and cache CSS and JS files. But I wasn’t seeing any minification happening. Upon some reading, it turns out that CloudFlare’s minification conflicts with W3 Total Cache’s. Disabling it on CloudFlare’s side fixed the non-minification problem for me.

Use a CDN for asset delivery

Once the thing to deliver is optimized, it is a good idea to optimize the delivery pipeline as well. Since my server is in the same country as me, it is easy to make a mistake of thinking every visitor of the website is seeing a 50 milliseconds time to connect to the server. The further the user is from the origin server, the longer it could take.

Hence, an global CDN like CloudFlare should be used which can serve static content from its edge node physically closest to the visitor.

TODO: Inline all CSS and Javascript

It doesn’t go beyond 100, but I’d still like to improve it further. For one, the little bit of CSS and JS that does exist doesn’t have to need two additional HTTP requests. Inlining that bit will mean that blog posts without an image, which for me are most of them, will get served in only three HTTP requests; the document, the font file and the favicon. Pretty cool, huh?

Conclusion

I’m pretty pumped about the 100/100 score. WordPress has a reputation for being slow and bloated, but with some simple optimizations, it starts performing like how you’d expect some text on a page to perform like.

Thank you for reading!

A Primer To Slow Thinking

I see that I’ve picked up this habit of keeping half finished articles in the backlog. Need to fix that. Anyway, let’s hope this article gets to see the light of day on the internet.

I wanted to write some of my current thoughts on the idea of slow thinking. I’d warn you before we start that none of what you’ll read in this article is a novel thought of my own. Rather, it is an aggregate of the various different books I read in the past three months, many of which pointed me towards this idea. It is just my interpretation of the idea, but I’d like to document it nevertheless.

What is slow thinking?

The way I understood it, slow thinking is the non-reactive way of thinking and responding to a situation. When presented with a situation that sets off strong emotions — especially negative ones like anger, fear or jealousy — the idea is to take a step back and recognize the emotion itself, thereby detaching ourselves from that emotion. It is also handy when dealing with situations that trigger an impulsive reaction, not necessarily a negative one.

From experience, I can vouch for the fact that reacting when in an emotional turmoil isn’t usually the best idea. I’d struggle to find an example of a situation in my life when bursting with anger, screaming at someone, getting violent or very negative brought me any net positive.

Similar, impulsively doing something can sometimes be beneficial, but often, and especially in the modern world we live in, impulses are unwarranted and just a reminiscent of the tribal and fight-for-survival past of humans. Being able to recognize when an impulse is justified and when not can come in handy in many life situations, and the ability to do so can be treated like a skill to hone.

Of course, none of this is to suggest we shouldn’t feel emotions. It is perfectly reasonable to feel sad about some of the world events we’re constantly made aware of, just as it is nice to feel excited about the thought of having a cake or petting a cat. I think the idea here is to recognize the complexities and different parts of the mind that are responsible for different emotions and reactions instead of abstracting it all under the one “you”. The idea is to go from “I’m angry” to “I’m feeling anger” and so on.

The following idea is from Robert Wright’s Why Buddhism Is True. Essentially, one can imagine there to be different modules that keep getting activated and deactivated as we go about our lives, and we live through those modules as long as they are active, like experiencing feelings towards the protagonist in a movie or feeling happiness upon hearing a good news. The modules may be triggered by external stimuli, and as such, we’re not really in control of the orchestration.

Since we’re not orchestrating how exactly we feel or react to a situation, it implies there’s no “you” but a lot of different parts that become “you” depending on the situation and the trigger. Lost a game, the “dejected” module activates. Had a nice time at the park with your partner, the “happiness” or “gratitude” module activates.

Yep, we’re talking in very abstract terms, but that’s okay. There’s no way to comprehend the immense complexities of the inner workings of the mind without spending a lifetime studying the subject like the people whose thoughts I’m borrowing and interpreting did. And like they say, all models are wrong. So as long as this way of thinking helps us better understand why we do what we do, it can be useful.

So how does one slow think?

I don’t think there’s one way to do it. The book I referred to earlier, Why Buddhism Is True by Robert Wright, suggests meditation techniques that can be put to use to recognize our emotions and detach ourselves from them. Thinking, Fast and Slow by Daniel Kahneman educates us about the biases that we might not recognize in our behaviors and that knowledge makes us more aware of our cognitive fallacies. Relationships by The School of Life, speaks about many of the inherent complexities in humans and human emotions and why people behave in certain ways from time to time (of course, with a focus on romantic relationships).

I think it doesn’t matter which way we choose to learn to slow think; it could be through mindfulness meditation, or educating ourselves on the topic of cognitive biases, or understanding the person we’re dealing with and recognizing them as humans and their emotions. The end goal is the same: to be less reactive, judgemental and impulsive, and more curious.

In conclusion

I hope this was a useful primer on the topic of slow thinking. I’m looking forward to putting it to use in my life and seeing how it works for me. That’s it for now. I’ll go back to getting entertained looking at all sorts of interesting people and the life happening at Catania airport.

Thank you for reading!

Learning Photography

We’ve just entered a brand new calendar year, so I’ll start with that. Happy new year everyone!

New year warrants some new learnings, I know. But I’ll start with something that I got into a couple of months ago and that has changed the way I see the world. It is digital photography.

Like probably many people at some point or other in their lives, I started getting unusually fascinated by pictures. Not just pictures for the sake of pretty pictures, but pictures as a medium to tell stories and pictures as a canvas for creativity. At this point, I know for a fact that no matter how trivial an activity looks, there’s usually a lot more than what meets the eye and surely this was the case with photography. After all, it isn’t one of the most popular professions and side hobby for no reason.

I started reading a book (Understanding Exposure by Brian Peterson) that was a gift from a friend and it got me very involved in photography. I understood the basics, and then a bit more. I put into practiced what I’d learned by taking pictures of the places I traveled to and people I met. I used photo editing tools to give extra character to my pictures. I shared them on social media as a reminder to my future self, and now I’m writing this article about how I’m feeling as a reminder to myself but also a general guide to anyone stumbling upon this from search engines.

I’ll list down some interesting avenues where I spent the most time on, and probably you will too in case you decide to take up this beautiful hobby!

Equipment

If you’re like me, this is where you’ll spend the most time in the beginning — finding the right equipment. Any seasoned professional will tell you that it doesn’t matter nearly as much as the many other things you’ll learn down this path. All I can add to that is that the most important aspect of having the right equipment is that you should be excited to use it and carry with you. It doesn’t have to be the most expensive or the most shinny, but it should bring a smile to your face when you pick it up to leave your house (you wanting to pick it up when leaving your house when you go for a walk is implicitly implied here).

If you do basic research before buying stuff online, it is hard to go wrong with your first equipment. You’ll find yourself asking questions like what size sensor the camera should have, or what lenses to go for, but if you have limited money like most people, you’ll quickly realize the best options for a given budget aren’t all that many and from among those, you’ll probably be fine with either as a beginner.

For me, apart from the happiness factor of the equipment, the other very important factor is knowing the limits of your equipment. If it is a beginner’s camera, or a used old pro piece of equipment (or any, for that matter, but especially these), it has to have some quirks that you need to be aware of. Lack of high dynamic range, poor low light performance, not weather proof camera body, lens performance quirks, lack of 4K video or image stabilization to name a few. When you know the limits, you won’t be disappointed when your equipment doesn’t perform as per your expectations. Given how good phone cameras are these days, this is especially important as your phone will most likely take better pictures (bright colors with good contrasts and HDR) than your camera right out of the box.

The last piece of equipment advice is to make it easy to take your camera with you. After the initial excitement runs out, you don’t want to just find an excuse to not have your camera with you. I read somewhere that the best camera and lens is the one you have with you.

Exposure triangle

Even after centuries after the first photograph was ever taken, some of the basics of this trade haven’t changed. At the absolute basic, a photograph is just some light projected on a light sensitive film. This opening of the light sensitive film to light is called an exposure. A good exposure has three important components, forming the exposure triangle. The exposure triangle is formed by a simple set of parameters

  1. How long do we expose the film?
  2. How sensitive the film is?
  3. What’s the size of the opening through which light falls on the light-sensitive film?

They are referred to as shutter speed, ISO and aperture respectively. All three do the same thing — control exposure or amount of light information captured by the film or sensor (in case of digital photography) — but each has its own tradeoffs. A clear understanding of the tradeoffs and when to prioritize what will help you take more controlled pictures.

Exposure triangle
WClarke and Samsara, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons

Shutter speed refers to the amount of time the “shutter” of the camera stays open. The longer it is open, the more light the sensor (or film, but I’ll use sensor as I’m guessing the vast majority of people think of digital photography when they hear the word photography) gathers. But if the shutter speeds are too slow (as in, it stays open for longer), your picture can turn out blurred if the camera isn’t kept steady for the duration of the exposure. On the other hand, too high shutter speeds can result in darker images as there just wasn’t enough light to properly illuminate the sensor.

ISO is the sensitivity or gain of the sensor. Just like with a microphone, increasing the sensitivity or gain increases the amount of sound captured, but also the noise. Digital cameras usually have an ISO range, like 100 to 6400 that you can choose depending on the situation.

Aperture is the size of the opening of the lens that focuses the image on the sensor. Naturally, larger opening results in more light captured. But interestingly, larger openings create a narrower plane of focus (creating beautiful bokah effect) which, while beautiful for some kind of pictures, isn’t always ideal and you have to “stop down” or increase the aperture number or reduce the size of the opening to get the desired depth of field.

Lenses – Reading the specifications

If you are able to afford an interchangeable lens camera (which is quite an appropriate name for a camera that you can attach different lenses to) you’ll be presented with a wide array of lenses you can buy that have very cryptic specifications. While it gets more complicated the more you know, a lens will generally have a few key specifications

Canon 18-55mm kit lens

Focal length

Specifies how wide or zoomed the perspective of the lens is.

Wide angle lenses are useful to capture a wide exposure, like landscapes while zoom lenses are useful to get closer to the subject without getting physically close. As you can guess, zoom lenses rule in the world of animal and sports photography.

It usually is measured in millimeters, and is either one number (For example, 50mm for prime or single focal length lenses) or a range (For example, 18-55mm for zoom lenses).

(Peak) Aperture

It is the measure of how large the camera’s lens can open and as a side effect, how blurry the foreground and background of your picture can get. It is measured in f-stop numbers and just like with focal length, it is either one number (For example, f1.8 for prime lenses) or a range (For example, f3.5-5.6 for zoom lenses).

Apertures
By KoeppiK – Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=78136658

Something to note is that a lens can always “stop down”, or shrink the size of its opening. The number on the lens is the maximum it can open for the focal length.

Just like with focal length, you don’t necessarily need to know what that number technically means to be able to select and operate the lens correctly. But it doesn’t hurt to know.

Image stabilization

Image stabilization is the ability of the lens (or camera) to reduce the impact of shaking on the final picture. Zoom lenses typically have image stabilization, while prime lenses typically don’t. The larger the focal length (or zoomed perspective), the more important having a stabilized lens becomes because the more “zoomed” your perspective is, the more prominent slight vibrations of your hand become.

Composition, and how it changes the way you see the world

While I can spend hours talking about topics like DSLRs vs mirrorless cameras, Sony vs Canon and the like, I think we can all agree those are better suited for Reddit and other internet forums. Here, I’d like to be a bit more personal and talk about something a bit more abstract and not technical. The experience of photography.

I’ve used smartphones with really good cameras. On multiple occasions I’ve owned a mobile phone with camera that was considered “flagship” at the time I bought it. Even then, I wasn’t exposed to the way of photography until I actually got hands on my first DSLR, my first “manual” camera.

I think I understand part of the reason. With phone cameras, you’re an operator of a blackbox. Sure, most phones take decent pictures most of the times (especially these days). They’re consistent, compact, internet enabled and always in our pockets. They’re also quick to share pictures on chat and social apps, which is arguably the end goal for many people taking pictures.

And don’t get me wrong. My phone takes wonderful pictures. Right out of the box, my iPhone 13 takes pictures that are arguably better to look at than my massive Canon 7D’s pictures with their poppy colors and HDR. But there’s no spark, no connection. When I take a good photo with my iPhone, I think the phone did a good job. When I take a bad one, I think the phone did a bad job.

That’s what makes manual photography so interesting. I own the composition and exposure. I envision the result before I take a picture and see if it worked out, and not simply like or dislike it after.

And if I fail, I know why. Or at least I know it was something that I did and I can improve upon it. This realization to see  failure, a bad photo in this case, as just another opportunity to learn something new is what’s different between taking a picture with my phone and my 12 year old Canon DSLR.

The photos themselves have character and a story to tell for they are just an extension of your imagination at this point.

In closing

Ever since I started carrying my camera around, I started seeing beautiful compositions in even the most mundane of things.

butterfly

I started noticing everything consciously for that’s where my next best picture could lie. Everyday streets had graffiti that I had never bothered to look at, or birds and animals and the detail in their creation. Even people and their faces seemed interesting — people that I’d known for years, even my parents. It filled me with gratitude for the beautiful world that we live in, and this experience of being alive.

I learned what “pause and ponder” meant and I started doing that even when I didn’t have my camera with me. Interesting what a hobby can do to you.

Thank you for reading!