JavaScript FileReader API不尊重接受的类型。

huangapple go评论78阅读模式
英文:

JavaScript FileReader API isn't respecting accept type

问题

我正在使用JavaScript的FileReader来在我的Web应用程序中上传文件。我想限制接受的文件类型只能是.pem.key。然而,我注意到我也能上传.crt.cer文件。我的实现有什么问题吗?我正在使用以下代码:

<input
  type="file"
  accept=".key, .pem"
/>
英文:

I am using the JavaScript FileReader to upload files in my web application. I want to restrict the accepted file types to only .pem and .key. However, I noticed that I am able to upload .crt and .cer files as well. Is there something wrong with my implementation? I am using the following code:

&lt;input
  type=&quot;file&quot;
  accept=&quot;.key, .pem&quot;
/&gt;

答案1

得分: 2

另一个答案是正确的,您不应该依赖accept属性来安全地过滤文件的类型,但可以注意到这实际上是一个Chrome错误(可能是特定于macOS的)。根据规范,如果逗号分隔的令牌列表中的令牌是:

> 第一个字符是U+002E FULL STOP字符(.)的字符串。
> 表示接受具有指定文件扩展名的文件。

然而,似乎Chrome实际上查看操作系统注册表,因此如果在您的操作系统上.pem文件与.cer文件一起注册,即使您只设置了accept=" .pem",它们也都会被接受。

这在我的macOS系统上是这种情况,其中lsregister -dump给出了以下结果:

type id:                    public.x509-certificate (0xc634)
bundle:                     CoreTypes (0x1d34)
uti:                        public.x509-certificate
localizedDescription:       &quot;ar&quot; = &quot;شهادة (X.509)&quot;, &quot;ca&quot; = &quot;certificat (X.509)&quot;, &quot;cs&quot; = &quot;certifik&#225;t (X.509)&quot;, &quot;da&quot; = &quot;certifikat (X.509)&quot;, &quot;de&quot; = &quot;Zertifikat (X.509)&quot;, &quot;el&quot; = &quot;πιστοποιητικό (X.509)&quot;, &quot;en&quot; = &quot;certificate (X.509)&quot;, &quot;en_AU&quot; = &quot;certificate (X.509)&quot;, &quot;en_GB&quot; = &quot;certificate (X.509)&quot;, &quot;es&quot; = &quot;certificado (X.509)&quot;, &quot;es_419&quot; = &quot;certificado (X.509)&quot;, &quot;fi&quot; = &quot;varmenne (X.509)&quot;, &quot;fr&quot; = &quot;certificat (X.509)&quot;, &quot;fr_CA&quot; = &quot;certificat (X.509)&quot;, &quot;he&quot; = &quot;אישור (X.509)&quot;, &quot;hi&quot; = &quot;सर्टिफ़िकेट (X.509)&quot;, &quot;hr&quot; = &quot;certifikat (X.509)&quot;, &quot;hu&quot; = &quot;tan&#250;s&#237;tv&#225;ny (X.509)&quot;, &quot;id&quot; = &quot;sertifikat (X.509)&quot;, &quot;it&quot; = &quot;certificato (X.509)&quot;, &quot;ja&quot; = &quot;証明書(X.509)&quot;, &quot;ko&quot; = &quot;인증서(X.509)&quot;, &quot;LSDefaultLocalizedValue&quot; = &quot;certificate (X.509)&quot;, &quot;ms&quot; = &quot;sijil (X.509)&quot;, &quot;nl&quot; = &quot;certificaat (X.509)&quot;, &quot;no&quot; = &quot;sertifikat (X.509)&quot;, &quot;pl&quot; = &quot;certyfikat (X.509)&quot;, &quot;pt_BR&quot; = &quot;certificado (X.509)&quot;, &quot;pt_PT&quot; = &quot;certificado (X.509)&quot;, &quot;ro&quot; = &quot;certificat (X.509)&quot;, &quot;ru&quot; = &quot;сертификат (X.509)&quot;, &quot;sk&quot; = &quot;certifik&#225;t (X.509)&quot;, &quot;sv&quot; = &quot;certifikat (X.509)&quot;, &quot;th&quot; = &quot;ใบรับรอง (X.509)&quot;, &quot;tr&quot; = &quot;sertifika (X.509)&quot;, &quot;uk&quot; = &quot;сертифікат (X.509)&quot;, &quot;vi&quot; = &quot;chứng nhận (X.509)&quot;, &quot;zh_CN&quot; = &quot;证书(X.509)&quot;, &quot;zh_HK&quot; = &quot;證書(X.509)&quot;, &quot;zh_TW&quot; = &quot;憑證(X.509)&quot;
flags:                      active  public  apple-internal  exported  core  trusted (0000000000000077)
conforms to:                public.data
tags:                       .cer, .der, .crt, .pem, application/x-x509-ca-cert

正如您所看到的,所有这些扩展都共享相同的type id,因此在我的Chrome中它们都是等效的。在Firefox中情况并非如此,它确实遵守规范,并根据扩展名进行真正的过滤。

(注意:我认为没有任何东西会影响这些扩展。)

不幸的是,您无法做太多事情,因为使用MIME类型(application/x-x509-ca-cert)将产生完全相同的结果。最好的方法是标记链接的问题,希望他们能在某一天修复它。

英文:

The other answer is right that you shouldn't rely on the accept attribute to safely filter the file's types, but one might note that this is actually a Chrome Bug (probably macOS specific).
According to the specs, if the token in the list of comma separated tokens is

> A string whose first character is a U+002E FULL STOP character (.).
> [It i]ndicates that files with the specified file extension are accepted.

However it seems that Chrome does look at the OS registry instead, and thus if on your OS .pem files are registered along with .cer files, they'll both be accepted even if you did only set accept=&quot;.pem&quot;.

This is the case on my macOS system where an lsregister -dump gives

type id:                    public.x509-certificate (0xc634)
bundle:                     CoreTypes (0x1d34)
uti:                        public.x509-certificate
localizedDescription:       &quot;ar&quot; = &quot;شهادة (X.509)&quot;, &quot;ca&quot; = &quot;certificat (X.509)&quot;, &quot;cs&quot; = &quot;certifik&#225;t (X.509)&quot;, &quot;da&quot; = &quot;certifikat (X.509)&quot;, &quot;de&quot; = &quot;Zertifikat (X.509)&quot;, &quot;el&quot; = &quot;πιστοποιητικό (X.509)&quot;, &quot;en&quot; = &quot;certificate (X.509)&quot;, &quot;en_AU&quot; = &quot;certificate (X.509)&quot;, &quot;en_GB&quot; = &quot;certificate (X.509)&quot;, &quot;es&quot; = &quot;certificado (X.509)&quot;, &quot;es_419&quot; = &quot;certificado (X.509)&quot;, &quot;fi&quot; = &quot;varmenne (X.509)&quot;, &quot;fr&quot; = &quot;certificat (X.509)&quot;, &quot;fr_CA&quot; = &quot;certificat (X.509)&quot;, &quot;he&quot; = &quot;אישור (X.509)&quot;, &quot;hi&quot; = &quot;सर्टिफ़िकेट (X.509)&quot;, &quot;hr&quot; = &quot;certifikat (X.509)&quot;, &quot;hu&quot; = &quot;tan&#250;s&#237;tv&#225;ny (X.509)&quot;, &quot;id&quot; = &quot;sertifikat (X.509)&quot;, &quot;it&quot; = &quot;certificato (X.509)&quot;, &quot;ja&quot; = &quot;証明書(X.509)&quot;, &quot;ko&quot; = &quot;인증서(X.509)&quot;, &quot;LSDefaultLocalizedValue&quot; = &quot;certificate (X.509)&quot;, &quot;ms&quot; = &quot;sijil (X.509)&quot;, &quot;nl&quot; = &quot;certificaat (X.509)&quot;, &quot;no&quot; = &quot;sertifikat (X.509)&quot;, &quot;pl&quot; = &quot;certyfikat (X.509)&quot;, &quot;pt_BR&quot; = &quot;certificado (X.509)&quot;, &quot;pt_PT&quot; = &quot;certificado (X.509)&quot;, &quot;ro&quot; = &quot;certificat (X.509)&quot;, &quot;ru&quot; = &quot;сертификат (X.509)&quot;, &quot;sk&quot; = &quot;certifik&#225;t (X.509)&quot;, &quot;sv&quot; = &quot;certifikat (X.509)&quot;, &quot;th&quot; = &quot;ใบรับรอง (X.509)&quot;, &quot;tr&quot; = &quot;sertifika (X.509)&quot;, &quot;uk&quot; = &quot;сертифікат (X.509)&quot;, &quot;vi&quot; = &quot;chứng nhận (X.509)&quot;, &quot;zh_CN&quot; = &quot;证书(X.509)&quot;, &quot;zh_HK&quot; = &quot;證書(X.509)&quot;, &quot;zh_TW&quot; = &quot;憑證(X.509)&quot;
flags:                      active  public  apple-internal  exported  core  trusted (0000000000000077)
conforms to:                public.data
tags:                       .cer, .der, .crt, .pem, application/x-x509-ca-cert

As you can see, all these extensions share the same type id, and thus in my Chrome they're all equivalent. This is not the case e.g. in Firefox, which does respect the specs and really filter by extension.

(Note: I don't think I've got anything that affected these extensions.)

Unfortunately there isn't much you can do about it, since using the MIME type (application/x-x509-ca-cert) would have the exact same result. The best would be to star the linked issue and hope they can fix it some day.

答案2

得分: 1

accept属性并不按照你期望的方式工作。以下是来自MDN文档的相关摘录:

accept属性不会验证所选文件的类型;它只是为了提示浏览器引导用户选择正确的文件类型。在大多数情况下,用户仍然可以切换文件选择器中的选项,以覆盖此提示并选择任何文件,甚至选择不正确的文件类型。

因此,你应该确保预期的要求在服务器端进行验证。

英文:

The accept attribute doesn't work in the way it seems you expect it to. Here's a relevant excerpt from MDN's documentation:

> The accept attribute doesn't validate the types of the selected files; it provides hints for browsers to guide users towards selecting the correct file types. It is still possible (in most cases) for users to toggle an option in the file chooser that makes it possible to override this and select any file they wish, and then choose incorrect file types.
>
> Because of this, you should make sure that expected requirement is validated server-side.

huangapple
  • 本文由 发表于 2023年6月16日 07:56:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486171.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定