←back to thread

669 points danso | 1 comments | | HN request time: 0.27s | source
Show context
snazz ◴[] No.23261598[source]
Here's the relevant frontend source code for the file upload picker, if anyone's wondering (webpack://src/components/exam/submissions/FileInput.js):

  <input
            type="file"
            ref={inputRef}
            name="fileupload"
            disabled={disabled}
            accept={EXTENSIONS[type]}
            data-cb-element="no-cb"
            onChange={async e => {
              const [file] = Object.keys(e.target.files).map(key => e.target.files[key])
              const fileSizeInMb = file.size/(CONVERSION_BASE*CONVERSION_BASE)
              const fileSizeInKb = file.size/CONVERSION_BASE
              const split = file.name.split('.')
              const fileType = split[split.length-1].toLowerCase()
              const extensions = EXTENSIONS[type].split(', ')
              const isAllowedExtension = extensions.includes(`.${fileType}`)
              const alreadyExists = files.find(f => f.name === file.name && f.size === file.size && f.lastModified === file.lastModified)
              let error

              if (alreadyExists)
                error = { title: 'You have already uploaded a file with the same name.', details: 'Please attach a different file.' }
              else if (!isAllowedExtension)
                error = { title: 'This file type is not acceptable.', details: 'Please check the requirements, save your file in one of the accepted formats, and resubmit.' }
              else if (fileSizeInKb <= minSize)
                error = { title: 'Your file is too small.', details: 'Please check the file-size requirements, save a larger version, and resubmit.' }
              else if (fileSizeInMb > maxSize)
                error = { title: 'Your file is too big.', details: 'Please check the file-size requirements, save a smaller version, and resubmit. ' }
            
              if (error)
                await setError(<><strong>{error.title}</strong> {error.details}</>)
              else {
                await updateFiles(file)
                setError(null)
              }

              inputRef.current.value = null
            }}
          />
The EXTENSIONS variable is defined here:

  export const EXTENSIONS = {
    [TYPE_DOC]: '.txt, .doc, .docx, .pdf, .odt',
    [TYPE_PHOTO]: '.png, .jpg, .jpeg',
    [TYPE_AUDIO]: '.m4a, .mp3, .wav, .ogg'
  }
replies(4): >>23262022 #>>23262067 #>>23263420 #>>23266424 #
scott_s ◴[] No.23262067[source]
I'm trying to square this with the fact people pointed out downthread, which is that iPhones will automatically convert HEIC images to jpeg from an HTML input form. Perhaps it's the `isAllowedExtension` check? If `e.target.files` is the actual file names on disk (and not whatever temporary file the browser made out of the HEIC file), that would cause a problem.
replies(2): >>23262429 #>>23263533 #
acqq ◴[] No.23262429[source]
Apparently somebody claims to have been able to change the extension and submit the picture, but got "file corrupted" later:

"Senior Dave Spencer took a demo test before his Calculus AB exam to make sure he understood the process for uploading photos. He Airdropped an iPhone image of his responses to his Mac and tried to convert it by renaming the HEIC file to PNG. Changing a file’s extension does not guarantee that it will be converted, but Spencer was still able to submit the demo test with no problem.

Spencer used the same process on the real exam and thought it went through, but he received an email the next day saying the files were corrupted and that he needed to retake the test."

replies(3): >>23262587 #>>23262762 #>>23264041 #
1. hysan ◴[] No.23264041[source]
As someone who started their career in QA and volunteered with IT support for non-technical organizations, this is one of the first test cases I would have thought to try.

Never trust user input!

Frontend validation can never be trusted. It’s only good for giving faster feedback for a nicer user experience. You should always have backend validation.

I’ve seen people do some weird stuff before because the majority of users don’t really understand much about file types. Users rename file extension all of the time thinking it’ll magically convert a file into something that can be opened by their program of choice.

This is just poor QA by the College Board.