Picture meta-data
Did you know that pictures can contain a lot of information about the device used to take the picture, the date and time and even the location where the picture was taken?
Protect your privacy
Did you know that you can remove metadata from your pictures to protect your privacy? Below are some tools that can help you remove metadata from your pictures.
- VerExif - Online tool to remove metadata from pictures.
- ExifRemove - Online tool to remove metadata from pictures.
- Remove Photo Metadata - Online tool to remove metadata from pictures.
- ExifTool - Command line tool to remove metadata from pictures.
IP Tools
Did you know that an IP address can provide information about its location, ISP, and more? This tool will display detailed information about a given IP address.
IP Tools
Your IP address is:
REMOTE_ADDR: 70.53.170.20
Protect your privacy
Did you know that you can use a VPN to hide your IP address and protect your privacy? Below are some tools that can help you hide your IP address.
- Firefox - Free browser with built-in VPN.
- ExpressVPN - VPN service to hide your IP address.
- NordVPN - VPN service to hide your IP address.
- CyberGhost VPN - VPN service to hide your IP address.
- Private Internet Access - VPN service to hide your IP address.
Pixel Tracker
Did you know that simply viewing an image in an email without clicking any links can expose information about you, such as:
- When you opened the email
- Your IP address
- Your approximate location
- Information about your device
- Your email client
Protect your privacy
You can protect your privacy by disabling image loading in your email client or using a text-based email client. This will prevent pixel trackers from being loaded and sending information back to the sender.
Additionally, you can use browser extensions or email services that block tracking pixels.
SQL Pen Testing
Did you know that SQL injection is one of the most common web application vulnerabilities? This tool will help you perform a basic analysis of the provided URL for potential SQL injection vulnerabilities.
Protect your web application
To protect your web application from SQL injection vulnerabilities, consider the following best practices:
- Important: Use prepared statements and parameterized queries.
/* password in db previously hashed with password_hash() function */
function login($db, $email, $pass) {
$stmt = $db->prepare("SELECT password FROM users WHERE email = ?");
$stmt->bind_param("s", $email); //HL
$stmt->execute();
$user = $stmt->get_result()->fetch_assoc();
if (!$user || !password_verify($pass, $user['password'])) {
unset($_SESSION['user_email']);
return false;
}
$_SESSION['user_email'] = $email;
return true;
}
# password in db previously hashed bcrypt.hashpw function
import bcrypt
def login(db, session, email, password):
cursor = db.cursor(dictionary=True)
cursor.execute("SELECT password FROM users WHERE email = %s", (email,)) //HL
user = cursor.fetchone()
if not user or not bcrypt.checkpw(password.encode(), user['password'].encode()):
session.pop('user_email', None)
return False
session['user_email'] = email
return True
/* password in db previously hashed bcrypt.hash function */
const bcrypt = require('bcrypt');
async function login(db, session, email, pass) {
const [rows] = await db.execute("SELECT password FROM users WHERE email = ?", [email]); //HL
const user = rows[0];
if (!user || !await bcrypt.compare(pass, user.password)) {
delete session.user_email;
return false;
}
session.user_email = email;
return true;
}
/* password in db previously hashed BCrypt.HashPassword function */
using BCrypt.Net;
using MySql.Data.MySqlClient;
using Microsoft.AspNetCore.Http;
public async Task<bool> Login(MySqlConnection db, ISession session, string email, string pass)
{
using var cmd = new MySqlCommand("SELECT password FROM users WHERE email = @email", db);
cmd.Parameters.AddWithValue("@email", email); //HL
using var reader = await cmd.ExecuteReaderAsync();
if (!await reader.ReadAsync() || !BCrypt.Verify(pass, reader.GetString("password")))
{
session.Remove("user_email");
return false;
}
session.SetString("user_email", email);
return true;
}
/* password in db previously hashed BCrypt.hashpw function */
import org.mindrot.jbcrypt.BCrypt;
import java.sql.*;
import jakarta.servlet.http.HttpSession;
public boolean login(Connection db, HttpSession session, String email, String pass) throws SQLException {
try (PreparedStatement stmt = db.prepareStatement("SELECT password FROM users WHERE email = ?")) {
stmt.setString(1, email); //HL
ResultSet rs = stmt.executeQuery();
if (!rs.next() || !BCrypt.checkpw(pass, rs.getString("password"))) {
session.removeAttribute("user_email");
return false;
}
session.setAttribute("user_email", email);
return true;
}
}
/* Maven dependency */
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
- Validate and sanitize user inputs.
- Use ORM (Object-Relational Mapping) frameworks that handle SQL safely.
- Regularly update and patch your database and web application software.
- Implement proper error handling to avoid exposing database errors to users.
XSS Pen Testing
Did you know that allowing images in your site can lead to XSS vulnerabilities?
XSS Pen Testing
In a chat application for example, you could try and post a fake image:
Hello, how are you today?
Good thank you.
Or:
<svg onload="window.location='https://LucLaverdure.com';" width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
Note: You can save the above svg to a file and upload it if SVG files are allowed. The onload event will trigger the JavaScript when the SVG is rendered in the browser.
Protect your web application
To protect your web application from XSS vulnerabilities, consider the following best practices:
- Sanitize and validate user inputs.
/* Install via composer:
composer require ezyang/htmlpurifier */
require_once 'HTMLPurifier.auto.php';
function sanitize_html(string $input): string {
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'b,i,u,strong,em,p,br,ul,ol,li,a[href|title],img[src|alt]');
return (new HTMLPurifier($config))->purify($input);
}
# Install via pip:
# pip install bleach
import bleach
ALLOWED_TAGS = ['b', 'i', 'u', 'strong', 'em', 'p', 'br', 'ul', 'ol', 'li', 'a', 'img']
ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'img': ['src', 'alt'],
}
def sanitize_html(input: str) -> str:
return bleach.clean(input, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES, strip=True)
/* Install via npm:
npm install sanitize-html */
const sanitizeHtml = require('sanitize-html');
const ALLOWED_TAGS = ['b', 'i', 'u', 'strong', 'em', 'p', 'br', 'ul', 'ol', 'li', 'a', 'img'];
const ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'img': ['src', 'alt'],
};
function sanitizeHtmlInput(input) {
return sanitizeHtml(input, {
allowedTags: ALLOWED_TAGS,
allowedAttributes: ALLOWED_ATTRIBUTES,
});
}
/* Install via dotnet:
dotnet add package HtmlSanitizer */
using Ganss.Xss;
public static string SanitizeHtml(string input)
{
var sanitizer = new HtmlSanitizer();
sanitizer.AllowedTags.Clear();
foreach (var tag in new[] { "b", "i", "u", "strong", "em", "p", "br", "ul", "ol", "li", "a", "img" })
sanitizer.AllowedTags.Add(tag);
sanitizer.AllowedAttributes.Clear();
sanitizer.AllowedAttributes.Add("href");
sanitizer.AllowedAttributes.Add("title");
sanitizer.AllowedAttributes.Add("src");
sanitizer.AllowedAttributes.Add("alt");
return sanitizer.Sanitize(input);
}
/* Install via Gradle:
implementation 'org.jsoup:jsoup:1.17.2' */
import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;
public static String sanitizeHtml(String input) {
Safelist safelist = new Safelist()
.addTags("b", "i", "u", "strong", "em", "p", "br", "ul", "ol", "li", "a", "img")
.addAttributes("a", "href", "title")
.addAttributes("img", "src", "alt");
return Jsoup.clean(input, safelist);
}
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
- Use Content Security Policy (CSP) headers.
header("Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self';
frame-src 'none';
object-src 'none';
");
# With Flask
@app.after_request
def set_csp(response):
response.headers['Content-Security-Policy'] = (
"default-src 'self'; "
"script-src 'self'; "
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; "
"img-src 'self' data: https:; "
"font-src 'self' https://fonts.gstatic.com; "
"connect-src 'self'; "
"frame-src 'none'; "
"object-src 'none';"
)
return response
# Django (middleware.py):
# pip install django-csp
class CSPMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
response['Content-Security-Policy'] = (
"default-src 'self'; "
"script-src 'self'; "
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; "
"img-src 'self' data: https:; "
"font-src 'self' https://fonts.gstatic.com; "
"connect-src 'self'; "
"frame-src 'none'; "
"object-src 'none';"
)
return response
# Then register it in settings.py:
MIDDLEWARE = [
'yourapp.middleware.CSPMiddleware',
...
]
- Escape output in HTML, JavaScript, and CSS contexts.
- Use frameworks that automatically handle XSS protection.
Files Pen Testing
Did you know that allowing file uploads in your web application can lead to security vulnerabilities?
Files Pen Testing
In a web application that allows file uploads, you could try and upload a malicious file to test for vulnerabilities. For example, you could try to upload a .htaccess file or a shell script.
Example of a malicious .htaccess file that could be used to test for vulnerabilities:
Options -Indexes -ExecCGI
Order deny,allow
Deny from all
<Files "*">
Order deny,allow
Deny from all
</Files>
Protect your web application
To protect your web application from file upload vulnerabilities, consider the following best practices :
- Validate file types and sizes. Accept defined file types rather than blocking unknown types.
- Store uploaded files outside the web root.
- Rename uploaded files to prevent overwriting and to avoid executing scripts. For example rename ".htaccess" by "my-download-001.bin"
- Set proper permissions on uploaded files and directories.
- Use a virus scanner to scan uploaded files.
Rainbow Tables
Did you know that rainbow tables are precomputed tables for reversing cryptographic hash functions? They can be used to crack password hashes.
Rainbow Tables
In a web application that stores password hashes, you could try and use a rainbow table to crack the hashes. For example, you could use a rainbow table to crack MD5 hashes.
Example of an MD5 hash: 5f4dcc3b5aa765d61d8327deb882cf99
This hash corresponds to the password "password".
For example you can provide a hash and see if it can be decrypted here: MD5 Hash Lookup
Protect your web application
To protect your web application from rainbow table attacks, consider the following best practices :
- Use a strong hashing algorithm (e.g., bcrypt, Argon2) with a unique salt for each password.
- Implement rate limiting and account lockout mechanisms to prevent brute-force attacks.
- Educate users about creating strong, unique passwords.
- A way to set a password is to use a phrase instead of random characters, for example: "Lookatwhatididtodayathome,itwasawesome!"
Brute Force Dictionaries
Did you know that brute force attacks can be performed using dictionary lists of common passwords?
Brute Force Dictionaries
Below is a link to a dictionary avoid storing passwords that matches this list:
Protect your web application
To protect your web application from brute force attacks, consider the following best practices :
- Implement account lockout mechanisms after a certain number of failed login attempts.
- Use CAPTCHAs to prevent automated login attempts.
- Encourage users to create strong, unique passwords and consider implementing password strength requirements.
- Use multi-factor authentication (MFA) to add an extra layer of security.
- You could also verify that the password doesn't exist in dictionary files.
Fork Bombs
Did you know that a fork bomb is a denial-of-service attack against a computer system? It works by creating a large number of processes very quickly, which can overwhelm the system and cause it to become unresponsive.
Fork Bombs
In a web application that allows code execution, you could try and execute a fork bomb to test for vulnerabilities. For example, you could use the following command (in bash: macos or linux):
:(){ :|:& };:
The command above defines a function that calls itself twice, creating an exponential growth of processes.
For PowerShell:
function Fork-Bomb {
while ($true) {
Start-Job -ScriptBlock { Fork-Bomb }
}
}
MS Command line:
@echo off
:start
start %0
goto start
Protect your web application
To protect your web application from fork bomb attacks, consider the following best practices :
- Limit the number of processes a user can create.
#Via Group Policy:
# Win + R → gpedit.msc
# Computer Configuration → Windows Settings → Security Settings → Local Policies → User Rights Assignment
# Find "Increase scheduling priority" and restrict users
# Limit processes for a specific user using job objects
# Requires third-party tools like Process Lasso or SysInternals for per-user limits
# Windows doesn't have a native per-user process limit like Linux — use Process Lasso or SysInternals PsExec for granular control.
# /etc/security/limits.conf file contents:
# Max processes per user
username hard nproc 100
# Or for all users
* hard nproc 100
# Temporary in shell:
ulimit -u 100
# Verify in shell:
ulimit -u
# Edit /etc/launchd.conf (older macOS) or use launchctl:
# Check current limits
launchctl limit maxproc
# Set limit
sudo launchctl limit maxproc 100 200
# (soft limit 100, hard limit 200)
# Or via /etc/sysctl.conf:
kern.maxprocperuid=100
sudo sysctl -w kern.maxprocperuid=100
- Implement monitoring and alerting for unusual process activity.
- Educate users about the dangers of executing untrusted code.

