diff --git a/testing/templates/check_email.html b/testing/templates/check_email.html index 42e3604..fb7cbcf 100644 --- a/testing/templates/check_email.html +++ b/testing/templates/check_email.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load tags %} +{% load static %} {% block content %}
@@ -41,11 +42,16 @@

Assess the security of your ema + value="{{ domain }}" required>

+ {% if result %} +
+ Export this to PDF +
+ {% endif %}
About the test
@@ -55,7 +61,7 @@

Assess the security of your ema {% if result %}
-

Overview of {{ result.domain }}

+

Overview of {{ domain }}

@@ -65,7 +71,7 @@

Overview of {{ result.domain }}

- {% if result.spf_valid %} + {% if spf_valid %} {% else %} @@ -75,7 +81,7 @@

Overview of {{ result.domain }}

SPF record
- {% if result.dmarc_valid %} + {% if dmarc_valid %} {% else %} @@ -85,7 +91,7 @@

Overview of {{ result.domain }}

DMARC Record
- {% if result.dnssec %} + {% if dnssec %} {% else %} @@ -95,10 +101,10 @@

Overview of {{ result.domain }}

Signed Domain Name (DNSSEC)
+
+

Overview of {{ domain }}

+ +
+ {% if spf_valid %} + + {% else %} + + {% endif %} + SPF record +
+ +
+ {% if dmarc_valid %} + + {% else %} + + {% endif %} + DMARC Record +
+ +
+ {% if dnssec %} + + {% else %} + + {% endif %} + Signed Domain Name (DNSSEC) +
+ +
+

Vulnerabilities

+
+ Good: {{ good }} +
+
+ Vulnerable: {{ vulnerable }} +
+
+ Pie chart of status counts +
+
+
+ + +
+

{% if spf_valid %} + + {% else %} + + {% endif %} SPF Record

+

The Sender Policy Framework (SPF) is an email validation protocol that helps detect and block email spoofing. Email spoofing is a common technique used in phishing and spam emails. SPF allows the receiving mail server to verify that incoming mail from a domain comes from a host authorized by that domain’s administrators. The list of authorized sending hosts for a domain is published in the Domain Name System (DNS) records.

+

SPF Record

+ {{ spf }} +

Valid: + {% if spf_valid %} + + {% else %} + + {% endif %} +

+

Recommendations:

+
+

Create and publish an SPF record in your DNS settings for your domain. The SPF record specifies which email servers are authorized to send emails on behalf of your domain name. Identify the IP addresses of your legitimate email servers and include them in your SPF record. This ensures that only authorized servers can send emails using your domain name. Configure your SPF record with a "hard fail" mechanism (-all) to explicitly reject any emails that do not originate from authorized IP addresses. This helps prevent unauthorized sources from sending emails on behalf of your domain. Consider implementing SPF alignment mechanisms, such as DMARC (Domain-based Message Authentication, Reporting, and Conformance), to further strengthen email authentication and protect against domain spoofing.

+
+
+ + +
+

{% if dmarc_valid %} + + {% else %} + + {% endif %} DMARC Record

+

DMARC (Domain-based Message Authentication, Reporting, and Conformance) is an email authentication protocol that provides additional protection against email spoofing and phishing attacks. It uses the Sender Policy Framework (SPF) and DomainKeys Identified Mail (DKIM) standards. DMARC enables a domain owner to specify how mail servers should handle messages from their domain that don’t pass SPF or DKIM checks. This adds an extra layer of security

+

DMARC Record

+ {{ dmarc }} +

Valid: + {% if dmarc_valid %} + + {% else %} + + {% endif %} +

+
+ + +
+

{% if dnssec %} + + {% else %} + + {% endif %} Signed Domain Name (DNSSEC)

+

DNSSEC (Domain Name System Security Extensions) is a set of cryptographic protocols and security measures designed to enhance the security of the Domain Name System (DNS). By digitally signing DNS data, DNSSEC ensures data integrity and authenticity, protecting against various forms of DNS attacks like cache poisoning or DNS spoofing. It uses public key cryptography to verify the authenticity of DNS responses and provides a chain of trust from the root DNS servers down to the individual domain names, ensuring that the DNS information received by a user is valid and has not been tampered with during transmission.

+

DNSSEC Status

+ {{ dnssec }} +

Recommendations:

+
+

+ IPv6 is the next generation of the Internet Protocol, and it offers a number of advantages over IPv4, the current version of the protocol. +

+
    +
  • + Address exhaustion: IPv4 is running out of available addresses due to the rapid growth of connected devices. IPv6 provides a significantly larger address space, ensuring that there are enough unique IP addresses to accommodate the expanding number of devices and services. +
  • +
  • + Future-proofing: As the industry shifts towards IPv6, enabling IPv6 support ensures compatibility and seamless communication with the growing number of IPv6-enabled networks and devices. It future-proofs your infrastructure, avoiding potential connectivity issues and the need for costly workarounds. +
  • +
  • + Enhanced functionality: IPv6 offers improvements in areas such as auto-configuration, mobility, and quality of service, allowing for more efficient and advanced network operations. Enabling IPv6 unlocks these enhanced functionalities, promoting a better user experience and enabling innovative applications and services. +
  • +
  • + Global reachability: With IPv6, your services can reach a larger global audience, including regions and networks that primarily use IPv6. By enabling IPv6, you expand your online presence and increase accessibility to your web services. +
  • +
  • + Security advancements: IPv6 includes built-in security features, such as IPsec (Internet Protocol Security), which provides native encryption, authentication, and data integrity. Enabling IPv6 allows you to leverage these security enhancements, improving the confidentiality and integrity of your network traffic. +
  • +
+
+
+ + +
+ diff --git a/testing/templates/infra-test_report.html b/testing/templates/infra-test_report.html new file mode 100644 index 0000000..d776d06 --- /dev/null +++ b/testing/templates/infra-test_report.html @@ -0,0 +1,88 @@ + + + + + + +
+ diff --git a/testing/templates/pdf_wrapper.html b/testing/templates/pdf_wrapper.html index ace183a..792ef4b 100644 --- a/testing/templates/pdf_wrapper.html +++ b/testing/templates/pdf_wrapper.html @@ -1,4 +1,32 @@ -

Result of {{ test | capitalize }} scan on {{ site }}

+ + + + + + + + + + + + + + + + + -{% set template = test + "_report.html" %} -{% include template %} +

Result of {{ test|capfirst }} scan on {{ site }}

+ +{% with test|add:"_report.html" as template %} + {% include template %} +{% endwith %} diff --git a/testing/templates/web-test_report.bkp.html b/testing/templates/web-test_report.bkp.html new file mode 100644 index 0000000..f27da19 --- /dev/null +++ b/testing/templates/web-test_report.bkp.html @@ -0,0 +1,899 @@ +
+
+
+
+
+

Basic Website Security Checker

+
+
+
+
+ +
+
+

Overview of {{ domain }}

+
+
+ +
+
+
+
+
+
+ {% if csp_result.status %} + + + {% else %} + + + {% endif %} + CSP Status +
+
+ {% if cookies_result.status %} + + + {% else %} + + + {% endif %} + Cookies Status +
+
+ {% if cors_result.status %} + + + {% else %} + + + {% endif %} + CORS Status +
+
+ {% if https_redirect_result.status %} + + + {% else %} + + + {% endif %} + HTTPS Redirect +
+
+ {% if referrer_policy_result.status %} + + + {% else %} + + + {% endif %} + Referrer Policy +
+
+ {% if sri_result.status %} + + + {% else %} + + + {% endif %} + Subresource Integrity (SRI) +
+
+ {% if x_content_type_options_result.status %} + + + {% else %} + + + {% endif %} + X-Content-Type-Options +
+
+ {% if hsts_result.status %} + + + {% else %} + + + {% endif %} + HTTP Strict Transport Security (HSTS) +
+
+ {% if security_txt_result.status %} + + + {% else %} + + + {% endif %} + Security.txt +
+
+
+
+
+
+ + +
+
+
+ {% if csp_result.status %} + + {% else %} + + {% endif %} Content Security Policy (CSP) + +
+
+

Content Security Policy (CSP) is an HTTP header that allows site operators + fine-grained control over where resources on their site can be loaded from. The + use of this header is the best method to prevent cross-site scripting (XSS) + vulnerabilities. Due to the difficulty in retrofitting CSP into existing + websites, CSP is mandatory for all new websites and is strongly recommended for + all existing high-risk sites.

+
+ + +
+
+

Result

+
+
+
+
CSP Value
+

+ {% if csp_result.csp_value %} + {{ csp_result.csp_value }} + {% else %} + None + {% endif %} +

+
CSP Report Only
+

+ {% if csp_result.csp_report_only %} + {{ csp_result.csp_report_only }} + {% else %} + None + {% endif %} +

+
Issues
+
    + {% for issue in csp_result.issues %} +
  • + {{ issue }} + Issue +
  • + {% endfor %} +
+
Recommendations
+
    + {% for recommendation in csp_result.recommendations %} +
  • + {{ recommendation }} + Recommendation +
  • + {% endfor %} +
+
+
+
+
+
+
+
+

How to implement the CSP?

+
+

Determine what types of resources your site should load: Before + implementing + CSP, it is important to identify which types of resources your site needs to + load such as scripts, stylesheets, images, and fonts.

+

Create a whitelist of + allowed sources:
Once you have determined the types of + resources your site needs to load, you should create a whitelist of allowed + sources for each of them. This will prevent malicious sources from injecting + unwanted code into your site.

+ +

Use the Content-Security-Policy header:
Add the + Content-Security-Policy + header + to the HTTP response of your site. This header specifies the whitelist of + allowed sources for each resource type.

+

For example, the following header + specifies that only resources from the same origin as the site are allowed: +

+
    +
  • Content-Security-Policy: default-src 'self'
  • +
+

Test your CSP policy:
After implementing your CSP policy, it is + important + to + test it to ensure that it does not break any functionality of your site. You + can use rescan and check if the CSP will pass.

+

Keep your CSP policy up to date:
As your site evolves, you may + need to add + new + resources or change the sources of existing resources. Therefore, it is + important to review and update your CSP policy regularly to ensure that it + remains effective.

+
+
+
+
+
+ +
+
+
+ {% if cookies_result.status %} + + {% else %} + + {% endif %} Cookies +
+
+

Using cookies attributes such as Secure and HttpOnly can protect users from + having their personal information stolen.

+
+
+
+

Result

+
+ + + {% if cookies_result.cookies %} + + + + + + + + + + {% for cookie in cookies_result.cookies %} + + + + + + {% endfor %} + +
Cookie NameSecureHttpOnly
{{ cookie.name }}{% if cookie.secure %}Yes{% else %}No{% endif %}{% if cookie.http_only %}Yes{% else %}No{% endif %}
+ {% else %} + + {% endif %} + + + +
+
+
+
+ +
+
+
+ +
+
+
+ {% if cors_result.status %} + + {% else %} + + {% endif %} + Cross-Origin Resource Sharing (CORS) +
+
+

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that + allows a server to indicate any origins (domain, scheme, or port) other than its + own from which a browser should permit loading resources. CORS also relies on a + mechanism by which browsers make a "preflight" request to the server hosting the + cross-origin resource, in order to check that the server will permit the actual + request. In that preflight, the browser sends headers that indicate the HTTP + method and headers that will be used in the actual request.

+
+
+
+

Result

+
+ + + {% if cors_result.cors_headers %} + + + + + + + + + {% for header, value in cors_result.cors_headers.items %} + + + + + {% endfor %} + +
HeaderValue
{{ header }}{% if value %}{{ value }}{% else %}Not set{% endif %}
+ {% else %} + + {% endif %} + + +
+
+
+
+
+

Recommendations

+
+ Specify origins + +

Instead of using the wildcard "*", explicitly specify the + allowed origins for + cross-origin requests. + This can be done by setting the Access-Control-Allow-Origin header to a + specific + origin, such as https://nc3.lu, or to a list of trusted origins. + By explicitly specifying the allowed origins, you can prevent unauthorized + access to your resources from untrusted sources.

+ + Restrict methods and headers + +

Use the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers + to + define the allowed HTTP methods and request headers for cross-origin requests. + Only include the necessary methods and headers that your application requires, + rather than allowing all methods or headers. + This can help to reduce the attack surface of your application and protect it + from malicious requests.

+ + Validate origin + +

Implement server-side validation of the Origin header in the request to + ensure + that it matches the list of allowed origins. + This prevents attackers from spoofing the origin and bypassing CORS + restrictions. + You can use the nginx web server to implement this validation by adding the + following line to your nginx.conf file: + + add_header Access-Control-Allow-Origin $http_origin; + +

+ Use credentials carefully + +

Be cautious when enabling the Access-Control-Allow-Credentials header. + Only enable it if your application requires sending and receiving credentials + (e.g., cookies, authorization headers) across origins. + Make sure to properly handle and validate the credentials on the server-side + to + prevent unauthorized access.

+ Apply origin whitelisting + +

Consider maintaining a whitelist of trusted origins within your application's + server-side logic. + Validate incoming requests against this whitelist and only allow requests from + trusted origins. + This can help to further reduce the attack surface of your application and + protect it from malicious requests.

+ Set secure CORS headers + +

In addition to the CORS headers, ensure that your application implements + other + security headers, such as Content Security Policy (CSP), Strict Transport + Security (HSTS), and X-Frame-Options, to provide a layered security approach. + These headers can help to protect your application from a variety of attacks, + including cross-site scripting (XSS), clickjacking, and man-in-the-middle + (MITM) + attacks.

+
+
+
+
+
+ + +
+
+
+ {% if https_redirect_result.status %} + + {% else %} + + {% endif %} + HTTPS Redirect +
+
+

Properly configured redirections from HTTP to HTTPS allow browsers to correctly + apply HTTP Strict Transport Security (HSTS) settings.

+
+
+
+

Result

+
+ + {% if https_redirect_result.redirect_url %} + + {% endif %} + + + +
+
+
+
+
+

Recommendations

+
+

Use HTTPS for all websites and APIs. This is the most important security + recommendation, + as it encrypts all communication between the client and the server, making it + much more difficult + for attackers to intercept and steal data.

+

Use 301 redirects to redirect HTTP requests to HTTPS. This ensures that users + are always redirected to the secure + version of the site, even if they type in the HTTP URL.

+

Enable HSTS. HSTS (HTTP Strict Transport Security) is a security feature that + tells browsers + to always connect to your site over HTTPS, even if the user types in the HTTP + URL. + This helps to prevent attackers from tricking users into connecting to your + site over HTTP.

+

Do not redirect from HTTP to HTTPS on a different host. This can prevent HSTS + from being set.

+

Keep your SSL/TLS certificate up to date. This helps to protect your site + from attacks that exploit expired or + misconfigured certificates.

+
+
+
+
+
+ + +
+
+
+ {% if referrer_policy_result.status %} + + {% else %} + + {% endif %} + Referrer Policy +
+
+

Referrer Policy can protect the privacy of your users by restricting the + contents of the HTTP Referer header.

+
+
+
+

Result

+
+ + + {% if referrer_policy_result.header_value %} + + {% endif %} + + +
+
+
+ +
+
+

Recommendations

+
+

You can set the header in an apache configuration file or in a + root web directory over an .htaccess file.

+ +

You need to add:
+ Header set Referrer-Policy + "replace-with-the-policy-you-want-to-use" +

+
+

What policies do exist?

+
    +
  • "no-referrer"- Do not send the referrer header.
  • +
  • "no-referrer-when-downgrade" - Send the referrer header only + when + the referring page is using HTTPS. +
  • +
  • "same-origin"- Send the referrer header only when the referring + page is from the same origin (same domain and protocol). +
  • +
  • "strict-origin" - Send the referrer header only when the + referring page is from the same origin, and only include the origin, not + the full URL. +
  • +
  • "strict-origin-when-cross-origin" - Send the referrer header + only + when the referring page is from the same origin, and only include the + origin when the referring page is from a different origin. +
  • +
  • "unsafe-url" - Always send the full URL in the referrer header, + even when the referring page is from a different origin. +
  • +
+

Which one to use?

+

+ If your website doesn't need to send any referrer information to other + domains, you can use the "no-referrer" directive. This will + prevent the + browser from sending any referrer information in the HTTP header.

+ +

If your website needs to send referrer information only when the user is + navigating within your own domain, you can use the + "same-origin" directive. + This will prevent the browser from sending referrer information when the + user navigates to a different domain.

+ +

If your website needs to send referrer information to other domains, but + you + don't want to leak sensitive information, you can use the + "strict-origin-when-cross-origin" directive. This will send + the referrer + information only when the referring page is from the same origin, and will + only include the origin (not the full URL) when the referring page is from + a + different origin.

+ +

If your website needs to send referrer information to other domains, and + you + don't need to hide the URL of the referring page, you can use the "origin" + or "unsafe-url" directive. The "origin" + directive will send only the origin + (not the full URL) in the referrer header, while the + "unsafe-url" directive + will send the full URL of the referring page.

+
+
+
+
+
+
+ + +
+
+
+ {% if sri_result.status == 'green' %} + + {% elif sri_result.status == 'neutral' %} + + {% else %} + + {% endif %} + Subresource Integrity (SRI) +
+
+

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they + fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing + you to provide a cryptographic hash that a fetched file must match.

+
+
+
+

Result

+
+ + + {% if sri_result.resources %} +
+ + + + + + + + + + + + + {% for resource in sri_result.resources %} + + + + + + + + + {% endfor %} + +
TypeSourceCross-OriginHas IntegrityIntegrity ValueIntegrity Valid
{{ resource.type }}{{ resource.src }}{% if resource.is_cross_origin %}{% else %}{% endif %}{% if resource.has_integrity %}{% else %}{% endif %}{% if resource.integrity_value %}{{ resource.integrity_value }}{% else %}N/A{% endif %} + {% if resource.is_cross_origin %} + {% if resource.integrity_valid is none %} + N/A + {% elif resource.integrity_valid %} + + {% else %} + + {% endif %} + {% else %} + N/A + {% endif %} +
+
+ {% else %} + + {% endif %} + + +
+
+
+
+
+ + +
+
+
+ {% if x_content_type_options_result.status %} + + {% else %} + + {% endif %} + X-Content-Type-Options +
+
+

X-Content-Type-Options is a security header that prevents browsers from guessing the MIME type of a file, + enforcing the type declared by the server. + This helps protect against certain types of attacks, like MIME type sniffing, by ensuring content is handled as intended.

+
+
+
+

Result

+
+ +
+
+
+
+
+

Recommendations

+
+

+ Implement the X-Content-Type-Options: nosniff header on your web server to enhance security by + preventing MIME type sniffing attacks. This header ensures browsers strictly + follow the declared content type and do not try to guess the MIME type, + reducing the risk of executing malicious files. +

+ +
+
+
+ +
+
+ + +
+
+
+ {% if hsts_result.status %} + + {% else %} + + {% endif %} + HTTP Strict Transport Security (HSTS) +
+
+

+ HSTS is a web security policy mechanism that helps protect websites against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should interact with it using only secure HTTPS connections. +

+
+
+
+

Result

+
+ +
+
+
+
+
+

Recommendations

+
+ {% if hsts_result.recommendations %} +
    + {% for recommendation in hsts_result.recommendations %} +
  • {{ recommendation }}
  • + {% endfor %} +
+ {% else %} +

No specific recommendations at this time.

+ {% endif %} +
+
+
+
+
+ + +
+
+
+ {% if security_txt_result.status %} + + {% else %} + + {% endif %} + security.txt +
+
+

+ The security.txt file is used to help security researchers contact the site owner about security issues. +

+
+
+
+

Result

+
+ + {% if security_txt_result.status %} +
Content:
+
{{ security_txt_result.data }}
+ {% else %} + + {% endif %} +
+
+
+
+
+

Recommendations

+
+ {% if security_txt_result.status %} +

The security.txt file is present. Ensure it contains up-to-date information and follows the standard format.

+
    +
  • Include a "Contact" field with a way to reach your security team.
  • +
  • Add an "Expires" field to indicate when the information should be considered stale.
  • +
  • Consider adding fields like "Encryption" for a PGP key and "Preferred-Languages" for communication preferences.
  • +
+ {% else %} +

Consider implementing a security.txt file:

+
    +
  • Create a file named "security.txt" in the "/.well-known/" directory of your website.
  • +
  • Include essential fields like "Contact" and "Expires".
  • +
  • Follow the format specified in RFC 9116.
  • +
+ {% endif %} +
+
+
+
+
diff --git a/testing/templates/web-test_report.html b/testing/templates/web-test_report.html index 9311a40..45c4555 100644 --- a/testing/templates/web-test_report.html +++ b/testing/templates/web-test_report.html @@ -1,1129 +1,757 @@ -{% load tags %} -{% if result %} + + + + + + +
+ +
+

Overview of {{ domain }}

+ +
+ {% if csp_result.status %} + CSP + {% else %} + CSP + {% endif %} +
- -
-
-

Overview of {{ domain_name }}

-
-
- -
-
-
-
-
-
- {% if result.content_security_policy.pass %} - - - {% else %} - - - {% endif %} - {{ result.content_security_policy.score_description }} -
-
-
-
- {% if result.cookies.pass %} - - - {% else %} - - - {% endif %} - {{ result.cookies.score_description }} -
-
-
-
- {% if result.cross_origin_resource_sharing.pass %} - - - {% else %} - - - {% endif %} - {{ result.cross_origin_resource_sharing.score_description }} -
-
-
-
- {% if result.redirection.pass %} - - - {% else %} - - - {% endif %} - {{ result.redirection.score_description }} -
-
-
-
- {% if result.referrer_policy.pass %} - - - {% else %} - - - {% endif %} - {{ result.referrer_policy.score_description }} (optional) -
-
-
-
- {% if result.strict_transport_security.pass %} - - - {% else %} - - - {% endif %} - {{ result.strict_transport_security.score_description }} -
-
-
-
- {% if result.subresource_integrity.pass %} - - - {% else %} - - - {% endif %} - {{ result.subresource_integrity.score_description }} -
-
-
-
- {% if result.x_content_type_options.pass %} - - - {% else %} - - - {% endif %} - {{ result.x_content_type_options.score_description }} -
-
-
-
- {% if result.x_frame_options.pass %} - - - {% else %} - - - {% endif %} - {{ result.x_frame_options.score_description }} -
-
-
-
- {% if result.x_xss_protection.pass %} - - - {% else %} - - - {% endif %} - {{ result.x_xss_protection.score_description }} -
-
- - - {% if tls_results %} - {% for version, suites in tls_results.items %} -
-
- {% if tls_lowest_sec_level|get:version == 'GOOD' or tls_lowest_sec_level|get:version == 'SUFFICIENT' %} - - - {% elif tls_lowest_sec_level|get:version == 'PHASE_OUT' %} - - - {% elif tls_lowest_sec_level|get:version == 'INSUFFICIENT' %} - - - {% endif %} - {{ version }} +
+ {% if cookies_result.status %} + Cookies + {% else %} + Cookies + {% endif %}
-
- {% endfor %} - {% endif %} - -
-
-

Vulnerabilities

-
-
Good
-
- -
-
-
-
Vulnerable
-
- - -
-
-
-
Warning
-
-
-
- -
-
-
-
- -
-
-
- {% if result.content_security_policy.pass %} - - {% else %} - - {% endif %} {{ result.content_security_policy.score_description}} -
-
-

Content Security Policy (CSP) is an HTTP header that allows site operators - fine-grained control over where resources on their site can be loaded from. The - use of this header is the best method to prevent cross-site scripting (XSS) - vulnerabilities. Due to the difficulty in retrofitting CSP into existing - websites, CSP is mandatory for all new websites and is strongly recommended for - all existing high-risk sites.

-
- {% if result.content_security_policy.data %} -
- +
+ {% if referrer_policy_result.status %} + Referrer Policy + {% else %} + Referrer Policy + {% endif %} +
-
-
- The current set CSP is the following: - - Content-Security-Policy - -
-
-
- {% endif %} -
- +
+ {% if sri_result.status %} + Subresource Integrity (SRI) + {% else %} + Subresource Integrity (SRI) + {% endif %} +
-
-
-

Determine what types of resources your site should load: Before - implementing - CSP, it is important to identify which types of resources your site needs to - load such as scripts, stylesheets, images, and fonts.

-

Create a whitelist of - allowed sources:
Once you have determined the types of - resources your site needs to load, you should create a whitelist of allowed - sources for each of them. This will prevent malicious sources from injecting - unwanted code into your site.

+
+ {% if x_content_type_options_result.status %} + X-Content-Type-Options + {% else %} + X-Content-Type-Options + {% endif %} +
-

Use the Content-Security-Policy header:
Add the - Content-Security-Policy - header - to the HTTP response of your site. This header specifies the whitelist of - allowed sources for each resource type.

-

For example, the following header - specifies that only resources from the same origin as the site are allowed: -

-
    -
  • Content-Security-Policy: default-src 'self'
  • -
-

Test your CSP policy:
After implementing your CSP policy, it is - important - to - test it to ensure that it does not break any functionality of your site. You - can use rescan and check if the CSP will pass.

-

Keep your CSP policy up to date:
As your site evolves, you may - need to add - new - resources or change the sources of existing resources. Therefore, it is - important to review and update your CSP policy regularly to ensure that it - remains effective.

-
-
-
+
+ {% if hsts_result.status %} + HTTP Strict Transport Security (HSTS) + {% else %} + HTTP Strict Transport Security (HSTS) + {% endif %} +
-
-
-
-
-
- {% if result.cookies.pass %} - - {% else %} - - {% endif %} {{ result.cookies.score_description}} -
-
-

Using cookies attributes such as Secure and HttpOnly can protect users from - having their personal information stolen.

-
- {% if result.cookies.output.data %} -
- +
+ {% if security_txt_result.status %} + Security.txt + {% else %} + Security.txt + {% endif %} +
-
-
-
- {% for cookie_key, cookie_value in result.cookies.output.data.items %} -

Cookie: {{ cookie_key }}

-
    - {% for attribute_key, attribute_value in cookie_value.items %} - {% if attribute_key == "secure" and not attribute_value or attribute_key == "httponly" and not attribute_value %} -
  • {{ attribute_key }}: {{ attribute_value }} -
  • - {% else %} -
  • {{ attribute_key }}: {{ attribute_value }}
  • - {% endif %} - {% endfor %} -
- {% endfor %} +
+

Vulnerabilities

+
+ Good: {{ good }} +
+
+ Vulnerable: {{ vulnerable }} +
+
+ Pie chart of status counts +
+
-
-
-
- {% endif %} -
- - - -
-
-
-
-
-
- {% if result.cross_origin_resource_sharing.pass %} - - {% else %} - - {% endif %} {{ result.cross_origin_resource_sharing.score_description}} -
-
-

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that - allows a server to indicate any origins (domain, scheme, or port) other than its - own from which a browser should permit loading resources. CORS also relies on a - mechanism by which browsers make a "preflight" request to the server hosting the - cross-origin resource, in order to check that the server will permit the actual - request. In that preflight, the browser sends headers that indicate the HTTP - method and headers that will be used in the actual request.

-
-
- - -
-
- Specify origins - -

Instead of using the wildcard "*", explicitly specify the - allowed origins for - cross-origin requests. - This can be done by setting the Access-Control-Allow-Origin header to a - specific - origin, such as https://nc3.lu, or to a list of trusted origins. - By explicitly specifying the allowed origins, you can prevent unauthorized - access to your resources from untrusted sources.

- - Restrict methods and headers - -

Use the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers - to - define the allowed HTTP methods and request headers for cross-origin requests. - Only include the necessary methods and headers that your application requires, - rather than allowing all methods or headers. - This can help to reduce the attack surface of your application and protect it - from malicious requests.

- - Validate origin - -

Implement server-side validation of the Origin header in the request to - ensure - that it matches the list of allowed origins. - This prevents attackers from spoofing the origin and bypassing CORS - restrictions. - You can use the nginx web server to implement this validation by adding the - following line to your nginx.conf file: - - add_header Access-Control-Allow-Origin $http_origin; - -

- Use credentials carefully - -

Be cautious when enabling the Access-Control-Allow-Credentials header. - Only enable it if your application requires sending and receiving credentials - (e.g., cookies, authorization headers) across origins. - Make sure to properly handle and validate the credentials on the server-side - to - prevent unauthorized access.

- Apply origin whitelisting - -

Consider maintaining a whitelist of trusted origins within your application's - server-side logic. - Validate incoming requests against this whitelist and only allow requests from - trusted origins. - This can help to further reduce the attack surface of your application and - protect it from malicious requests.

- Set secure CORS headers - -

In addition to the CORS headers, ensure that your application implements - other - security headers, such as Content Security Policy (CSP), Strict Transport - Security (HSTS), and X-Frame-Options, to provide a layered security approach. - These headers can help to protect your application from a variety of attacks, - including cross-site scripting (XSS), clickjacking, and man-in-the-middle - (MITM) - attacks.

- -
-
-
- -
-
-
-
-
-
- {% if result.redirection.pass %} - - {% else %} - - {% endif %} {{ result.redirection.score_description}} -
-
-

Properly configured redirections from HTTP to HTTPS allow browsers to correctly - apply HTTP Strict Transport Security (HSTS) settings.

-
-
-
- - -
-
-

Use HTTPS for all websites and APIs. This is the most important security - recommendation, - as it encrypts all communication between the client and the server, making it - much more difficult - for attackers to intercept and steal data.

-

Use 301 redirects to redirect HTTP requests to HTTPS. This ensures that users - are always redirected to the secure - version of the site, even if they type in the HTTP URL.

-

Enable HSTS. HSTS (HTTP Strict Transport Security) is a security feature that - tells browsers - to always connect to your site over HTTPS, even if the user types in the HTTP - URL. - This helps to prevent attackers from tricking users into connecting to your - site over HTTP.

-

Do not redirect from HTTP to HTTPS on a different host. This can prevent HSTS - from being set.

-

Keep your SSL/TLS certificate up to date. This helps to protect your site - from attacks that exploit expired or - misconfigured certificates.

-
-
-
-
-
- + +
+

{% if csp_result.status %} + + {% else %} + + {% endif %} Content Security Policy (CSP)

+

Content Security Policy (CSP) is an HTTP header that allows site operators + fine-grained control over where resources on their site can be loaded from. The + use of this header is the best method to prevent cross-site scripting (XSS) + vulnerabilities. Due to the difficulty in retrofitting CSP into existing + websites, CSP is mandatory for all new websites and is strongly recommended for + all existing high-risk sites.

+ +

Details:

+

CSP Value: + {% if csp_result.csp_value %} + {{ csp_result.csp_value }} + {% else %} + None + {% endif %} +

-
-
-
-
- {% if result.referrer_policy.pass %} - - {% else %} - - {% endif %} {{ result.referrer_policy.score_description}} -
-
-

Referrer Policy can protect the privacy of your users by restricting the - contents of the HTTP Referer header.

-
-
-
- +

Issues:

+ {% for issue in csp_result.issues %} +
{{ issue }}
+ {% endfor %} -
-
-

You can set the header in an apache configuration file or in a - root web directory over an .htaccess file.

+

Recommendations:

+ {% for recommendation in csp_result.recommendations %} +
{{ recommendation }}
+ {% endfor %} -

You need to add:
- Header set Referrer-Policy - "replace-with-the-policy-you-want-to-use" -

-
-

What policies do exist?

-
    -
  • "no-referrer"- Do not send the referrer header.
  • -
  • "no-referrer-when-downgrade" - Send the referrer header only - when - the referring page is using HTTPS. -
  • -
  • "same-origin"- Send the referrer header only when the referring - page is from the same origin (same domain and protocol). -
  • -
  • "strict-origin" - Send the referrer header only when the - referring page is from the same origin, and only include the origin, not - the full URL. -
  • -
  • "strict-origin-when-cross-origin" - Send the referrer header - only - when the referring page is from the same origin, and only include the - origin when the referring page is from a different origin. -
  • -
  • "unsafe-url" - Always send the full URL in the referrer header, - even when the referring page is from a different origin. -
  • -
-

Which one to use?

-

- If your website doesn't need to send any referrer information to other - domains, you can use the "no-referrer" directive. This will - prevent the - browser from sending any referrer information in the HTTP header.

+

How to implement the CSP?

+
+

Determine what types of resources your site should load: before + implementing CSP, it is important to identify which types of resources + your site needs to load such as scripts, stylesheets, images, and fonts.

+

Create a whitelist of allowed sources:
+ Once you have determined the types of + resources your site needs to load, you should create a whitelist of allowed + sources for each of them. This will prevent malicious sources from injecting + unwanted code into your site.

+ +

Use the Content-Security-Policy header:
Add the + Content-Security-Policy + header + to the HTTP response of your site. This header specifies the whitelist of + allowed sources for each resource type.

+

For example, the following header + specifies that only resources from the same origin as the site are allowed: +

+
    +
  • Content-Security-Policy: default-src 'self'
  • +
+

Test your CSP policy:
After implementing your CSP policy, it is + important + to + test it to ensure that it does not break any functionality of your site. You + can use rescan and check if the CSP will pass.

+

Keep your CSP policy up to date:
As your site evolves, you may + need to add + new + resources or change the sources of existing resources. Therefore, it is + important to review and update your CSP policy regularly to ensure that it + remains effective.

+
+
-

If your website needs to send referrer information only when the user is - navigating within your own domain, you can use the - "same-origin" directive. - This will prevent the browser from sending referrer information when the - user navigates to a different domain.

+ +
+

{% if cookies_result.status %} + + {% else %} + + {% endif %} Cookies

+

Using cookies attributes such as Secure and HttpOnly can protect users from + having their personal information stolen.

+ +

Result:

+ {% if cookies_result.cookies %} + + + + + + + + + + {% for cookie in cookies_result.cookies %} + + + + + + {% endfor %} + +
Cookie NameSecureHttpOnly
{{ cookie.name }}{% if cookie.secure %}Yes{% else %}No{% endif %}{% if cookie.http_only %}Yes{% else %}No{% endif %}
+ {% else %} +
No cookies found.
+ {% endif %} -

If your website needs to send referrer information to other domains, but - you - don't want to leak sensitive information, you can use the - "strict-origin-when-cross-origin" directive. This will send - the referrer - information only when the referring page is from the same origin, and will - only include the origin (not the full URL) when the referring page is from - a - different origin.

+
+ Overall status: {% if cookies_result.status %}All cookies are secure and HttpOnly{% else %}Some cookies are not secure or HttpOnly{% endif %} +
-

If your website needs to send referrer information to other domains, and - you - don't need to hide the URL of the referring page, you can use the "origin" - or "unsafe-url" directive. The "origin" - directive will send only the origin - (not the full URL) in the referrer header, while the - "unsafe-url" directive - will send the full URL of the referring page.

+

Recommendations:

+
-
-
-
-
-
-
-
-
- {% if result.subresource_integrity.pass %} - - {% else %} - - {% endif %} - {{ result.subresource_integrity.score_description}} -
-
-

Subresource Integrity (SRI) is a security feature that enables browsers to - verify that files they fetch (for example, from a CDN) - are delivered without unexpected manipulation. It works by allowing you to - provide a cryptographic hash that a fetched file must match. -

-
-
- {% if result.subresource_integrity.output.data %} -
- - - -
-
+ +
+

{% if cors_result.status %} + + {% else %} + + {% endif %} Cross-Origin Resource Sharing (CORS)

+

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that + allows a server to indicate any origins (domain, scheme, or port) other than its + own from which a browser should permit loading resources. CORS also relies on a + mechanism by which browsers make a "preflight" request to the server hosting the + cross-origin resource, in order to check that the server will permit the actual + request. In that preflight, the browser sends headers that indicate the HTTP + method and headers that will be used in the actual request.

+ +

Result:

+
+ CORS is {% if cors_result.status %}configured{% else %}not configured{% endif %}. +
-
-
-
- {% endif %} -
-
+ {% if cors_result.cors_headers %} + + + + + + + + + {% for header, value in cors_result.cors_headers.items %} + + + + + {% endfor %} + +
HeaderValue
{{ header }}{{ value }}
+ {% else %} +
No CORS headers found.
+ {% endif %} - -{% endif %} + {% if referrer_policy_result.header_value %} +
+ Referrer-Policy: {{ referrer_policy_result.header_value }} +
+ {% endif %} - - +
+

{% if sri_result.status == 'green' %} + + {% elif sri_result.status == 'neutral' %} + + {% else %} + + {% endif %} Subresource Integrity (SRI)

+

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they + fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing + you to provide a cryptographic hash that a fetched file must match.

+ +

Result:

+ +
+
+ {{ sri_result.message }} +
+ + {% if sri_result.resources %} +
+ + + + + + + + + + + {% for resource in sri_result.resources %} + + + + + + + {% endfor %} + +
SourceCross-OriginHas IntegrityIntegrity Valid
{{ resource.src }}{% if resource.is_cross_origin %}{% else %}{% endif %}{% if resource.has_integrity %}{% else %}{% endif %} + {% if resource.is_cross_origin %} + {% if resource.integrity_valid is none %} + N/A + {% elif resource.integrity_valid %} + + {% else %} + + {% endif %} + {% else %} + N/A + {% endif %} +
+
+ {% else %} +
+ No resources found. +
+ {% endif %} -
-
-

IPv6 Test Results

-
+
+ Overall status: {{ sri_result.message }} +
+
+
-

Records:

- {% if records %} - - - - - - - {% for record in records %} - - - - - -
ServerIPv4IPv6
{{ record.0 }}{{ record.1 }}{{ record.2 }}
- {% if record.2 %} -

- - Your server has an IPv6 address. -

- {% else %} -

+ +

+

{% if x_content_type_options_result.status %} + + {% else %} - Your server does not have an IPv6 address. -

- {% endif %} + {% endif %} X-Content-Type-Options

+

X-Content-Type-Options is a security header that prevents browsers from guessing the MIME type of a file, + enforcing the type declared by the server. + This helps protect against certain types of attacks, like MIME type sniffing, by ensuring content is handled as intended.

+

Result

+
+ {{ x_content_type_options_result.message }} +
+

Recommendations:

+
+

Implement the X-Content-Type-Options: nosniff header on your web server to enhance security by + preventing MIME type sniffing attacks. This header ensures browsers strictly follow the + declared content type and do not try to guess the MIME type, reducing the risk of executing malicious files.

+
+
- {% endfor %} - {% endif %} -

- {% if records_v4_comments.grade == "full" %} - - {% elif records_v4_comments.grade == "null" %} - + +

+

{% if hsts_result.status %} + + {% else %} + + {% endif %} HTTP Strict Transport Security (HSTS)

+

+ HSTS is a web security policy mechanism that helps protect websites against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers should interact with it using only secure HTTPS connections. +

+

Result:

+
+

HSTS Details

+

Status: + {% if hsts_result.status %} + 'Implemented' + {% else %} + 'Not Implemented' + {% endif %} +

+

HTTP Status: {{ hsts_result.http_status }}

+

HSTS Header: {{ hsts_result.data }}

+

Preload Ready: + {% if hsts_result.preload_ready %} + 'Yes' + {% else %} + 'No' + {% endif %} +

+

Implementation Strength: {{ hsts_result.strength }}

+ {% if hsts_result.parsed %} +
Parsed Header:
+
    + {% for key, value in hsts_result.parsed.items %} +
  • {{ key }}: {{ value }}
  • + {% endfor %} +
{% endif %} - {{ records_v4_comments.comment }} -

-

- {% if records_v6_comments.grade == "full" %} - - {% elif records_v6_comments.grade == "null" %} - +

+

Recommendations:

+
+ {% if hsts_result.recommendations %} +
    + {% for recommendation in hsts_result.recommendations %} +
  • {{ recommendation }}
  • + {% endfor %} +
+ {% else %} +

No specific recommendations at this time.

{% endif %} - {{ records_v6_comments.comment }} -

-
-
-
-
- -
-
+ +
+

{% if security_txt_result.status %} + + {% else %} + + {% endif %} security.txt

- IPv6 is the next generation of the Internet Protocol, and it offers a - number of advantages over IPv4, the current version of the protocol. + The security.txt file is used to help security researchers contact the site owner about security issues.

-
    -
  • - Address exhaustion: IPv4 is running out of available addresses due to - the rapid growth of connected devices. IPv6 provides a significantly - larger address space, ensuring that there are enough unique IP addresses - to accommodate the expanding number of devices and services. -
  • -
  • - Future-proofing: As the industry shifts towards IPv6, enabling IPv6 - support ensures compatibility and seamless communication with the - growing number of IPv6-enabled networks and devices. It future-proofs - your infrastructure, avoiding potential connectivity issues and the need - for costly workarounds. -
  • -
  • - Enhanced functionality: IPv6 offers improvements in areas such as - auto-configuration, mobility, and quality of service, allowing for more - efficient and advanced network operations. Enabling IPv6 unlocks these - enhanced functionalities, promoting a better user experience and - enabling innovative applications and services. -
  • -
  • - Global reachability: With IPv6, your services can reach a larger global - audience, including regions and networks that primarily use IPv6. By - enabling IPv6, you expand your online presence and increase - accessibility to your web services. -
  • -
  • - Security advancements: IPv6 includes built-in security features, such as - IPsec (Internet Protocol Security), which provides native encryption, - authentication, and data integrity. Enabling IPv6 allows you to leverage - these security enhancements, improving the confidentiality and integrity - of your network traffic. -
  • -
- -
+

Result:

+
+

security.txt Status

+

{% if security_txt_result.status %}Found{% else %}Not Found{% endif %}

+
+ {% if security_txt_result.status %} +
Content:
+
{{ security_txt_result.data }}
+ {% else %} +
+ {{ security_txt_result.data }} +
+ {% endif %} +

Recommendations:

+
+ {% if security_txt_result.status %} +

The security.txt file is present. Ensure it contains up-to-date information and follows the standard format.

+
    +
  • Include a "Contact" field with a way to reach your security team.
  • +
  • Add an "Expires" field to indicate when the information should be considered stale.
  • +
  • Consider adding fields like "Encryption" for a PGP key and "Preferred-Languages" for communication preferences.
  • +
+ {% else %} +

Consider implementing a security.txt file:

+
    +
  • Create a file named "security.txt" in the "/.well-known/" directory of your website.
  • +
  • Include essential fields like "Contact" and "Expires".
  • +
  • Follow the format specified in RFC 9116.
  • +
+ {% endif %} +
-
-
-
---> - {% if tls_results %} -
-
-
- TLS Results -
-
- Transport Layer Security (TLS) is a cryptographic protocol that protects data in - transit over a network. It does this by establishing a secure channel between two - communicating applications, using a handshake process to agree on the protocol - version, cryptographic algorithms, and exchange cryptographic keys. This ensures - that the data is confidential, authentic, and integral, protecting against - eavesdropping, tampering, or message forgery. -
- {% for version, suites in tls_results.items %} -
- - -
-
- - - - - - {% for name, info in suites.items %} - - - - - {% endfor %} -
CiphersuiteSecurity level
{{ name }} - {% if info.sec_level.level == "GOOD" or info.sec_level.level == "SUFFICIENT" %} - - {% elif info.sec_level.level == "PHASE_OUT" %} - - {% elif info.sec_level.level == "INSUFFICIENT" %} - - {% endif %} - {{ info.sec_level.level }} -
-
-
-
- - {% endfor %} - -
- - -
-
- - Stay Updated: -
    -
  • Always use the latest TLS versions to benefit from improved security - features. -
  • - -
  • Disable outdated and vulnerable protocols like SSL to prevent potential - attacks. -
  • -
  • Prioritize strong cipher suites to ensure robust encryption and - authentication. -
  • -
- Manage Certificates: -
    -
  • Obtain certificates from trusted Certificate Authorities (CAs) to - establish trust with your users. -
  • -
  • Regularly check and monitor for any certificate revocations to maintain - the integrity of your certificates. -
  • -
  • Implement certificate pinning to protect against fraudulent or compromised - certificates. -
  • -
- Implement Perfect Forward Secrecy (PFS): -
    -
  • Enable Perfect Forward Secrecy to ensure that past communications remain - secure even if private keys are compromised. -
  • -
  • By generating unique session keys, PFS adds an extra layer of - confidentiality to your data. -
  • -
- - Use Strong Cryptography: -
    -
  • Employ strong cryptographic algorithms for encryption, key exchange, and - hashing. -
  • -
  • Regularly update your cryptographic libraries to address any emerging - vulnerabilities and ensure optimal security. -
  • -
- - Disable Vulnerable Features: -
    -
  • Disable insecure protocols such as SSLv2, SSLv3, and outdated TLS versions - (e.g., TLS 1.0, TLS 1.1). -
  • -
  • Remove weak ciphers, like those using the RC4 encryption algorithm or - outdated key sizes, to eliminate potential security risks. -
  • -
- -
-
-
-
-
- - -{% endif %} - - + + diff --git a/testing/views.py b/testing/views.py index 3fb23fc..b68d69e 100644 --- a/testing/views.py +++ b/testing/views.py @@ -3,23 +3,17 @@ import os import re import socket -import time -import io - -import jinja2 import xmltodict -from bs4 import BeautifulSoup import weasyprint +import matplotlib.pyplot as plt +import base64 +from io import BytesIO from typing import Any, Dict from urllib.parse import parse_qs, urlparse -import zapv2 from ipwhois import IPDefinedError, IPWhois -from zapv2 import ZAPv2 -from reportlab.pdfgen import canvas -from django.http import FileResponse from django.contrib import messages from django.contrib.auth.decorators import login_required from django.core.files.base import ContentFile @@ -27,6 +21,8 @@ from django.shortcuts import redirect, render from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods +from django.template.loader import get_template +from wkhtmltopdf.views import PDFTemplateResponse from testing_platform import settings @@ -201,6 +197,16 @@ def check_website_security(request): 'security_txt_result': security_txt_result } + try: + test_report = TestReport.objects.get(tested_site=domain, test_ran="web-test") + test_report.report = context + test_report.save() + except TestReport.DoesNotExist: + test_report = TestReport.objects.get_or_create( + tested_site=domain, + test_ran="web-test", + report=context + ) return render(request, 'check_webapp.html', context) return render(request, 'check_webapp.html') @@ -233,8 +239,19 @@ def email_test(request): context['dmarc'], context['dmarc_valid'] = check_dmarc(target) context['dkim'], context['dkim_valid'] = check_dkim(target, dkim_selector) + try: + test_report = TestReport.objects.get(tested_site=target, test_ran="email-test") + test_report.report = context + test_report.save() + except TestReport.DoesNotExist: + test_report = TestReport.objects.get_or_create( + tested_site=target, + test_ran="email-test", + report=context + ) + nb_tests += 1 - response = render(request, "check_email.html", {"result": context}) + response = render(request, "check_email.html", context) response.set_cookie("nb_tests", nb_tests) return response else: @@ -286,8 +303,21 @@ def web_server_test(request): "You reached the maximum number of tests. Please create an account.", ) return redirect("signup") - context = {} - context.update(web_server_check(request.POST["target"])) + domain = request.POST["target"] + context = {'domain': domain} + context.update(web_server_check(domain)) + + try: + test_report = TestReport.objects.get(tested_site=domain, test_ran="infra-test") + test_report.report = context + test_report.save() + except TestReport.DoesNotExist: + test_report = TestReport.objects.get_or_create( + tested_site=domain, + test_ran="infra-test", + report=context + ) + nb_tests += 1 response = render(request, "check_infra.html", context) response.set_cookie("nb_tests", nb_tests) @@ -545,39 +575,76 @@ def dmarc_upload(request): return HttpResponse(status=401) -def export_pdf(request, test): - # Create a file-like buffer to receive PDF data. - buffer = io.BytesIO() - - # Create the PDF object, using the buffer as its "file." - p = canvas.Canvas(buffer) - - # Draw things on the PDF. Here's where the PDF generation happens. - # See the ReportLab documentation for the full list of functionality. - - # Close the PDF object cleanly, and we're done. - p.showPage() - p.save() - - # FileResponse sets the Content-Disposition header so that browsers - # present the option to save the file. - buffer.seek(0) - return FileResponse(buffer, as_attachment=True, filename="hello.pdf") - - def pdf_from_template(request, test, site): - env = jinja2.Environment(loader=jinja2.PackageLoader('testing', 'templates')) - template = env.get_template('zap_pdf_wrapper.html') report = TestReport.objects.get(tested_site=site, test_ran=test).report css_path = os.path.join(settings.STATIC_DIR, 'css/style.css') + bootstrap_path = os.path.join(settings.STATIC_DIR, 'npm_components/bootstrap/dist/css/bootstrap.css') with open(css_path, 'r') as f: - css_content = f.read() - - html_out = template.render(report, static_url=css_path, test=test, site=site) + css = f.read() + + with open(bootstrap_path, 'r') as f: + bootstrap = f.read() + + css_content = bootstrap + '\n' + css + + # Calculate stats + count_good = 0 + count_vulnerable = 0 + if test == "web-test": + for key, value in report.items(): + if isinstance(value, dict) and 'status' in value: + if value['status'] is False: + count_vulnerable += 1 + else: + count_good += 1 + + elif test == "email-test": + if report['spf_valid'] is True: + count_good += 1 + else: + count_vulnerable += 1 + if report['dmarc_valid'] is True: + count_good += 1 + else: + count_vulnerable += 1 + if report['dnssec'] is True: + count_good += 1 + else: + count_vulnerable += 1 + + report['good'] = count_good + report['vulnerable'] = count_vulnerable + + # Generate pie chart + try: + labels = ['Good', 'Vulnerable'] + sizes = [count_good, count_vulnerable] + colors = ['green', 'red'] + plt.figure(figsize=(4, 4)) + plt.pie(sizes, labels=labels, labeldistance=0.3, colors=colors, autopct=None, + startangle=90, shadow=False) + plt.axis('equal') + + # Save the chart as a PNG image + buffer = BytesIO() + plt.savefig(buffer, format='png') + buffer.seek(0) + image_png = buffer.getvalue() + buffer.close() + image_base64 = base64.b64encode(image_png).decode('utf-8') + report['img'] = image_base64 + except ValueError as e: + pass + + template = get_template("pdf_wrapper.html") + report['site'] = site + report['test'] = test + + html_out = template.render(report) pdf_file = weasyprint.HTML(string=html_out).write_pdf(stylesheets=[weasyprint.CSS(string=css_content)]) response = HttpResponse(pdf_file, content_type='application/pdf') - response['Content-Disposition'] = f'attachment; filename="{test}_{site}_report.pdf"' + response['Content-Disposition'] = f'attachment; filename="tp_{test}_{site}_report.pdf"' return response