How to Make a Clickjacking Vulnerability Scanner with Python

Learn how to create a Python script to detect clickjacking vulnerabilities in websites. This tutorial covers the basics of clickjacking, protection methods, and provides step-by-step instructions to build a simple yet effective clickjacking vulnerability scanner.
  · 6 min read · Updated jun 2024 · Ethical Hacking

Confused by complex code? Let our AI-powered Code Explainer demystify it for you. Try it out!

Introduction

Clickjacking is a malicious technique attackers use to trick users into clicking something different from what they perceive. This is typically achieved by embedding a legitimate website inside an invisible iframe and overlaying it on top of a malicious page. When users interact with the page, they unknowingly perform actions on the embedded site, such as liking a post, submitting a form, or even executing transactions.

Clickjacking can also be used for:

  • Data Theft: Attackers can exploit clickjacking to steal sensitive information by tricking users into submitting forms or entering credentials.
  • Malware Distribution: Clickjacking can be used to download and execute malware on the victim's machine.

Table of Contents:

Protecting Against Clickjacking

To protect websites from clickjacking, web developers or security experts can use specific HTTP headers that control how the website is embedded in frames. The primary headers are:

1. X-Frame-Options: This header has three values:

      • DENY: Prevents the page from being displayed in an iframe.
      • SAMEORIGIN: Allows the page to be framed only by pages on the same origin.
      • ALLOW-FROM uri: Allows the page to be framed only by the specified origin. However, this method has been deprecated and is not widely supported.

2. Content-Security-Policy (CSP): Specifically, the frame-ancestors directive can be used to control the domains that are allowed to frame the content.

In our program, we’ll be checking the X-Frame-Options to determine if a website is vulnerable to clickjacking.

Checking for Clickjacking Vulnerabilities with Python

To get started, make sure to have Python 3 and the requests library installed. We’ll use the requests library to send HTTP requests to the website we want to check. You can install requests using:

$ pip install requests

Open up a new Python file, as always, name it meaningfully like clickjacking_scanner.py and include the following code. 

import requests, argparse #argparse for parsing command-line arguments

# Function to check if a website is vulnerable to clickjacking
def check_clickjacking(url):
    try:
        # Add https:// schema if not present in the URL
        if not url.startswith('http://') and not url.startswith('https://'):
            url = 'https://' + url
        # Send a GET request to the URL
        response = requests.get(url)
        headers = response.headers
        # Check for X-Frame-Options header
        if 'X-Frame-Options' not in headers:
            return True
        # Get the value of X-Frame-Options and check it
        x_frame_options = headers['X-Frame-Options'].lower()
        if x_frame_options != 'deny' and x_frame_options != 'sameorigin':
            return True
        return False
    except requests.exceptions.RequestException as e:
        print(f"An error occurred while checking {url} - {e}")
        return False

The check_clickjacking function checks if a website is vulnerable to clickjacking by sending a GET request to the URL, verifying the presence of the X-Frame-Options header, and ensuring its value is either deny or sameorigin, indicating protection against clickjacking.

Next, we’ll create a main function to accept user arguments (url) via the command line and check for clickjacking vulnerabilities.

# Main function to parse arguments and check the URL
def main():
    parser = argparse.ArgumentParser(description='Clickjacking Vulnerability Scanner')
    parser.add_argument('url', type=str, help='The URL of the website to check')
    parser.add_argument('-l', '--log', action='store_true', help='Print out the response headers for analysis')
    args = parser.parse_args()
    url = args.url
    is_vulnerable = check_clickjacking(url)
    if is_vulnerable:
        print(f"[+] {url} may be vulnerable to clickjacking.")
    else:
        print(f"[-] {url} is not vulnerable to clickjacking.")
    if args.log:
        # Add https:// schema if not present in the URL for response printing
        if not url.startswith('http://') and not url.startswith('https://'):
            url = 'https://' + url
        print("\nResponse Headers:")
        response = requests.get(url)
        for header, value in response.headers.items():
            print(f"{header}: {value}")

if __name__ == '__main__':
    main()

The main function parses command-line arguments to check a given URL for clickjacking vulnerability, prints the result, and optionally logs the HTTP response headers if specified (using the --log or -l flags).

That’s it. We’re done. Now, let’s run our code.

Running our Script

To test our script, I'll first use an intentionally vulnerable website and a non-vulnerable one. https://xss-game.appspot.com/ is an intentionally vulnerable site for testing XSS vulnerabilities. However, it’s also vulnerable to clickjacking, so we can test our script with it.

$ python clickjacking_scanner.py https://xss-game.appspot.com/ – -log

Result:

[+] https://xss-game.appspot.com/ may be vulnerable to clickjacking.

Response Headers:
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
X-Cloud-Trace-Context: 6c11c9a7bd445462fa98c8b72023255d
Date: Fri, 21 Jun 2024 07:24:41 GMT
Server: Google Frontend
Content-Length: 3080
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

Result as a screenshot:

Now, let’s test on a site that is not vulnerable to clickjacking.

$ python clickjacking_scanner.py www.guardyk.com —l

Result:

[-] www.guardyk.com is not vulnerable to clickjacking.

Response Headers:
Date: Fri, 21 Jun 2024 07:30:13 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
X-Clacks-Overhead: GNU Terry Pratchett
Content-Encoding: gzip
Server: PythonAnywhere

Screenshot:

You may be wondering, in the code we added functionality to add schema (http://, https://) if it wasn’t supplied by the user. Don’t worry, it still works - just in the background. The results you see above are presented to the user the same way they entered it.

Conclusion

The Python script we just built provides a simple and effective way to check if a website is vulnerable to clickjacking by inspecting the X-Frame-Options header. Developers can protect their websites and users from potential clickjacking attacks by understanding and utilizing these headers.

Check the complete code here.

A Little Challenge For You

A challenge for you is to improve the scripts by making it possible to add multiple URLs via the command line. It’s very simple. A hint for you is to use the nargs parameter in the url argument in argparse. Use this tutorial as a guide. I covered adding multiple IP addresses there.

Other relevant tutorials include:

Final Note

If you’re ever in a situation where you quickly want to check for Clickjacking vulnerabilities and have no access to Python, you can use this tool.

I hope you enjoyed this one, till next time.

Just finished the article? Why not take your Python skills a notch higher with our Python Code Assistant? Check it out!

View Full Code Auto-Generate My Code
Sharing is caring!



Read Also



Comment panel

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!