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.
Want to code smarter? Our Python Code Assistant is waiting to help you. Try it now!
View Full Code Improve 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!