SchoolDay uses advanced security to protect user privacy and data. This includes:

SSL/HTTPS Full encryption to protect against data transferred between client and server.

We store and protect the privacy of passwords using a PBKDF2 algorithm with a SHA256 hash.

Cross site scripting (XSS) protection

  • XSS attacks allow a user to inject client side scripts into the browsers of other users. This is usually achieved by storing the malicious scripts in the database where it will be retrieved and displayed to other users, or by getting users to click a link which will cause the attacker’s JavaScript to be executed by the user’s browser. However, XSS attacks can originate from any untrusted source of data, such as cookies or Web services, whenever the data is not sufficiently sanitized before including in a page.

Cross site request forgery (CSRF) protection

  • CSRF attacks allow a malicious user to execute actions using the credentials of another user without that user’s knowledge or consent.

SQL injection protection

  • SQL injection is a type of attack where a malicious user is able to execute arbitrary SQL code on a database. This can result in records being deleted or data leakage.

Clickjacking protection.

  • Clickjacking is a type of attack where a malicious site wraps another site in a frame. This attack can result in an unsuspecting user being tricked into performing unintended actions on the target site.

Host header validation

  • We use the Host header provided by the client to construct URLs in certain cases. While these values are sanitized to prevent Cross Site Scripting attacks, a fake Host value can be used for Cross-Site Request Forgery, cache poisoning attacks, and poisoning links in emails. Because even seemingly-secure web server configurations are susceptible to fake Host headers, Django validates Host headers against the ALLOWED_HOSTS setting in the django.http.HttpRequest.get_host() method. This validation only applies via get_host(); if your code accesses the Host header directly from request.META you are bypassing this security protection. For more details see the full ALLOWED_HOSTS documentation.

Session security

  • Similar to the CSRF limitations requiring a site to be deployed such that untrusted users don’t have access to any subdomains, django.contrib.sessions also has limitations.

User-uploaded content

  • We limit uploads in the Web server configuration to a reasonable size in order to prevent denial of service (DOS) attacks.
  • No bulletproof technical solution exists at the framework level to safely validate all user uploaded file content, however, these are other steps we take to mitigate these attacks:

  1. One class of attacks can be prevented by always serving user uploaded content from a distinct top-level or second-level domain. This prevents any exploit blocked by same-origin policy protections such as cross site scripting. For example, if your site runs on, you would want to serve uploaded content (the MEDIA_URL setting) from something like It’s not sufficient to serve content from a subdomain like
  2. Beyond this, applications may choose to define a whitelist of allowable file extensions for user uploaded files and configure the web server to only serve such files.

Additional security measures

  • Our Python code is outside of the Web server’s root. This ensures that Python code is not accidentally served as plain text (or accidentally executed).
  • To protect against brute-force attacks against the authentication system, we deploy a Django plugin or Web server module to throttle these requests.