Confused by complex code? Let our AI-powered Code Explainer demystify it for you. Try it out!
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:
Table of Contents:
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.
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.
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.
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 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:
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
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!