• Book review: The Seven Husbands of Evelyn Hugo

    “The Seven Husbands of Evelyn Hugo” is a fictional biography. It describes the life of Evelyn Hugo, a Hollywood actress.

  • HTMX does not play well with content security policy

    HTMX is a JavaScript framework that makes it possible to replace DOM elements with dynamic data from AJAX requests, specified by HTML attributes. Because dynamic behavior is added to the page using normal HTML tags with custom attributes, it is difficult to provide additional security against cross-site scripting (XSS) attacks.

  • Seed of random number generator carried across connections in MariaDB

    I found a vulnerability in MariaDB where it is possible to influence the state of the random number generator for another user’s session. This random number generator is also used for password authentication, making it possible to perform replay attacks by fixing the “random” data.

  • String comparison timing attacks

    Strings that have more characters in common take longer to compare. This can result in a timing attack. However, in practice strings are often not compared one byte at a time, and time differences are very small. Therefore, timing attacks are not necessarily possible, even when using strcmp or == to compare strings.

  • Twig retrieves each attribute twice on Eloquent models

    Using the Twig template engine with Laravel Eloquent models works, but is slower than it needs to be since Twig and Eloquent have a hard time determining which attributes actually exist.

  • Create objects instead of strings

    URLs and HTML can be constructed securely by first creating an object and then serializing that to a string, instead of concatenating strings directly.

  • Curl facilitates header injection

    Header injection is possible by adding newlines in a header. This makes sense for HTTP/1, but HTTP/2 headers can technically contain newlines. When using curl, however, header injection is still possible even with HTTP/2.

  • MySQL's random number generator

    MySQL and MariaDB have a RAND function that is supposed to return random numbers. However, the numbers it returns are not particularly random.

  • A practical attack on Hashids

    Hashids is an algorithm that converts numbers to string tokens and back. It’s similar to base64 encoding, but with extra steps. For example, it can convert 77305 to NgDmz. It takes a salt parameter that alters the encoding, but this salt can be recovered by looking at pairs of numbers and tokens.

  • Securing HTML fragments returned by API endpoints

    A web application frontend often performs requests to a backend API. Even though this API is only supposed to be used by the frontend, it is usually also accessible with a browser. An attacker can use this to exploit vulnerabilities.

  • I made a client-side spamfilter for Tutanota email

    I created a spamfilter that runs in the browser for my personal email.

  • Tweakable block ciphers

    With block ciphers, using a different key results in a different encryption. Sometimes it is also useful to have different encryption without changing the key. That’s were tweakable block ciphers come in.

  • Origin header in password reset email

    Some applications use the Origin header to determine their own domain. This can result in account takeover when used in password reset emails.

  • Block ciphers with a 64 bit block size

    There are many 64 bit block ciphers, but few have a good security reputation. Use Blowfish.

  • Short session expiration does not help security

    When logged into a web application, the session does not remain valid forever. Typically, the session expires after a fixed time after login, or after the user has been idle for some time. How long should these times be?

  • Encrypting identifiers

    In the previous post, I suggested encrypting identifiers in URLs. However, it turns out there is no straightforward way to do this. The current best practice is to don’t do it at all, and use a database mapping instead. In this speculative post we explore the problem and what it would take to encrypt identifiers anyway.

  • Security of identifiers

    This UUID has one weird trick to remain globally unique - database indices hate him!

  • My experience with organizing a giving game

    My girlfriend and I organized a giving game, where participants had to donate to a charity of their choice. I explained how to rationally choose a charity, but in the end most people chose a charity to which they were emotionally attached.

  • MIME type sniffing and the X-Content-Type-Options: nosniff header

    To render things correctly, browsers want to know the file type of a response. The Content-Type response header indicates the file type, but the browser also looks at the content of a response and guesses the file format. This “sniffing” can be disabled with the header X-Content-Type-Options: nosniff. Even though sniffing vulnerabilities are not as common as in the days of Internet Explorer, this nosniff header is still useful.

  • IP spoofing and SQL injection in Textcube

    Textcube is a open source blogging application. It contains a SQL injection vulnerability in a HTTP header that is used to determine the client’s IP address.

  • Cookie prefixes turn security problems into functional problems

    Adding a prefix to a cookie enables security measures in such a way that the cookie doesn’t work anymore in an insecure setting. This makes the problem easier to notice by the developers. A working but insecure cookie wouldn’t be noticed until the next pentest, but a cookie that doesn’t work at all will quickly be investigated.

  • XSS in ViewVC

    I found a cross-site scripting (XSS) vulnerability in ViewVC, a source code repository web frontend.

  • Should 2FA secrets be encrypted?

    When setting up two-factor authtentication using time-based OTP, the client and secret agree on a symmetric secret key. The application has to save this key somewhere in order to verify 2FA tokens. How can this key be stored securely?

  • Mark sensitive information as such in the source code

    Sensitive information such as passwords and API keys should not be stored in strings, but in specific class meant for that purpose, to avoid accidentally exposing them in logs or stack traces.

  • Clever ORM causes password reset vulnerability

    At one of my previous jobs, the database logic was a little bit too clever, resulting in a vulnerability in the authentication layer.

  • Running Etherkey on an ATmega32u4 to emulate a keyboard

    This article describes a cheap solution to emulate a keyboard on another computer. This is a rudimentary method of transferring data from one computer to another, with the advantage that it works on any computer and does not need installation of any software on the target device.

  • Enforcing object lifecycles through interfaces

    In object-oriented programming, objects can be in a particular state in which it is not valid to call certain methods. This article explores a solution for when methods need to be called in a particular order.

  • Avoid passing secrets in build arguments in Docker

    While building a Docker image, arguments can be passed using the ARG keyword and --build-arg option. These should not be used for secrets, because the build arguments end up in the history for the image.

  • MCH 2022 hacker camp - technical talks and workshops

    I followed about 15 talks and workshops on the MCH 2022 hacker camp. This post briefly describes each talk, my opinion on it, and key points.

  • MCH 2022 hacker camp - personal anecdotes

    I went to the MCH hacker camp. This post describes my non-technical, personal experiences while on MCH.

  • Lucky 13 and other padding oracle attacks on CBC ciphers

    Lucky 13 is a padding oracle timing attack on CBC ciphers, which required multiple patches to solve. Does this mean that this vulnerability is now solved for good, or that it is the vulnerability that keeps on giving?

  • Git submodules update to default branch, except when it's changed

    Git submodules by default update to the remote default branch. However, when you change the default branch, the submodule does not automatically switch to the new default branch.

  • How does git diff --ignore-matching-lines work

    Git diff does not display a hunk of changes, if all of the removed and added lines match any of the regexes specified by --ignore-matching-lines (-I).

  • Long passwords don't cause denial of service when using proper hash functions

    ASVS states that passwords should be at most 128 characters. This originates from the idea that longer passwords take longer to hash, which can lead to a denial of service when an attacker performs login attempts with very long passwords. However, this is not generally true. With a proper hash function, longer passwords do not take a significantly longer time to hash.

  • Remote code execution through unsafe unserialize in PHP

    Using gadget chains it is possible to achieve remote code execution in web application that unserialize user input, even without having the complete source code.

  • Adding request headers to image requests using a service worker

    Service workers can modify requests from a web application. This includes requests from <img> tags, but additional steps are needed before a request header can be added.

  • IoT security regulation

    Consumer IoT devices have been riddled with the same vulnerabilities for a long time. Authorities are now considering IoT cybersecurity regulation, which would make it possible to take insecure devices off the market.

  • Comparison of IoT security frameworks

    Several IoT frameworks have been devised that can help vendors in developing secure devices. These frameworks contain security measures to follow during development, helping vendors to create a secure device.

  • The most important security problems with IoT devices

    In this article, we list the eleven most important security issues faced by IoT devices. We will review them from the most severe though to the least. It is worth noting that the six most severe issues were used in an actual attack, or to demonstrate proof-of-concept of a vulnerability.

  • Infinite loop leads to denial of service in Centreon

    Centreon is a IT infrastructure monitoring tool, similar to Nagios. An infinite loop can be caused by changing a parameter that is used for the loop counter to a punctuation character, which is a denial-of-service vulnerability.

  • Overwriting HttpOnly cookies using cookie jar overflow

    Even though HttpOnly cookies cannot be read using JavaScript, it is still possible to overwrite HttpOnly cookies using JavaScript.

  • Testing Android apps on a virtual machine

    A virtual machine running Android is useful when hacking Android apps. In this post I describe my experiences with setting up a virtual machine and intercepting traffic from Android apps.

  • Combine two word lists for cracking passwords

    To crack passwords, it is sometimes useful to combine word lists in a way that concatenates words from multiple lists. This article shows three ways to accomplish this.

  • Abusing javascript:history.back() as an open redirect

    Using javascript:history.back() on a page may introduce a kind of open redirect. The previous page may not belong to the application that contains the link, so a seemingly trusted link now points to another (untrusted) page. This may be usable in phishing attacks.

  • The struggle of perfectionism

    I am a perfectionist. This often helps me to deliver quality, but also gives me anxiety if things are not perfect, which happens to be always. In this post I share my experience with perfectionism, and some methods that help with the continuous struggle.

  • Bypass virus scanners by renaming files

    To prevent spreading viruses or malware, many web applications scan uploaded files using a virus scanner. Often, the virus scanner is started as another process, and the output is checked for the result. The output of the virus scanner also contains the filename, which makes it possible to influence the logic that checks for the result. This post describes some instances where virus scanning can be bypassed by naming the file a particular way.

  • How to open a Compal CH7465LG-ZG Ziggo Connect Box

    Ziggo (or UPC) is a cable company in Europe that offers internet over cable. One of the DOCSIS modems they offer is the Compal CH7465LG-ZG, or Ziggo Connectbox. This post describes where the screws are and to open the modem enclosure to get to the hardware.

  • The case for client-side hashing: logging passwords by mistake

    Hashing passwords makes it possible to use them for authentication, while making it hard to reconstruct the original password. Hashing passwords on the client may be beneficial: even though it does not protect against attackers, it does protect against accidental mistakes.

  • Grepping functions with srcML

    In a previous post, Grepping functions with ANTLR, we looked into parsing source code to perform queries on it using XPath. For that post, I implemented a custom parser using ANTLR. In this post we look at an alternative: srcML is a software project that converts source code to XML so we can query it using XPath.

  • Cracking password hashes in Yclas

    Yclas is a CMS for classified advertisements. Its administrator interface has general search functionality, and was vulnerable to path traversal. Combined, these could be abused by administrators to obtain the passwords of other users.

  • Matrix.org hack

    Matrix.org develops standards and software for messaging and other online communication. In April 2019, Matrix.org was hacked. Starting from a public Jenkins with a months-old bug, the attacker quickly gained full access to all servers the developers could access. Both Matrix.org and the attacker reflected on the attack, making this an interesting hack to learn from.

  • Should each form have a different CSRF token?

    A common protection against CSRF attacks is to have a secret token in each POST request. Typically, this token is the same throughout the session, but in some circumstances it is more secure to rotate CSRF tokens often, or make them specific to the form they are on.

  • XSS in username in Sakai

    Sakai is educational software, to keep track of classes, students and test marks.

  • Breaking message franking

    Message franking is a mechanism to facilitate abuse reporting when using end-to-end encryption. This article describes how it works and how it can fail.

  • Most commonly used Dutch passwords

    Online brute force attacks use a list of commonly used passwords. Which passwords are common can vary for different countries. In this article, we look into how passwords differ for Dutch users.

  • A cheap alternative for Mictor 38 debugging connectors

    Western Digital hard drives have pads for a Mictor-38 connector, a debugging port that features JTAG. I found a cheaper alternative for these connectors and tried to attach them to the hard drive.

  • Reflected XSS in Yclas

    Yclas is a content management system for classified marketplaces. The search functionality was vulnerable to reflected cross-site scripting, even though HTML tags are stripped.

  • Second order SQL injection in ZoneMinder

    While searching for vulnerable projects I encountered ZoneMinder, a video surveillance software system. I found several vulnerabilities in its web interface, including second order SQL injection.

  • My pen testing project setup

    When working on a project I want to keep all project data in one directory. I keep notes and logs to make reporting easier, and to be able to answer customer questions. Although it’s rare, sometimes it is necessary to go back through the logs to see what happened during the test. In that case the logs need to be complete, and contain only information from that project. To make this easier, I have partly automated a workflow I will explain below.

  • Insecure direct object reference in Growatt

    An insecure direct object reference in the Growatt API to retrieve data on solar panels makes it possible to retrieve information on other users.

  • How to survive an office job

    A pen tester works in an office at a desk behind a computer screen for hours on end. Working in an office with nerds brings several challenges, and in this post I will share my personal experiences to help you handle these.

  • A method to do TLS on IoT devices

    Consider a device with a web interface in a home network. It has an RFC1918 address like How can we connect to this device using HTTPS with a trusted certificate?

  • Learning how to be a pentester

    In my post From developer to pentester, I described how I switched from a job as a software developer to a job as a security tester. Since I wrote that post, I’ve been asked a lot about how to learn pentesting as a developer and how to make the switch to pentester. This article describes how I learned enough security to get a job, and then even more.

  • Command injection on CommonAccord

    I found and fixed a simple command injection vulnerability in the CommonAccord web site.

  • Attacking RSA keys

    RSA keys need to conform to certain mathematical properties in order to be secure. If the key is not generated carefully it can have vulnerabilities which may totally compromise the encryption algorithm. Sometimes this can be determined from the public key alone. This article describes vulnerabilities that can be tested when in possession of a RSA public key.

  • Open redirect in CrushFTP

    CrushFTP is a file transfer solution with a web interface to transfer files and perform administrative tasks. It had an open redirect vulnerability in the login functionality.

  • Logging DNS requests with internet sharing on macOS

    When using Internet Sharing on macOS, the DNS log can provide insight in the behavior of connected Wi-Fi devices. This article describes how to view the DNS log.

  • ENISA Technical Measures for IoT

    ENISA has created a list of technical measures for securing IoT devices. These are hands-on rules which IoT manufacturers and developers should follow to secure their devices. Furthermore, the measures are useful when testing IoT devices, to make sure that all measures have been tested, and to point out in which field the most vulnerabilities are.

  • Working with bits and bytes in Python 2 and 3

    When performing a bit flip attack or working with XOR encryption, you want to change the bits and bytes in a string of bytes. How this is done differs between Python 2 and 3, and this article explains how.

  • Quickly set up a test mail server

    If you are setting up a web application on your own computer you sometimes need a simple mail server that just lets you view emails, for example for a password reset mail. This article lists several solutions to quickly set up a test mail server.

  • Hacking the Motorola MBP88Connect WiFi camera

    The Motorola Wi-Fi Video Baby Monitor Camera (MBP88CONNECT) is a webcam that can be controlled and viewed using the Hubble mobile app and Hubble web app. I found several vulnerabilities in the camera’s web interface, which have been resolved by the distributor through firmware updates. This article describes the vulnerabilities and how I found them.

  • USB to UART serial bridges

    USB to UART converters or bridges present themselves as a serial port to your computer and send serial data over a couple of wires. They can be used to make a serial connection to another device. In this post we’ll look into how this works.

  • Coverage of a security assessment

    When performing a typical security assessment, what percentage of all security vulnerabilities is found?

  • Prevent CSRF with the Origin request header

    The Origin header in a HTTP request indicates where the request originated from. This can be useful in preventing cross-site request forgery.

  • A USB Wi-Fi adapter that works with MacOS Mojave

    This article describes my experiences with the TP-Link TL-WN823N USB Wi-Fi adapter under MacOS Mojave.

  • Securing against cyber-attacks

    In the previous two articles, we explored the risk of cyber-attacks. This article explores how you can reduce that risk.

  • Impact of cyber attacks

    In a risk assessment, total risk is often calculated as a product of probability and impact. To make a proper risk assessment of cyber attacks, companies need to know both the probability and the impact of cyber attacks. This article explores the impact. What are the consequences of getting hacked?

  • Probability of cyber attacks

    In a risk assessment, total risk is often calculated as a product of probability and impact. To make a proper risk assessment of cyber attacks, companies need to know both the probability and the impact of cyber attacks. This article explores the probability. How likely is it for a company to get hacked?

  • Cross site request forgery (CSRF)

    This article describes how cross site request forgery works, how sites defend against it and how to bypass these defenses.

  • Accessing cross-site data using JSONP

    JSON with padding or JSONP is a method to access JSON data from another web site. This can lead to security vulnerabilities if the JSON data contains sensitive information.

  • Practice your hacking skills with these CTFs

    The best way to learn how to hack is to do it. There are several practice sites and capture-the-flag exercises to teach you how to break security.

  • Take over sessions in Metasfresh using CORS

    Metasfresh is a open source ERP web application. By default, it has misconfigured CORS headers which allow any other site to perform authenticated requests to it.

  • Should you update jQuery over a hypothetical vulnerability?

    If the version of jQuery you use contains a vulnerability, you may need to update your site to use a newer version. However, this can break functionality. You need to incorporate that into your decision on how to mitigate the vulnerability.

  • Truncating strings with MySQL

    Typical behavior in web applications is to validate user input before storing it in the database. However, in some cases the database may not store exactly what you put into it. This may be used to bypass input validation. This post describes some ways data can be altered when storing it in a MySQL database, and how to prevent it.

  • Creating custom word lists for password cracking

    When cracking passwords, the success greatly depends on the quality of the word list you use. This article lists some methods to create custom word lists for cracking passwords.

  • Which CORS headers do you need to send an Authorization header?

    In cross origin requests, the authorization header can be sent in two ways: either by the browser or specified along with the request. This article explains which CORS headers you need for each.

  • Automating path traversal with protravel

    With a path traversal vulnerability it is possible to download files by specifying their filename. The protravel tool helps you to download files and guess file names.

  • Changing your password through CSRF in IceHRM

    IceHRM is an open source human resource management system. Its functionality to change the user’s password is vulnerable to CSRF.

  • Path traversal in Monstra CMS

    In the administration interface of Monstra CMS, there is an option to download a backup file. This request can be modified to download any file on the server.

  • PHP type confusion on password comparison

    When comparing two values, PHP guesses at their type and performs the comparison accordingly. This can be misused by formatting a string as a number, so that comparison is done more loosely.

  • Discovering subdomains

    Early in a pentest it may be helpful to enumerate all the subdomains of a domain in scope. This article lists some tools that do that.

  • Vulnerability bingo

    I made a script to generate random bingo cards with vulnerabilities on it. Now you can play vulnerability bingo.

  • Finding common files in the webroot

    A common attack on a web application is trying to retrieve common files, such as .gitignore or README.md, using a tool such as dirbuster. The success of this approach depends a great deal on the quality of the word list. In this post we will try to compile our own word list from public data.

  • Detecting postMessage interfaces

    The postMessage mechanism provides a JavaScript interface to web pages. This interface is not immediately visible in an intercepting proxy when doing a security assessment. However, as any interface, it can have security issues. This post looks into possible security issues and detecting pages which use this mechanism, so that this interface is not overlooked on a security assessment.

  • Bitflip effect on encryption operation modes

    In a bitflip attack, the attacker modifies ciphertext in a way that predictably changes the decryption result. This way, an attacker can tamper with data even if it’s encrypted. How this works depends on which encryption mode of operation is used. In this post we’ll look into what behavior each mode has when a bit is flipped.

  • Grepping functions with ANTLR

    In order to find security bugs it is helpful to find specific patterns of code. In this post we will create a programming language parser to help us find vulnerable methods.

  • Intercepting HTTP requests with mitmproxy

    Mitmproxy is a command-line intercepting proxy. Just like with Burp, you can view and modify requests. It also has some features that distinguish it from other intercepting proxies. In this post, we will look into three features unique to mitmproxy.

  • Hacking the Huawei HG655d

    The Huawei HG655d is an obsolete ADSL modem. I found some vulnerabilities in its admin interface.

  • Experiences with the CC2530 Zigbee IC

    My set-top box for my TV has a remote that works with RF instead of infrared light. I read somewhere that it could be Zigbee, which made me interested in sniffing Zigbee communication. I bought a development board without thinking how to get it working. Also, I don’t have much experience with hardware. In this article I describe what I learned along the way.

  • Ubuntu mirrors behind on security updates

    Ubuntu retrieves packages from a package repository. These repositories are mirrored by several hosts on the internet. Even though the security pocket is also mirrored, you aren’t supposed to use it to avoid mirror delays in your security updates. I wasn’t aware of this, and I discovered that I was using a mirror that was running behind, resulting in missing security updates for over six months.

  • Upgrading a password hash function

    Most password hashes have a cost parameter that determines how long it takes to hash a password. As computers get faster over time, it is advisable to increase the cost parameter so that the password hash stays sufficiently slow.

  • Problems with pwdhash

    You shouldn’t reuse passwords across multiple websites. However, it is also hard to remember hundreds of different passwords. One solution to this is a deterministic password manager: you hash the domain name and the master password, and use that as the site password. This has some obvious problems, but in this post I would like to point out some problems that I think are less obvious.

  • Testssl.sh vs. OWASP O-saft

    An endpoint that supports SSL can support several versions, ciphers and algorithms, all of which have different security properties. There are several tools available to test whether a SSL-supporting server is configured securely. In this post we compare two of them, testssl.sh and OWASP O-saft.

  • Password hashing considerations

    Passwords are typically not stored plaintext in a database. Instead, a cryptographic hash is stored. This makes it possible to check the password, but makes it hard to get the plaintext password, even if the database is leaked. The way the password is hashed affects how hard it is to obtain the plaintext password. In this post we look into what properties a password hash should have.

  • Breaking cryptography using quantum computers

    Quantum computers have different properties than classical computers. This can be used to make some calculations dramatically faster, which in turn has implications for encryption. For example, RSA can be trivially broken given a quantum computer. This article explains approximately how this works.

  • Comparing secure strings in .NET

    In .NET, the SecureString class protects data in memory. The contents of a SecureString object are not accessible as a normal string and that makes it hard to work with it. This post describes some secure ways to compare two SecureString objects.

  • Leave secure cookies alone

    With the introduction of strict secure cookies, browsers won’t allow overwriting secure cookies from insecure origins.

  • Open redirect with authentication in OpenText Documentum

    Documentum is an enterprise content management platform in which it is possible to upload and share documents. I found an open redirect in it that also exposes credentials.

  • Libraries that evaluate remote JavaScript

    Some JavaScript libraries have functionality to automatically evaluate any JavaScript returned on AJAX requests. This introduces an XSS vulnerability if an attacker can control the URL of the request.

  • Attacks on the Host header

    If a website works even if the host header is missing or incorrect in the request, it may be vulnerable to several kinds of attacks. This post explains the implications of ignoring the host header.

  • Hacking from within the browser with Tamper Chrome

    Tamper Chrome is an extension for Chrome that makes it possible to modify HTTP requests in order to pentest web applications.

  • From developer to pentester

    Last year I switched from developing web applications to hacking them. In this post I describe why I made the switch and how that turned out for me.

  • Burp intruder attack types

    Burp is an intercepting proxy that can be used to test web sites. It has a fuzzing feature called intruder that can replace parameters in a request with values from one or more payload lists. It has several attack types that determine how the payloads are used in the request parameters. This post explains how the different attack types work.

  • Drive-by remote code execution in MAMP

    MAMP is an Apache, MySQL, and PHP stack for Mac OS X. It comes with SQLiteManager, which has several vulnerabilities. This post describes how to exploit these vulnerabilities to execute code when a user of MAMP visits a malicious web site.

  • Prevent session hijacking with token binding

    In web applications, anyone that possesses the session token has access to the session. Token binding introduces a cryptographic token where this is no longer the case, thus making it harder to hijack sessions by obtaining the session identifier.

  • Bypass CSRF checks using referrer policy

    The referer header is sometimes used as CSRF protection. This post describes a method for the attacker to remove the referer header, which can bypass some CSRF checks.

  • Finding vulnerable code on GitHub with Google BigQuery

    Some vulnerabilities are easy to spot in code. Searching code of multiple projects can quickly reveal vulnerabilities. This post describes how to use Google BigQuery to search for vulnerabilities in GitHub.

  • Automating web application attacks with Tampermonkey

    Tampermonkey and Greasemonkey are userscript managers that make it possible to add custom Javascript functionality to web pages. User scripts can be used to customize pages, or to automate web interactions. In this post we will use Tampermonkey to automate filling out a login form, to try to brute force credentials.

  • Generating password lists with regular expressions

    When cracking passwords, it is sometimes useful to try specifically formatted passwords. This post describes how you can generate a big list of passwords conforming to a specific pattern.

  • Checking whether files exist outside open_basedir

    PHP’s open_basedir setting limits the files that can be accessed by PHP to the specified directory. It should not be possible to access files outside of the directory set as open_basedir. However, it is still possible to check whether files exist because the file used as client certificate in an SSL connection is not checked against open_basedir.

  • Downloading an exposed Mercurial .hg directory

    Version control systems sometimes create a hidden directory in the repository. Git creates a .git directory, and Mercurial creates a .hg directory. If the contents of a web site are managed with Git or Mercurial, this directory is sometimes exposed on the web. In this post we look at a way to download these directories.

  • vBulletin random number function

    VBulletin is a message board web application written in PHP. Before PHP 7 came with random_int and random_bytes it was pretty hard to create a secure random number, and vBulletin uses a pretty bad way to solve that problem. In this post we look at the code and how it can fail to create a random number that is hard to guess.

  • Don't use base_convert on random tokens

    The PHP function base_convert can convert numbers to a different numeric system. This can be used for example to convert a number to a sequence of letters and numbers. However, because it has limited precision it is not suitable for random tokens such as those used for session tokens or CSRF tokens.

  • Bypass IP blocks with the X-Forwarded-For header

    Sometimes the IP address is used for access control or rate limiting. If the client is behind a proxy, the proxy forwards the IP address of the client to the server in a specific header, X-Forwarded-For. In some cases, a client can use this header to spoof his IP address.

  • Securing cookies with cookie prefixes

    Cookies can be overwritten by a man-in-the-middle attacker, even when using HTTPS. Using special cookie prefixes makes cookies more secure.

  • Checking passwords against a dictionary in ASP.NET MVC

    When using passwords for authentication, users may choose passwords that are too easily guessed. A method to prevent this is to have a list of known passwords and deny any password that is present in the list. This post will describe how to implement this in ASP.NET MVC Core. When registering, the user will get an error if he tries to use a password that is present in the dictionary.

  • Book review: Bulletproof SSL and TLS

    Recently I read the book Bulletproof SSL and TLS. I think it is a great book and I would recommend reading it. In this post I describe what you can expect from this book.

  • Check CRSF token by default in ASP.NET MVC

    ASP.NET MVC protects against CSRF by using a secret token, and checking it if an attribute is present. In this post we will show how to check the CSRF token for all POST requests.

  • Strengthening password hashes by brute-forcing random data

    Password hashes should be slow to prevent offline brute-force attacks. One way to make them slow is to include some unstored random data in the hash, which has to be brute-forced whenever a password is verified against a hash.

  • Adding a HTTP header to Nikto requests

    Nikto is a tool to scan websites for misconfigurations and vulnerabilities. It does a lot of requests to the target server. Sometimes you want to add a custom HTTP header to these requests. This article explains some ways to do that.

  • HTTPS does not provide privacy

    If you visit a web site over HTTPS, all traffic between the client and the server is encrypted. This does not mean that somebody that intercepts the connection can’t see which pages you are visiting. This post describes what is visible over an HTTPS connection and why.

  • The economics of certificate transparency

    Traffic to any web site that uses HTTPS is encrypted, and the server’s identity is verified. For this the web server needs a certificate. The certificate proves that the client is really talking to the domain it expects, and not to some man in the middle attacker. This security is broken if an attacker can obtain a certificate for a domain he wants to attack. To prevent this, we need certificate transparency.

  • The current state of the BREACH attack

    In August 2013 the BREACH attack was presented at the Black Hat conference in Las Vegas. With this attack it is possible in some cases to read parts of HTTPS traffic. A serious attack, but to this day there is no good fix for it. How come?

  • The password guessing bug in Tenex

    In 1974, BBN computer scientist Alan Bell discovered a security flaw in the operating system Tenex. The password checking procedure would access certain memory pages during checking. By looking at which pages were accessed during checking of the password, user passwords could be guessed one character at a time.

  • SSRF in LiveAgent

    The helpdesk software LiveAgent makes it possible to configure a SMTP server. Since it does not validate the SMTP server parameter and returns the response of the TCP connection, it is vulnerable to server side request forgery.

  • Attacking JWT authentication

    JSON Web Tokens or JWTs are used by some web applications instead of traditional session cookies. Because of their statelessness and the signature implementation there are some security issues that are specific to JWTs. This post describes some ways you can verify that a JWT implementation is secure.

  • Uploading webshells using .NET MoxieManager

    MoxieManager is a file manager for web applications. By using the built-in unzip functionality we can bypass the file extension filter in the .NET version of MoxieManager.

  • XSS in Kayako helpdesk software

    In the Kayako helpdesk software, customers can submit tickets which staff can then view and answer. In this feature there is a XSS vulnerability in the ticket title. This post describes how I found that vulnerability.

  • Compression side channel attacks

    Compression side-channel attacks can be used to read some data by knowing only the size of the compressed data. Recently compression side-channel attacks have been published on compressed HTTPS connections: the CRIME, TIME, BREACH and HEIST vulnerabilities. This post describes how compression side-channel attacks work in general and what these attacks do in particular.

  • Interesting recent web application hacks

    This post looks at some interesting web application hacks that were recently published.

  • Intercepting smartphone HTTP requests on MacOS

    If you are testing a mobile app on a smartphone, you want to intercept all HTTP requests with Burp Suite. However, not all mobile apps respect the proxy settings, making it necessary to have another way to intercept all traffic. This post describes a solution using Internet Sharing on MacOS, and using PF to forward all traffic to Burp.

  • Fuzzing SAML with SAMLReQuest

    SAML is a single sign-on solution. It uses XML, but this is sometimes encoded in such a way to it hard to deal with in Burp Suite. Luckily, there are some extensions that can decode these request.

  • Headers to block iframe loading

    A typical clickjacking attack loads a site in a transparent iframe and asks the user to click an underlying element. The user thinks it is interacting with the attacker’s page, while the input actually goes to the transparent iframe. To avoid this, the X-Frame-Options header and frame-ancestors option in the content security policy are available to instruct browsers to not load the site in an iframe. This post explains more about these headers.

  • Insecure token generation in Kayako

    The helpdesk software Kayako uses an insecure method of generating tokens used for sessions and CSRF protection. It is possible to seed the random number generator with the current time and then crack that seed, making it possible to predict a large part of any following tokens generated by Kayako.

  • How PHP's uniqid works

    PHP has a uniqid function, that creates a unique identifier. This function is sometimes used in a security context, such as for creating tokens for sessions or CSRF protection. This makes it interesting to know how it works exactly and whether we can predict its output.

  • Overwriting memory in Python

    The post “Clearing secrets from memory” discussed that it might be beneficial to clear secrets from memory after using them. This post discusses how to do this in Python.

  • Requirements for iterative password hashing

    To securely store passwords they should be hashed with a slow hashing function, such as PBKDF2. PBKDF2 is slow because it calls a fast hash function many times. This blog post explores some properties that the iterations must have to be secure.

  • Clearing secrets from memory

    When handling a secret such as an encryption key or a password, it is important not to leak it in any way. If the secret ends up in a log file, core dump or error message this could result in showing the secret to people who are not meant to see it. It may even be a good idea to remove the secret from memory after it is has been used. This blog post will look into whether that is good practice and how you can clear things from memory.

  • XSS in user-agent header in Bolt CMS

    Recently I tried to find vulnerabilities in Bolt CMS 2.2. Like many content management systems, Bolt has a publicly accessible web site, and a back end for administrators to modify the web site. I was looking for a way to get into the back end without valid credentials.

  • Combining CSRF and timing attacks

    In a CSRF attack it is typically not possible for the attacker to retrieve the result of the forged requests. In this post we show that by measuring the time that a forged requests take we can extract some information, for example whether a specific resource exists.

  • Preventing CSRF with the same-site cookie attribute

    Cookies are typically sent to third parties in cross origin requests. This can be abused to do CSRF attacks. Recently a new cookie attribute was proposed to disable third-party usage for some cookies, to prevent CSRF attacks. This post will describe the same-site cookie attribute and how it helps against CSRF.

  • Django's reset password mechanism

    Django enables users to reset their password with a token that is emailed to the user. This mechanism contains some smart features, so let’s look at how it works.

  • Datatypes for pycrypto in Python 3

    Say you want to encode some things in Python 3 using pycrypto, and you want full control over what is encrypted or decrypted. In that case you should use the bytes and bytearray types, not strings.

  • Opentape authorization vulnerability

    Opentape is a web application to create a playlist of MP3 files that users can play on a web page. It was first released in 2008, just after the music service Muxtape stopped its services.

  • Polymorphic Javascript malware

    Recently I received two similar e-mails with attached trojans, both using encoded Javascript. In this post we look into how the Javascript is encoded and what it does when it is run.

  • Cracking PHP rand()

    Webapps occasionally need to create tokens that are hard to guess. For example for session tokens or CSRF tokens, or in forgot password functionality where you get a token mailed to reset your password. These tokens should be cryptographically secure, but are often made by calling rand() multiple times and transforming the output to a string. This post will explore how hard it is to predict a token made with rand().

  • Circumventing authentication of a webshell

    When a website is hacked, the attacker often leaves a backdoor or webshell to be able to easily access the website in the future. These are often obfuscated to avoid detection, and need authentication so only the attacker can gain access to the site. In this post I am going to deobfuscate a webshell and show how the authentication can be bypassed when you have the source code but not the password.

  • Circumventing XSS filters

    XSS or cross site scripting is an attack where an hacker injects Javascript in a page that is then run by another visitor. To prevent this, some software tries to remove any Javascript from the input. This is pretty hard to implement correctly. In this article I will show some code that tries to remove Javascript code from the input, and show several ways to circumvent this.