Skip to content

kinoz01/dwi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

180 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Real Time Forum

This project is a web forum designed to enhance user interaction and streamline content organization. Registered users can share posts with categorized tags, engage through likes and dislikes on both posts and comments, and easily navigate content with awesome filtering option. It also functions as a SPA that promotes private messages and real-time events, ensuring seamless communication. Built with Go for a fast and reliable backend, SQLite for lightweight yet robust data storage, and Docker for seamless deployment, this platform combines performance, simplicity, and scalability to deliver an exceptional user experience.

For a live preview of the project please check the link: https://dwi.fly.dev/

Some Explanations: https://excalidraw.com/#json=aaPfOnBdAFyYjrF4KL7Gp,qf57RNVURw8aO1VGdsyJZg

Usage Guidance

1. Prerequisites

Software Purpose Installation Guide
Go To compile and run the application locally. Install Go
Docker To build and run the application in a container. Install Docker
SQLite The application's database management system. Install SQLite

2. Installation

Using a terminal, clone and navigate to the repository:

git clone https://github.com/sadiqui/real-time-forum
cd real-time-forum

Then, you can run the application either locally or using Docker, access on localhost.

Command Description
make go Runs the application locally using Go.
make docker Builds a Docker image and starts the application container.
make clean Stops container and cleans up all Docker resources related to the application.
make deepClean Stops all Docker resources, even if they are not related to this application.

3. Database Mounting

The -v $(PWD)/database:/app/database option in the docker run or make docker command is used to create a volume mapping between the host machine and the container. This mapping ensures that any changes made to the database files in the container (stored in /app/database) are reflected on the host machine (in the database directory) and vice versa. This setup is particularly useful for persisting database changes made during the container's lifecycle, even after the container stops or is removed.

4. Dynamic Port Allocation

The application supports running on a flexible port. By default, it binds to a random available port when no specific port is specified. To set a specific port for local execution, export the PORT environment variable (e.g., export PORT=8080), and the application will use it. To revert to a random port, unset the variable with unset PORT. When running the application in Docker, specify the desired port using PORT=<port> in Makefile. If no port is specified, Docker will default to using the random port generated by the application.

5. Open Authorization

To use OAuth, you can obtain your own GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from the Google Developer Console by searching for OAuth setup (the same applies to GitHub or other providers) and set them as environment variables, e.g.:

GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."
GITHUB_CLIENT_ID="..."
GITHUB_CLIENT_SECRET="..."

During deployment, you can set these environment variables on the hosting server.
For Fly.io, use the flyctl secrets command to securely store them:

flyctl secrets set GOOGLE_CLIENT_ID="your-google-client-id"
flyctl secrets set GOOGLE_CLIENT_SECRET="your-google-client-secret"
flyctl secrets set GITHUB_CLIENT_SECRET="..."
flyctl secrets set GITHUB_CLIENT_ID="..."

These secrets will be available as environment variables in your deployed application.

6. Used packages

This project uses several Go packages that contribute to security in different ways:

Package Security Role
gofrs/uuid Prevents predictable IDs & session ID enumeration attacks
sqlite3 Mitigates SQL injection, improves DB security
bcrypt Provides password hashing/salting, randomness, and prevents rainbow table attacks

Security Features

1. Secure cookies

`CreateSession() function in session.go

cookie := &http.Cookie{
    Name:     "session_token",
    Value:    token,
    Expires:  expiresAt,
    Path:     "/",
    // Moderate CSRF protection, send cookie on links but not on embedded requests
    SameSite: http.SameSiteLaxMode,
    // Protects against XSS, blocks access to document.cookie
    HttpOnly: true,
    // Only send the cookie over HTTPS
    Secure:   true,
}

This cookie configuration implements several security measures to protect user sessions. The HttpOnly flag prevents JavaScript access to the cookie, mitigating the risk of Cross-Site Scripting (XSS) attacks. The Secure flag ensures that the cookie is transmitted only over HTTPS, preventing exposure in plaintext over unsecured connections. The SameSite=Lax setting provides moderate protection against Cross-Site Request Forgery (CSRF) by allowing the cookie to be sent with top-level navigations (e.g., clicking a link) but restricting its use in cross-origin subrequests (e.g., iframes or AJAX calls). Additionally, setting an expiration (Expires) ensures the session token is not stored indefinitely, reducing the impact of session hijacking. Finally, the cookie is scoped to the entire site (Path="/"), ensuring it is available across all pages. This setup balances security and usability, protecting against common web vulnerabilities while maintaining session persistence.

2. Secure Headers

`secureHeaders() function in helpers.go

w.Header().Set("Content-Security-Policy", "script-src 'self';")
  • Allows scripts only from the same origin ('self').
  • If an attacker injects a <script> tag from another domain, it won't run.
w.Header().Set("X-Frame-Options", "DENY")
  • Prevents clickjacking attacks by blocking <iframe> embedding.
  • No one can embed your site in an <iframe>.
w.Header().Set("X-Content-Type-Options", "nosniff")
  • Prevents MIME sniffing attacks.
  • Ensures browsers only execute files with declared content types.
  • Prevents content-type spoofing (e.g., treating a text file as HTML/JavaScript).
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
  • Forces HTTPS by telling browsers to always use HTTPS instead of HTTP.
  • max-age=31536000 → Enforces HTTPS for 1 year.
  • includeSubDomains → Applies to all subdomains.

3. HTTP Secure

`Server() function in server.go

A secure client-server connection over HTTPS relies on four parameters: key exchange, authentication, symmetric encryption, and hashing.

  1. Key Exchange Protocol ensures that both parties can securely generate and exchange the necessary encryption keys.
  2. Authentication verifies the server’s identity, preventing man-in-the-middle attacks.
  3. Symmetric Encryption guarantees confidentiality and privacy by encrypting the data exchanged.
  4. Hashing Algorithms maintain data integrity, ensuring that the transmitted data has not been altered.

These four parameters are combined into Cipher Suites, which define the cryptographic algorithms used in a TLS connection. Each cipher suite follows the format:

TLS_{KeyExchange}{Authentication}_WITH_{Encryption}{Hash}
Example: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

Where each part specifies the protocol for key exchange, authentication, encryption, and hashing. The TLS (Transport Layer Security) protocol is responsible for selecting and enforcing cipher suites in HTTPS:

  • During the TLS handshake, the client (browser) sends a list of supported cipher suites.
  • The server picks the most secure one it supports from the list.
  • The chosen cipher suite defines how the four parameters will work for that session.

The actual selection of a cipher suite depends on:

  • The client’s and server’s supported cipher suites.
  • The server’s configuration (it can enforce strong ciphers).
  • The TLS version (newer versions deprecate weaker ciphers).

A seamless TLS handshake enables the encrypted data transmission that secures our digital world. It allows safe online commerce, communication, and connectivity by:

  • Verifying you are connected to the authentic site and not an impersonator
  • Encrypting all data exchanged during the session.
  • Ensuring no third party can read or modify the information as it travels across the internet

Without the TLS handshake, our sensitive information would be exposed online.

Although Let’s Encrypt offers free trusted certificates, we wanted to generate our own self-signed certificate. In order to do so, we first created a configuration file named san.conf where we included the Subject Alternative Name (SAN) to match the used domain (localhost for development). Then, we generated our certificates with SAN support:

# Generate CA key and certificate
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/CN=MyCA"

# Generate server key
openssl genrsa -out server.key 4096

# Generate CSR using the san.conf
openssl req -new -key server.key -out server.csr -subj "/CN=127.0.0.1" -config san.conf

# Generate server certificate
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
    -out server.crt -days 365 -sha256 -extensions v3_req -extfile san.conf

2048-bit: Good security, faster performance.
4096-bit: Stronger security, slower performance.

  • san.conf: Configuration file specifying certificate attributes, including Subject Alternative Names (SAN) for IP and DNS.
  • ca.key: Private key of the Certificate Authority (CA), used to sign certificates.
  • ca.crt: Public certificate of the CA, used to verify certificates it signs.
  • server.key: Private key for the server, used in SSL/TLS encryption.
  • server.csr: Certificate Signing Request (CSR) for the server, sent to the CA to obtain a signed certificate.
  • server.crt: Server’s signed certificate, issued by the CA, used for HTTPS authentication and encryption.

Lastly, we have imported the CA certificate ca.crt into the browser's trusted root certificates.

TLS excali: https://excalidraw.com/#json=deZ-na0KKm5T9M8rbE9yV,KaJgeOjLKFIs9Yus8PW6Yg

About

A single-page forum application (SPA) built using Go, SQLite, and vanilla JavaScript, with real-time chat, post feeds, and notifications.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors