我有一个允许用户上传附件的网络应用;但是,我想将用户限制为仅限某些文件类型 - Adobe PDF和MS Excel。 原因是在用户提交文档进行处理和工作流程之前,我将汇总一些附件并创建一个PDF报告。
我做了一些研究并转换DOC(X),RTF等......会很头疼。 而且每个人都会在理论上和#34;如果附件都是PDF格式,则可以获得更好的查看可移植性。
目前我正在检查mime类型 -
PDF - "application/pdf"
XLS(X) -
"application/vnd.ms-excel"
"application/msexcel"
"application/x-msexcel"
"application/x-ms-excel"
"application/x-excel"
"application/x-dos_ms_excel"
"application/xls"
"application/x-xls"
这很有效,但我注意到我可以采用.docx
文件并将其更改为.pdf
并成功绕过此检查。< / p>
为了解决这个问题,我计划进一步检查实际文件的标题。
根据文件签名的this library
PDF将包含以下标题 -
25 50 44 46
它将有以下预告片之一 -
0A 25 25 45 4F 46 (.%%EOF)
0A 25 25 45 4F 46 0A (.%%EOF.)
0D 0A 25 25 45 4F 46 0D 0A (..%%EOF..)
0D 25 25 45 4F 46 0D (.%%EOF.)
到目前为止,我已经有了执行此检查的框架代码 -
**编辑反映回答**
public boolean confirmAttachmentAuthenticity(ProposalDevelopmentForm form, String mimeType) {
boolean authentic = true;
// Case: User is attempting to upload a "PDF" document
if (mimeType.equals(ADOBE_PDF_CONTENT_TYPE)) {
try {
InputStream inputStream = form.getNewNarrative().getNarrativeFile().getInputStream();
PdfReader pdfReader = new PdfReader(inputStream);
int numberOfPages = pdfReader.getNumberOfPages();
if (numberOfPages > 0) {
// Success - valid PDF
info(form.getNewNarrative().getNarrativeFile().getFileName() + " validated authentic Adobe PDF file");
}
}
catch(IOException ioe) {
// Failure - masquerading PDF
authentic = false;
info(form.getNewNarrative().getNarrativeFile().getFileName() + " is not an authentic Adobe PDF file.");
reportError("newNarrative.narrativeFile",
KeyConstants.ERROR_ATTACHMENT_PDF_NOT_AUTHENTIC,
form.getNewNarrative().getNarrativeFile().getFileName());
}
catch (Exception e) {
// Failure - other causes
authentic = false;
info(form.getNewNarrative().getNarrativeFile().getFileName() + " could not be authenticated at this time.");
e.printStackTrace();
reportError("newNarrative.narrativeFile",
KeyConstants.ERROR_ATTACHMENT_TYPE_CORRUPTED,
form.getNewNarrative().getNarrativeFile().getFileName());
}
}
// Case: User is attempting to upload an "EXCEL" spreadsheet
else {
try {
InputStream inputStream = form.getNewNarrative().getNarrativeFile().getInputStream();
POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);
HSSFWorkbook workBook = new HSSFWorkbook(fileSystem);
int numberOfSheets = workBook.getNumberOfSheets();
if (numberOfSheets > 0) {
// Success - valid Excel Spreadsheet
info(form.getNewNarrative().getNarrativeFile().getFileName() + " validated authentic MS Excel file");
}
}
catch(IOException ioe) {
// Failure - masquerading XLS(X)
authentic = false;
info(form.getNewNarrative().getNarrativeFile().getFileName() + " is not an authentic MS Excel file.");
reportError("newNarrative.narrativeFile",
KeyConstants.ERROR_ATTACHMENT_XLS_NOT_AUTHENTIC,
form.getNewNarrative().getNarrativeFile().getFileName());
}
catch (Exception e) {
// Failure - other causes
authentic = false;
info(form.getNewNarrative().getNarrativeFile().getFileName() + " could not be authenticated at this time.");
e.printStackTrace();
reportError("newNarrative.narrativeFile",
KeyConstants.ERROR_ATTACHMENT_TYPE_CORRUPTED,
form.getNewNarrative().getNarrativeFile().getFileName());
}
}
return authentic;
}
我认为最好的方法是使用BinarySearch
方法来执行此操作。
但是,我还阅读了一些人们建议将fileData转换为字符串然后使用正则表达式的帖子。
任何想法都会受到赞赏。
如果你可以帮助我开始填写我的骨架代码中的任何一个案例,那么奖励积分。 我的逐位逻辑知识生疏了。这是我过去一年编写的高级客户端代码所能得到的。
答案 0 :(得分:1)
永远不会信任来自客户端的传入请求,标头值可以更改,并且它不会反映请求正文中的内容。
使用第三方库来检查文件是PDF还是Excel或其他内容。
检查文档是否为PDF,例如尝试使用iText打开文档,Excel尝试使用Apache POI打开文档。