This document describes the steps we take to secure our systems and how we protect our customers’ information. If you have any questions or concerns over the security of GivingTools, please let us know by sending us an email to or consulting our security.txt file.


Our systems are hosted on DigitalOcean . Access to this cloud provider is restricted to as few personnel as possible. Each person uses a strong password and two-factor authentication to login to the service. As we learned from the Reddit security breach and others beforehand, SMS-based 2FA is insecure. As such, we only use app-based 2FA.

All our servers have password-based SSH login disabled. Access to the server requires an authorized SSH key. Login to the root account is forbidden. Elevated permission is only obtained via sudo which requires the user’s strong personal password.

We perform software updates on a weekly basis to ensure we always have the latest security fixes installed.

Mail Server

Our mail server runs Mail-in-a-Box . A firewall is in place as you can see below:

  • Inbound: ICMP
  • Inbound: SSH TCP on 22
  • Inbound: HTTP(S) TCP on 80 & 443
  • Inbound: DNS TCP & UDP on 53
  • Inbound: Mail TCP on 25, 587, & 993
  • Outbound: ICMP
  • Outbound: All TCP & UDP


Our main GivingTools server runs Ubuntu 18.04. Software updates are applied weekly.

Our firewall can be seen below:

  • Inbound: ICMP
  • Inbound: SSH TCP on 22
  • Inbound: HTTP(S) TCP on 80 & 443
  • Outbound: ICMP
  • Outbound: All TCP & UDP

Source Code

We host our source code on GitLab . Access here is limited to restricted to as few personel as possible. Access to production branches require 2FA.

Password Handling

We store our passwords using BCrypt v0.3m with 10 rounds. We do not log passwords anywhere.

Credit Card Numbers

We do not store or log credit card numbers or their CVV codes. All credit cards are tokenized by our various 3rd party processors. The token is then stored on our systems.

Administrative Interfaces

For our administrators at GivingTools, we expose an admin panel for maintenance purposes. While this is public-facing (, it is protected by an IP whitelist and a strong password. Most usage through this panel is through an SSH tunnel.


On each server, we run services inside unprivileged Docker containers.


To be PCI compliant, we only support TLS version 1.2. More information about our TLS security can be found here:

PCI Compliance

We are PCI compliant (level D). Trustwave automatically scans us on a quarterly basis searching for unpatched CVEs and other vulnerabilities. With this information, we patch our systems if they havn’t already been.

Secret Access

Secrets are not stored in the source code. They are stored on the servers they are used on and are built into the Docker image specific to that server. We should theoretically be able to release our full source code and not be at risk.

Data Storage and Backups

We use the OpenZFS filesystem.

While not necessary to the security of our system, stored data and backups will be encrypted with the 0.8.0 release of OpenZFS.

We perform ZFS snapshots on an hourly basis. These are synced to a backup server in DigitalOcean’s LON1 data center. Access to this server is done via a SSH key.


Logs that our servers generate do not contain any passwords, credit card numbers, or other security-revealing details. Logs are retained for no longer than 90 days.

Security Headers


You may notice that we use X-Frame-Options:allowall . This is to allow our clients to embed their donation pages. However, we use this script to block embedding of the login and dashboard pages.

We use Access-Control-Allow-Origin:* on both the and domains because:

  • The domain does not have any cookies associated with it used for authentication. These are stored inside local storage and are not subject to CORS requests.
    • The also does not have any cookies associated with it. Authentication is performed through the Authorization header.

We are currently in the process of developing a content security policy. For now, we have it set to report only.

SQL Injection

We prevent SQL injection by not running any raw SQL queries. We store our data using GORM v6 and Hibernate v5 which will automatically escape any SQL statements.

Cross-site Scripting

Our client framework, Angular, prevents cross-site scripting (XSS) by treating all values as untrusted by default . All user-supplied content is automatically escaped.

Fraud Detection System

We have custom built a system that will automatically detect “cardrunners” (bad folks, often Russian, who use systems like ours to run test transactions to see if a stolen credit card is active). While the exact algorithm used is confidential, the system will determine if it thinks the user is a bad guy, and if so, make them fill out a captcha which increasingly gets more difficult to solve.

Independent Security Assessments

This document is also available in Markdown, HTML, PDF, Text, Word, and Rich text formats.

This website uses cookies