Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SecurityError: The operation is insecure #382

Open
magician11 opened this issue Jul 14, 2022 · 1 comment
Open

SecurityError: The operation is insecure #382

magician11 opened this issue Jul 14, 2022 · 1 comment

Comments

@magician11
Copy link

magician11 commented Jul 14, 2022

I have a component that looks like this...

import { useState, useRef } from 'react';
import {
  Button,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogContentText,
  Slider,
  Box
} from '@mui/material';
import AvatarEditor from 'react-avatar-editor';
import { CloudUpload } from '@mui/icons-material';

const ImageEditor = ({
  editImage,
  setEditImage,
  editedImage,
  initialImage
}) => {
  const [imageFile, setImageFile] = useState(initialImage);
  const [scale, setScale] = useState(1);
  const setEditorRef = useRef();

  const saveImage = () => {
    if (setEditorRef) {
      const canvas = setEditorRef.current.getImage();
      canvas.toBlob(blob => editedImage(blob));
      setEditImage(false);
    }
  };

  const editorDimenson = 272;

  return (
    <Dialog open={editImage} onClose={() => setEditImage(false)}>
      <DialogTitle>Profile image</DialogTitle>
      <DialogContent>
        <DialogContentText gutterBottom>
          Choose your profile image
        </DialogContentText>

        <AvatarEditor
          ref={setEditorRef}
          image={imageFile}
          width={editorDimenson}
          height={editorDimenson}
          border={8}
          color={[0, 0, 0, 0.8]}
          scale={scale}
          rotate={0}
        />
        <Box>
          <input
            color="primary"
            accept="image/*"
            type="file"
            onChange={event => setImageFile(event.target.files[0])}
            id="icon-button-file"
            hidden
          />
          <label htmlFor="icon-button-file">
            <Button
              variant="outlined"
              component="span"
              size="small"
              startIcon={<CloudUpload />}
            >
              Select profile photo
            </Button>
          </label>
        </Box>

        <Slider
          aria-label="Volume"
          value={scale}
          step={0.1}
          min={1}
          max={3}
          onChange={(evt, newValue) => setScale(newValue)}
        />
        <Button onClick={() => saveImage()} variant="contained">
          Update
        </Button>
      </DialogContent>
    </Dialog>
  );
};

export default ImageEditor;

Basically clicking "Update" and triggering the saveImage() function, results in this security error. In Firefox I get the above error "The operation is insecure". In Chrome I get a slightly more detailed message which says "Tainted canvases may not be exported."

Specifically it's from the line where canvas.toBlob is called.

I can see from the docs https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob a reference to this error. I'm just not sure how to fix it.

@dmitry-kovalev
Copy link

Maybe it's too late for @magician11, but useful for other users.
You can try to set the crossOrigin property to anonymous.

        <AvatarEditor
          ref={setEditorRef}
          image={imageFile}
          width={editorDimenson}
          height={editorDimenson}
          border={8}
          color={[0, 0, 0, 0.8]}
          scale={scale}
          rotate={0}
          crossOrigin={'anonymous'}
        />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants