A hacky way to disable express-jwt expiry for development

I'm developing a small app in my free time using the nodejs and express, trying out Auth0 as a way to handle authentication nicely. One problem I face though is as I want to test out my API, which I now typically do via Insomnia (great tool btw), I couldn't get a long lasting token to test the with.

So I figured out a quick dirty trick to fix this. Jumping through the calls through different node packages for JWT (express-jwt -> jsonwebtoken); I found a clockTimeStamp option.

clockTimestamp: the time in seconds that should be used as the current time for all necessary comparisons.

Simply set the clockTimeStamp value to some small non-zero integer. This will fake the time for the expiry check to think that it's sometime at the beginning of probably unix time or something.

Some example code / barebones app:

const express = require("express");
const jwt = require("express-jwt");
const jwks = require("jwks-rsa");

const app = express();

const jwtOptions = {
  secret: jwks.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: "https://some-domain.auth0.com/.well-known/jwks.json"
  audience: "http://localhost:3000/api/",
  issuer: "https://some-domain.auth0.com/",
  algorithms: ["RS256"]

// This effectively disables the expiry check
if (process.env["DISABLE_JWT_EXPIRY"]) {
  console.log("WARNING: set clockTimeStamp to 0");
  jwtOptions.clockTimestamp = 1;

let jwtCheck = jwt(jwtOptions);

app.get("/userinfo", (req, res) => {

console.log("Starting on port 4000");

Running it locally now with the DISABLE_JWT_EXPIRY environment variable set I can skip having to get a fresh token. Another alternative would ofc be to just use a different JWT setup for local development, but eh... too lazy :)

Of course, don't use this anywhere outside local development.

A small Golang webservice Dockerimage

Here is the Dockerfile for a small golang webservice I wrote, which I managed to make quite small. Saving it for myself and I guess I may as well share it since I think it will otherwise be thrown away.

Note I've replaced the more project-specific stuff. Like the project name and package. Probably there is some smarter way to compile it with the correct path.

# The file has two steps, first the builder then the actual running image.
# This part identifies it as the builder.
FROM golang:1.10 as builder

# Create appuser to avoid running as root later
RUN adduser --system appuser

# Import the project onto where it would go on the gopath
WORKDIR /go/src/github.com/<username>/<project>
COPY . .

# Fetch dependencies
RUN go get -d -v ./...
# Compile the binary. Mind the flags because it has to work in the next image.
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo .

# Here we start the actual image. Scratch is super barebones.
FROM scratch


# Copy over the files we need.
# The ssl certs are needed for doing any kind of ssl connection
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# The actual binary.
COPY --from=builder /go/src/github.com/<username>/<project>/<project> /<project>
COPY --from=builder /etc/passwd /etc/passwd

# Use the non-root user.
USER appuser

# The tcp port to expose, in my case 1323 which is the default of the framework I use.

# Start the binary as the entrypoint.
ENTRYPOINT ["/<project>"]

When building this Dockerfile for my project, I get an image that is only 13.1MB big. Pretty good, compared to other services in e.g. NodeJS or Python that I have made before that usually end up 300MB+.

IMAP Tools for migrating email accounts

I wrote some tools to help with migrating an existing imap account from one server to another, so that you can keep your emails when you switch your domain name to a new provider. I think normally your email client might do this for you automatically just by you changing the server settings, but I have some users only using a webmail client, meaning they don't have a local copy to sync to the new server. Plus it's always good to have a backup.

To solve this I wrote some scripts that let me download an entire mailbox and then reupload it to a new server. You can find them here: https://github.com/Tethik/imap-tools

I initially intended to use these for migrating a domain name and the email to a new provider. Unfortunately I never got to carry out the migration, so I only got to try this out with some test accounts. The way I imagine the whole process of moving email servers with a domain name looks something like this:

  1. Download all accounts and their emails locally using my script.
  2. Do the domain transfer.
  3. Set up the new imap accounts at the new provider.
  4. Use the upload script for each account to upload all old emails to the new accounts.

Tagging docker images differently based on git branch

At work we use git flow to organize our git repositories. master is the production branch, develop is the staging branch, and longer features get their own feature/* branch. On these branches, everything is built into docker images that are uploaded to a registry to later be deployed. git flow also gives us some basic version tagging that we want to use to track our releases.

I wanted to tag these docker images so that we could easier refer to them in our deployment. Where there would be a latest tag that would always be the latest version, and maybe a tag for every version.

I came up with a python script that wraps around docker and git to automatically generate these tags for me, with some basic customization. It's pretty rough, but you can find it here: https://github.com/Tethik/lame-cli-programs/tree/master/docker-branch-tagging


docker-branch-tagging init generates a default .docker-branch-tagging file that looks something like the following.

    "develop": ["latest","develop-{CIRCLE_BUILD_NUM}","{git_branch}"],
    "feature/(.+)": ["{git_branch}"],
    "master": ["master","master-{CIRCLE_BUILD_NUM}","{git_latest_version_tag}"]

The keys are regex, and the values are python format strings. The values get passed the current environment variables as well as two special case variables git_branch and git_latest_version_tag. The script will simply look for any keys matching the current git branch and perform the templating on the values to generate the different tags.

Doing a docker-branch-tagging build aws-blahabhla.com/example on the master branch would then result in something like the following.

docker build -t aws-blahabhla.com/example:master -t aws-blahabhla.com/example:master-123 -t aws-blahabhla.com/example:0.2.1 .

docker-branch-tagging push would then perform the docker push. Ungefär like so:

docker push aws-blahabhla.com/example:master 
docker push aws-blahabhla.com/example:master-123
docker push aws-blahabhla.com/example:0.2.1

On CircleCI, which is where we do our continous integration, the step for building and pushing the docker containers generally looks something like this now.

      - image: circleci/python3
      - run: sudo pip install awscli
      - run: sudo pip install "git+https://github.com/Tethik/lame-cli-programs#egg=docker_branch_tagging&subdirectory=docker-branch-tagging"
      - checkout
      - attach_workspace:
          at: .
      - setup_remote_docker
      - run: "docker login -u AWS -p $(aws ecr get-authorization-token --output text --query authorizationData[].authorizationToken | base64 --decode | cut -d: -f2) $DOCKER_REPOSITORY"
      - run: docker-branch-tagging build $DOCKER_REPOSITORY
      - run: docker-branch-tagging push $DOCKER_REPOSITORY

The attach_workspace is used to copy over whatever dependencies that may have been installed via e.g. npm or binaries/webpacks that may have been built in a previous workflow step. DOCKER_REPOSITORY is the environment variable I set in the project configuration to the AWS ECR uri.


Just for fun, I decided to try making a CI/CD pipeline for my CV. This post will be a bit rough and jumbled, sorry about that, probably would have been better to split this into several posts. Anyhow, here's how I did it.

Building the LateX file via Docker

Before I used to just update my CV via ShareLatex, so I didn't have any Latex packages installed on my system. Installing Latex is usually a confusing mess of packages, so I figured using docker might be a good fit. In addition I knew that CircleCI takes a docker image to launch it's jobs in, so I could reuse it later.

Luckily I found that someone else had made a docker image for xelatex. With some adjustments I made my own image that contained everything I needed for compiling my tex files.

Then I uploaded it to docker hub for free (since it's open source).

Setting up CircleCI

With the previously mentioned docker image I defined a CircleCI job step as follows.

      - image: tethik/xelatex:latest
      - checkout
      - run: make 
      - attach_workspace:
          at: .  
      - persist_to_workspace:
          root: .
            - cv.pdf

The persist_to_workspace step saves the pdf so that it can be reused later in the deploy job using the attach_workspace step. The current attach_workspace step in the config above coming before the persist_to_workspace is to collect some scripted parts of the CV that I try to generate automatically. More on this later.

Deploying to Github Pages

For CD (Continuous Delivery) part of the process I needed somewhere to publish the document. I do have my own domains and servers, but I'd rather not have to give access to CircleCI to ssh or ftp into these. The hacky and cheap solution was to just reuse the same github repository and enable the Github pages feature. To do this I enabled Github Pages on the master branch, which I kept empty except for the final pdf output. Then I set up another step in the CircleCI config to commit and push the new pdf file to the master branch.

The CircleCI config step looks like this.

      - image: circleci/node:8.9
      - checkout
      - attach_workspace:
          at: .      
      - run: .circleci/deploy.sh

The deploy script itself looks like this.


git config --global user.email "circleci@blacknode.se"
git config --global user.name "CircleCI Deployment"
mv cv.pdf ..
git fetch --all
git reset --hard origin/develop
git checkout master
mv ../cv.pdf .
git add cv.pdf
git commit -m "PDF build $CIRCLE_SHA1"
git push origin master

By default CircleCI generates a key on your github repo which only has READ access. To get around this I created a new ssh key and added it as a deploy key to the github repository. Then I removed the original key from the CircleCI project configuration, and added the new ssh key that I generated.

The final step was to add the redirect from my main homepage (this site) to the github pages link where the document would be hosted. Since the server is running Apache I could use the following config.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.)cv$ https://tethik.github.io/curriculum-vitae/cv.pdf
RewriteRule ^curriculum-vitae https://tethik.github.io/curriculum-vitae/cv.pdf

It's a bit hacky, but it works :)

Automatically updating the document

The next fun step I wanted to do was add some parts to the document that would be automatically generated. Because writing CVs is boring and too manual. For now though I just coded something simple: A script that summarizes all my pull requests made on Github that are in some sense Open Source. i.e. not to repos that I own myself or repos that were created for e.g. schoolwork.

To organize the LateX files I set up the repo as follows. I wanted to keep the generated files separate from the main latex file that I copied from before.

partials/ ->  generated tex files.
src/github/ -> python script that generates into partials/

Inside the main cv.tex file I could then refer to the scripted content using the subfile package.

\subsection{Github Open Source Contributions}

Inside the src/ folder I mean to keep scripts that generate the partials. The src/github/ folder contains a script that generates a pull_requests.tex into the partials/ folder. It talks the to Github GraphQL API and summarizes the info into a table.

I added the following CircleCI job config. This goes before the previously defined build_pdf step.

      - image: kennethreitz/pipenv
      - checkout      
      - run: 
          command: pipenv install 
          working_directory: ~/project/src/github/
      - run: 
          command: pipenv run make
          working_directory: ~/project/src/github/
      - persist_to_workspace:
          root: .
            - partials/

Again I persist_to_workspace to keep the resulting partial/*.tex files. Pipenv handles the python dependencies beautifully. The github api key and a blacklist of repos to ignore is passed through environment variables.

This is what the table looks like in the PDF.

The resulting table

In the future I'd like to add more content that's automatically generated. E.g. pypi and npm packages published, total github commit stats etc.

Final Result

You can find the repository here, the latest pdf built by the pipline here, and the CircleCI project here.

I still need to update my CV though.

Working locally with Docker containers

Over the weekend I wrote a small tool that will automatically update the /etc/hosts file with your running docker container. You can find the script here: https://github.com/Spielstunde/docker-hosts-update

Example usage

First create a docker network. This will allow the containers to connect to each other and automatically resolve hostnames. This is most of the magic tbh.

docker network create evilcorp.internal

Now you can start new containers in the network:

docker run --network evilcorp.internal --rm -it nginx
docker run --network evilcorp.internal --name hello --rm -it nginx

After starting the above two container you can then start ...

sudo docker-hosts-update

... and you should see a section like this in your /etc/hosts file.

# ! docker-hosts-update start !
# This section was automatically generated by docker-hosts-update
# Don't edit this part manually :)   hello.evilcorp.internal   friendly_golick.evilcorp.internal
# ! docker-hosts-update end   !

Because these networks are on the same bridged network, docker will first of all ensure that their hostnames resolve to each other. E.g. in the first container it will be able to connect to the "hello" container, either via hello.evilcorp.internal or just hello.

What my script does is easily enable the host machine to resolve the hostnames too. This saves you the trouble of either getting the ip manually (because hostname, duh) but also removes the need for other approaches where you need to assign different ports to different containers, and then use some sort of service discovery tool and proxy to manage them. On both host and container the url http://hello.evilcorp.internal will resolve to the correct container.

Finally when you stop the containers using Ctrl+C or docker stop hello, you'll see the lines automatically removed from the hosts file, if docker-hosts-update is still running.

Custom Application Launchers in Linux

Just a small howto for creating new application launchers in ubuntu, and I guess other similar distros. These will typically automatically show up in your start menu or launchers.

Simply create a <application>.desktop file in the ~/.local/share/applications/ or /usr/share/applications/ folder. <application> can be whatever.

At work I use the following desktop entry as a shortcut to open up an editor for our documentation. Here's an example file:

[Desktop Entry]
Exec=code code/docs/

The following is copied for reference from https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles

Version is the version of this .desktop file.

Name is the name of the application, like 'VLC media player'.

Comment is a phrase or two describing what this program does, like 'Plays your music and videos files'.

Exec is the path to the executable file. The full path to the executable file must be used only in case it isn't in any of the paths specified in the $PATH variable. For example, any files that are inside the path /usr/bin don't need to have their full path specified in the Exec field, but only their filename.

Icon field is the icon that should be used by the launcher and represents the application. All icons that are under the directory /usr/share/pixmaps don't need to have their full path specified, but their filename without the extension. For example, if the icon file is /usr/share/pixmaps/wallch.png, then the Icon field should be just 'wallch'. All other icons should have their full path specified.

Terminal field specifies whether the application should run in a terminal window or not.

Type field specifies the type of the launcher file. The type can be Application, Link or Directory, but this article covers the 'Application' type.

Categories field specifies the category of the application. It is used by the Dash so as to categorize the applications.

Some other very good references: https://wiki.archlinux.org/index.php/Desktop_entries#Autostart https://specifications.freedesktop.org/desktop-entry-spec/latest/

Graphing the Ferryman Problem

Hello again, blog. It's been a while. I had a lot of topics that I wanted to write about the past year, but in the end I never managed to finish and publish anything. I think I'm generally ok with that though.

In the german lesson I had this week, we came across the "Ferryman problem" as part of an exercise. I found the following English explanation on the Mathswork website.

A man needs to cross a river with a wolf, a goat and a cabbage. His boat is only large enough to carry himself and one of his three possessions, so he must transport these items one at a time. However, if he leaves the wolf and the goat together unattended, then the wolf will eat the goat; similarly, if he leaves the goat and the cabbage together unattended, then the goat will eat the cabbage. How can the man get across safely with his three items?

During the lesson I then spent way too much time trying to draw a graph of all the different states. So instead I made a script using python and the graphviz library to draw this graph for me.

The different states are represented by a tuple of three. The leftmost value of the tuple is the set of who are on the initial (left) bank of the river. The second or middle value is the set for who are on the boat. The rightmost value is the destination bank of the river. Each character of the problem is identified by the letters. W is the wolf, S is the (Schafe), K is the cabbage (Kohl) and F is the ferryman.

Some example states:

('FKSW', '', '') # Our initial starting state with everyone the first riverbank.
('KW', 'FS', '') # The cabbage and the wolf are on the first bank. The ferryman and the sheep are on the boat in the river.

Anyhow, too much writing for something that is overkill. I'm pretty sure there are much simpler solutions to this. You can find the graph below.


Stored XSS via Swish Transaction

Last week I went to the cinema with some friends. My friend paid for the ticket so I decided to use the "Swish" app to transfer them the money. As a joke I put <script src="https://blacknode.se/xss"></script> in the description.

Imagine my surprise as the alert popped when I visited the transaction page later on.

Image of XSS alert

I reported this vulnerability to Skandia by calling their head office directly and getting patched through to their security guy. One or two days later I got an irl-mail with a thank you letter as well as two cinema vouchers.

My guess is that because they use aspx-pages they assumed that all input was already escaped for XSS. Aspx-pages typically throws an error and rejects detects any input that has html tags. However, since this came from an (I assume) external system that filtering never applied.

As of today it looks like it's been fixed. So I feel ok publishing it. My friend uses SEB, which was not affected by the vulnerability. It might be worth testing if the vulnerability exists on other banks.


I'd like to write about a part of what was my master thesis project. For my thesis I wrote about a mostly theoretical whistleblowing system. A part of that system was a component which verified that the javascript client, used for the submission of new whistleblowing leaks, had not been tampered with. This was to ensure that we could better trust the client, which may be hosted somewhere outside the organisation.

The idea is simple. Basically I've created a program which allows you to verify a static content on a hidden service. I assume that most people when using Tor are using the Tor Browser. This is the recommended way to stay anonymous, by not standing out you are part of a larger anonymity set. Compare this to the normal internet, where there are multiple browsers with versions and operating systems to keep track of. Because most people on Tor use the same client, we can emulate that client programmatically to create requests that are indistinguishable from those that would come from a real user. Since the verifier is using the same client, it will display the same behaviour and send the same HTTP headers like that of a real user. On the internet this would not work, because these things are so diverse that they can uniquely identify a user. On Tor however, the Tor Browser has been specifically engineered to not fingerprint individual users, meaning that all users mostly look the same.

For a verifier this is useful because it will be difficult for a server to tell apart a verification request from a real request. This allows it to monitor the server without the server being able to alter its behaviour by knowing when its being watched.

One problem this might solve is the untrustworhtiness of doing clientside cryptography in javascript. One problem why we can't trust javascript crypto is that there is no guarantee that a server hosting the cryptographic routines has not introduced a backdoor (like removing the encryption altogether). With this verifier we can have some guarantee that the javascript has not been altered by the server.


I implemented a prototype to test out this idea. Here's a link to the repository.

Run it once to stamp the "state" of a hidden service...

tamperfree stamp <url.onion>

...then run it again later to verify that the state has not changed.

tamperfree verify <url.onion>

When stamping a website tamperfree tries to identify and save a secure hash of the raw content received from the server for each path visited. It does this by working as a proxy between the Tor Browser and the Tor Socks proxy that it uses to connect to the network. Then it opens the targeted url in a selenium controlled instance of the Tor Browser. When verifying it captures the same raw content, computes the hashes etc and then it compares against the saved hashes.

There are some major caveats to this tool:

  • Can't use it on HTTPS. The proxy can't see the plaintext data as it passes directly to the browser and the encrypted content is not static since I'm guessing different IVs or somesuch are used.
  • Can't use it on dynamic websites (i.e. websites that change the content).
  • Using it on non-Tor websites is kind of pointless since the server would easily identify it by the user agent.
  • Sites requiring user interactions or multiple page loads are not supported. This would require that I spoof user behaviour, adding further complexity to the tool. I think it's doable for smaller sites to build a tree of possible user interactions and generate fake traffic based on every sub-tree. However, I am certain that most users will likely navigate a site the same way, meaning that certain patterns will emerge and make real users stand out from the fake.

So the use case for my tamperfree tool is pretty slim. You're limited to having a single page webapp which loads everything it needs on the first given url. Oh, and it has to run as a tor hidden service.

You want to run this tool often. So often that a malicious server has a higher probability of encountering a verification request than a real request if attempting to tamper by picking a request at random. To do this we simply want the tool to send out more requests to the server than the real requests. For my use-case, a whistleblowing site, the number of real visitors expected is actually pretty low (few visitors per day), so this is something we can do.

Timing is also important. If the verifier runs on a regular schedule then it's trivial for the server to figure out that incoming requests in that specified schedule are verification requests. Therefore it's important that the verifier runs on a random schedule that the server can not determine. E.g. running the verifier every 5 minutes would make it easy for the server to figure out the pattern and only serve it's malicious responces to requests outside that schedule. However, just running a ´sleep(rand())´ would also lead to scenarios where if there are multiple requests happening in quick succession, then the server can see that it's unlikely to be the verifier. I'm currently trying to figure this part out, and I think I will dedicate my next blogpost to it.

That's it for now. This post is a bit rambling and I apologize for that. When I get the time I will go back and try to clean it up, maybe add some pictures to make it easier to read. I'm publishing this now to try to get into the groove of posting again. If you have any feedback or ideas on this, feel free to contact me.