Dickimaw Books Blog
Bug Bounty Hunters 🔗
Website Security Vulnerability NotificationThe message ended with the following:Dear Security Team,
We would like to inform you that a security vulnerability affecting dickimaw-books.com website was reported via Open Bug Bounty coordinated and responsible disclosure program. Submission details are available here: https://www.openbugbounty.org/reports/3283279/
Following the ISO/IEC 29147 (“Information technology — Security techniques — Vulnerability disclosure”) guidelines, we verified the vulnerability's existence prior to notifying you. Please contact the security researcher directly for technical details of the vulnerability, his/her profile is available on the submission page. The researcher may also help remediate the vulnerability if you need any assistance. If you received this notification by error, please accept our apologizes and forward it to your IT security team or a person in charge of your website security.
DISCLAIMER: Open Bug Bounty is a non-profit project, we never act as an intermediary between website owners and security researchers. We have no relationship or control over the researchers. Our role is limited to independent verification of the submitted reports and proper notification of website owners by all reasonably available means.
I was given 90 days to fix the issue before the full details in the referenced URL were publicly disclosed.
This is quite an alarming email for a website owner to receive, and unfortunately both messages ended up in the junk folder for the associated email account, which meant that I didn’t notice them immediately.
Was this genuine or a scam? If genuine, I needed to find out what the vulnerability was and how to remedy the problem.
I started searching for information about openbugbounty.org and found conflicting reports, which could be divided into the following categories:
- People who gave a positive report and acknowledged that the bug bounty hunters had alerted them to a vulnerability and helped to fix it;
- WordPress users with absolute faith in the WordPress security settings who cried scam;
- Comments to various posts from people claiming to have been scammed.
The openbugbounty.org site has a banner at the top of the page that reads:
All Open Bug Bounty emails are sent only from openbugbounty.org domain being digitally signed. All others are fake.Their FAQ includes the following:
Can researchers demand a payment in exchange for vulnerability details?No, researchers must not demand anything in exchange for vulnerability details, this a direct violation of our guidelines on ethics and may lead to permanent suspension of the researcher’s account. Please always contact us to report any violations of the guidelines, and we will try to resolve the situation as soon as possible.
In other words, there are scammers who are purporting to be from Open Bug Bounty who are attempting to extort payment from website owners, but they aren’t genuinely affiliated with Open Bug Bounty. I think this explains the third category above. Note that, if the researcher helps you to fix the problem, they may ask you if you are willing to reward them (such as, by writing a review or a small donation) but they can’t demand payment for simply providing you with the vulnerability details. With regard to the second category above, no amount of WordPress security features would have protected my site from the bug that was found, so do take a vulnerability report seriously.
If you receive an email like this, the first thing to do is verify that the submission details link in the message has the exact domain “openbugbounty.org”. Make sure that the suffix hasn’t been swapped (for example, “.net” instead of “.org”) and make sure that there aren’t any extra or missing letters (such as “bugg” or “bouty”). The digitally signed header should encourage your mail server to correctly determine whether or not the email is genuine, but in my case the message was incorrectly classified as spam even though it was digitally signed, so the spam settings aren’t always reliable. Bear in mind that not all vulnerability reports are made via Open Bug Bounty. Just make sure that the sender isn’t trying to spoof a well-known site.
Having determined that the email was genuinely from Open Bug Bounty, I had a look at the report in the provided URL which indicated a cross-site scripting (XSS) vulnerability. My initial assumption was that this issue was due to an unvalidated form parameter in one of the files that made up my website. However, I was still a bit wary about responding to an unsolicited email, so I decided to do some preliminary investigations first.
At the time, this site had several distinct areas:
- The shop was running on osCommerce, an open source e-commerce web application written in PHP that I had heavily customised;
- This blog was running on WordPress, also an open source web application written in PHP, with a custom child theme I had created to add some minor adjustments;
- PHP scripts written by me using a custom class;
- HTML files (with server-side includes and some JavaScript) that were mostly written by me or converted from another format (such as LaTeX, BibTeX or XML).
The shop concerned me most as the database contained postal addresses and telephone numbers of customers, along with their order details (but not credit card numbers as the actual financial transactions are performed by PayPal, so the shop never has access to that information). Since the shop has been closed for sometime (first following PayPal’s decision to drop support for its encrypted payment button and then pending an upgrade to the new osCommerce release), I decided to err on the side of caution and deleted the shop subdirectory and redacted the information in the shop’s database. (I have backups on a local device.) It was probably overkill, but better safe than sorry. The new version of osCommerce requires a completely new installation and migration of the data from the previous version, so I wouldn’t have been able to perform a simple update in the way I’ve done previously anyway.
Next, I had a look through the advisory details linked on the Open Bug Bounty report and saw that some missing security headers had been flagged. (These don’t count as vulnerabilities¹ but are worth addressing.) Most of these were straight-forward to add. With Apache, this can be done in the .htaccess file:
<IfModule mod_headers.c> Header set Strict-Transport-Security "max-age=31536000" env=HTTPS Header always append X-Frame-Options "SAMEORIGIN" Header set X-Content-Type-Options nosniff </IfModule>The trickiest header is the Content-Security-Policy (CSP). The most restrictive setting is “self”, which indicates that all resources (such as files referenced with the
src
attribute in the
img
or script
elements) must come from the
same domain.
Header set Content-Security-Policy "default-src 'self'"This means you can’t have any inline styles or JavaScript, but can load a local file. For example, you can have:
<script src="/path/to/file.js"></script>or
<link rel="stylesheet" type="text/css" href="/path/to/file.css" >but you can’t have:
<script> // some JavaScript code </script>or
<style> /* some CSS code */ </style>You also can’t use the
style
attribute or event
attributes, such as onclick
. So you can’t have
something like:
<button style="background: red;" onclick="myFunction()" >Click Me!</button>This meant that I had to remove as much of this inline content as possible. For example, using
addEventListener
within a
JavaScript file instead of the onclick
attribute.
Unfortunately, there is some <style>
and
<script>
content that’s dynamically created by
the PHP code and so can’t be moved into static files. This can be
dealt with by creating a nonce (a single-use randomly generated
token that’s changed whenever the page is loaded). The nonce can be
added to the <style>
and
<script>
elements with the “nonce” attribute.
The nonce has to be declared in the Content-Security-Policy
header, and this is where things get a bit tricky. The
.htaccess file is static, so the dynamically-generated
nonce can’t go in there. The header can be set in the PHP file, but
multiple Content-Security-Policy headers can only tighten the
restrictions, and adding a nonce attempts to loosen the
default-src 'self'
restriction set in the
.htaccess file. I worked around this by adjusting the
.htaccess file to include a conditional:
<If "%{REQUEST_FILENAME} =~ /\.php$/"> Header set Content-Security-Policy "connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'self'; worker-src 'self'" </IF> <Else> Header set Content-Security-Policy "default-src 'self'" </Else>
This will set the Content-Security-Policy to default-src
'self'
for any file that’s not a PHP file. For PHP files, it
does almost the same as default-src 'self'
, but omits
the style-src
and script-src
parts. These
then need to be set in the PHP file.²
My PHP files all use a custom class, so this is fairly straight-forward to implement with the following functions:
function generate_nonce() { // return a randomly-generated alphanumeric string } public function getCspNonce() { if (empty($this->cspNonce)) { $this->cspNonce = $this->generate_nonce(); } return $this->cspNonce; } public function csp_header() { header(sprintf("Content-Security-Policy: style-src 'nonce-%s' 'self'; script-src 'nonce-%s' 'self' ", $this->getCspNonce(), $this->getCspNonce() )); } public function page_header() { // function called at the start of every page // ... $this->csp_header(); // ... }(where
$this->cspNonce
is a private variable).
Any dynamically generated <style>
or <script>
elements need to be adjusted to
include the nonce. For example,
echo '<script nonce="', $myClass->getCspNonce(), '" >';
This was fine for all my PHP files, but not for the WordPress files. I could add the header via my custom child theme, but there were too many instances of inline JavaScript or styles in files that would be overwritten on the next update. Newer themes are template-based and I couldn’t find a way of hooking into them. In the end, I decided that (since I was the only person with a WordPress account on this site and I didn’t need most of the WordPress features) it was simpler to delete WordPress and reimplement the blog using a method similar to other pages on this site, such as the gallery and book list. This has the added advantage of reducing the number of accounts and databases I need to manage the site. Additionally, the site-wide admin account is protected by 2FA and the admin directory is password-protected (in addition to requiring an admin session login), which wasn’t the case with WordPress.
I went through every page on the site map with the Web Developer Tools console open. That’s when I finally found an HTML file that had some JavaScript with an unchecked value from an input element. I guessed that was the XSS issue and, after correcting it, I finally decided to contact the security researcher.
Turns out my guess was wrong. I had found and fixed a vulnerability, but the actual one reported was rather more serious. If I hadn’t been quite so suspicious about responding to an unsolicited email, I would’ve found this out sooner.
The vulnerability (cPanel CVE-2023-29489) makes it possible to execute arbitrary JavaScript, pre-authentication in the context of a victim, on almost every port of a webserver using cPanel within its default setup. It has a CVSS3 score of 6.1, which is classed as medium severity with low attack complexity (that is, no complex knowledge is required on the part of the attacker). Fortunately, it does require user interaction (other than the attacker) in order to exploit the vulnerability.
I verified the proof of concept sent to me by the 4websecurity team (who logged the issue on Open Bug Bounty). The non-invasive probe that demonstrated the flaw by-passed the newly-added Content-Security-Policy header that would ordinarily have caused my browser to block the attempt on any regular page on the site.
The issue has been fixed in a recent cPanel update, but any website running on an older version is vulnerable. The advisory was published by AssetNote on 26th April 2023 following on from the public disclosure on the cPanel website on 1st March 2023. The email I received from Open Bug Bounty was sent on 30th April. I suspect there is now a race between security researchers trying to alert owners of vulnerable websites and cybercriminals trying to exploit the flaw.
So if you have a website running on cPanel, make sure that the version is any of the following or above:
11.109.9999.116 11.108.0.13 11.106.0.18 11.102.0.31
Some cPanel installations have automatic updates. Those installations will already have a patched version. Unfortunately, because I was on a shared hosting account, I didn’t have this feature. I contacted my web hosting provider. Their engineers are working on it, but the complexities of shared hosting means that it takes time to implement. Although shared hosting provides a cheap solution for low budgets, this is one of their drawbacks.
Since the web hosting company was unable to provide an estimated time when the issue would be resolved, I decided to switch to another web hosting company, Hostinger, having first checked that they didn’t have the issue as well. This took about a week and, in the meantime, I received another email from Open Bug Bounty with a second report about the same issue from another security researcher before the switch in servers finally took effect.
The migration to Hostinger took a while. I think I moved at a busy time for them. I had a problem initially trying to log in, but I found a sales email address on their contact page and got a prompt response and the issue was soon resolved. I signed up for their migration support, but I got stuck in a 24 hour queue. When it was finally my turn, the migration failed as they hit a 403 trying to pull my files from the old server. I decided to migrate everything over myself. It would’ve been quicker if I’d opted to do that in the first place.
Having pulled my website apart in the bug hunt, I’m now in the process of putting it back together again. There are still some pages with inline styles. These are mostly HTML files that were generated via some conversion tool, such as LaTeX2HTML for the LaTeX books. It will take me a while to fix them all. I’m now getting messages from Google Search Console complaining about 404 errors from pages in my site map. These are most likely the shop pages. I’m in the process of adding these back, but I still need to decide whether or not to install the new version of osCommerce or find some other solution before I can reopen the shop. If you are waiting for updates to any of my free software or LaTeX packages, please be patient.
The timing of it all was unfortunate (and there was a certain amount of irony) as it coincided with the publication of my new cybercrime short story Unsocial Media. So instead of a fanfare 🎉 on the publication date, I had a message about the disruptions to the website.
Thank you to 4websecurity for promptly responding to my query for further details and for alerting me to the problem. I bought them coffee and gave them 100%-off coupons for all my ebooks. (I don’t know if they like fiction, but I don’t have any Dickimaw swag and, well, what else do you expect from an indie author?)
¹Your browser should adhere to headers it recognises to protect you, but bad bots won’t bother to honour them.
²[Update 2023-06-17] After migrating to a new server that uses LiteSpeed instead of Apache, the PHP code described here to set the CSP header dynamically no longer has an affect. However, it’s important to remember that the security headers are intended to protect website visitors in the event that the site is compromised, but they don’t prevent the server from being compromised (see previous footnote).
2023-05-22 (updated 2023-06-17)Next Post
Previous Post
Recent Posts
Search Blog
📂 Categories
- Autism
- Books
- Children’s Illustrated Fiction
- Illustrated fiction for young children: The Foolish Hedgehog and Quack, Quack, Quack. Give My Hat Back!
- Creative Writing
- The art of writing fiction, inspiration and themes.
- Crime Fiction
- The crime fiction category covers the crime novels The Private Enemy and The Fourth Protectorate and also the crime short stories I’ve Heard the Mermaid Sing and I’ve Heard the Mermaid Sing.
- Fiction
- Fiction books and other stories.
- Language
- Natural languages including regional dialects.
- (La)TeX
- The TeX typesetting system in general or the LaTeX format in particular.
- Music
- Norfolk
- This category is about the county of Norfolk in East Anglia (the eastern bulgy bit of England). It’s where The Private Enemy is set and is also where the author lives.
- Security
- Site
- Information about the Dickimaw Books site.
- Speculative Fiction
- The speculative fiction category includes the novel The Private Enemy (set in the future), the alternative history novel The Fourth Protectorate, and the fantasy novel Muirgealia.
🔖 Tags
- Account
- Alternative History
- Sub-genre of speculative fiction, alternative history is “what if?” fiction.
- book samples
- Bots
- Conservation of Detail
- A part of the creative writing process, conservation of detail essentially means that only significant information should be added to a work of fiction.
- Cookies
- Information about the site cookies.
- Dialect
- Regional dialects, in particular the Norfolk dialect.
- Docker
- Education
- The education system.
- Ex-Cathedra
- A Norfolk-based writing group.
- Fantasy
- Sub-genre of speculative fiction involving magical elements.
- File formats
- Hippochette
- A pochette (pocket violin) with a hippo headpiece.
- I’ve Heard the Mermaid Sing
- A crime fiction short story (available as an ebook) set in the late 1920s on the RMS Aquitania. See the story’s main page for further details.
- Inspirations
- The little things that inspired the author’s stories.
- Linux
- Migration
- Posts about the website migration.
- Muirgealia
- A fantasy novel. See the book’s main page for further details.
- News
- Notifications
- Online Store
- Posts about the Dickimaw Books store.
- Quack, Quack, Quack. Give My Hat Back!
- Information about the illustrated children’s book. See the book’s main page for further details.
- Re-published
- Articles that were previously published elsewhere and reproduced on this blog in order to collect them all together in one place.
- Sale
- Posts about sales that are running or are pending at the time of the post.
- Site settings
- Information about the site settings.
- Smile for the Camera
- A cybercrime short story about CCTV operator monitoring a store’s self-service tills who sees too much information.
- Story creation
- The process of creating stories.
- TeX Live
- The Briefcase
- A crime fiction short story (available as an ebook). See the story’s main page for further details.
- The Foolish Hedgehog
- Information about the illustrated children’s book. See the book’s main page for further details.
- The Fourth Protectorate
- Alternative history novel set in 1980s/90s London. See the book’s main page for further details.
- The Private Enemy
- A crime/speculative fiction novel set in a future Norfolk run by gangsters. See the book’s main page for further details.
- Unsocial Media
- A cybercrime fiction short story (available as an ebook). See the story’s main page for further details.
- World Book Day
- World Book Day (UK and Ireland) is an annual charity event held in the United Kingdom and the Republic of Ireland on the first Thursday in March. It’s a local version of the global UNESCO World Book Day.
- World Homeless Day
- World Homeless Day is marked every year on 10 October to draw attention to the needs of people experiencing homelessness.