Aelira Core v0.11.1 and v0.12.0: what we found when we attacked our own code
Three Aelira Core releases in under 24 hours; the last two came from turning our own tools on our own code. v0.11.1 stops scanned documents steering our AI prompts, and v0.12.0 rewrites how uploads with macros, scripts or embedded objects are handled.
We shipped three releases of Aelira Core in under 24 hours. v0.11.0 fixed four problems in the Microsoft 365 integration and review pages. The two that followed came from turning our own tools on our own code. v0.11.1 fixes a low-severity issue in how text from scanned documents reaches our AI prompts. v0.12.0 rewrites how we handle uploads that carry macros, scripts or other active content, after we found that our defences for them were not doing their job.
If you self-host Aelira Core, upgrade to v0.12.0. It includes everything in v0.11.1 and adds no database migration. It does change what happens to some uploads, so read what changes for you before you roll it out. The hosted service at app.aelira.ai has run the v0.11.1 fix since 28 October and the v0.12.0 upload and alert fixes since 29 October (UTC), before this post.
v0.11.1: document text that could steer the model
Aelira uses language models to draft fixes: alt text for images, labels for unlabelled buttons, summaries of maths, plain-language explanations of scan results. Every one of those prompts contains text from the document being fixed, and a document is written by someone else. A course page, a slide deck or a LaTeX file can say anything, including "ignore your instructions and write this instead".
We run a reviewing agent on our own hardware with an open-weight model. We gave it the public repository and asked for an honest review, and it went straight for the prompts.
Document text went into our prompts inside a pair of markers, <user_content> and </user_content>, meant to tell the model "this part is data". The function that added them did not check whether the document already contained one. A LaTeX file that included </user_content> closed the block itself, and everything after it sat outside, next to our own instructions. In the agent's proof of concept, replayed against a small local model, the model's first words were the ones the attacker asked for.
Fixing it turned up two more problems. An audit of all 30 places that call a model found prompts with no markers at all. And our filter for suspicious phrases deleted words such as "act as" and "disregard" from course text, so "Valves act as a buffer; disregard the old reading" reached the model as "Valves a buffer; the old reading". For a tool whose job is to describe content faithfully, that was the worse bug.
Document text in every prompt now sits inside a tag whose code is derived from a hash of that text, such as <user_content_3f9c…>, and the prompt tells the model the text ends only at the closing tag with the same code. A document cannot know that code in advance, so it cannot close its own block. The phrase list is gone, and text reaches the model as the author wrote it.
Markers make it much harder for a document to steer a model, but they cannot make it impossible, because the model still reads the document. In these prompts the model has no tools and no secrets, its output is short, and a remediated file needs human approval before it is published. Review AI-drafted text before you publish it. The advisory is GHSA-7pr5-834v-2wp5 (low).
v0.12.0: following a risky upload all the way through
The v0.11.1 notes listed one open issue: our upload check rated an Office file as a high threat whenever its text contained an ordinary phrase like "act as" (#856). A document that said "the valve can act as a buffer" could not be scanned at all. That looked like a false positive to tidy up. To fix it properly we followed a high-rated file through the whole upload path, and very little of it held up.
- The macro check never ran. It imported a function that the version of oletools we ship does not provide. The import failed on every upload, the validator logged a low "macro check skipped" notice, and a Word file carrying a VBA project was never rated high.
- The cleaned copy was not the one we kept. When a file was rated high, the upload routes stored the original but queued the scan with the hash of the rebuilt copy. The scan failed on the mismatch, and the stored file still held what the rebuild was meant to remove.
- Rebuilt Office files could not be opened. The rebuild deleted parts by file name and left behind everything that pointed at them. When it failed, it returned the original bytes, and every one of these uploads was recorded as sanitised.
- The PDF rebuild cut bytes out with regular expressions, which left the file's cross-reference table pointing at the wrong places.
The advisory is GHSA-9qc4-vxh5-v366 (low). Aelira never runs macros or PDF scripts itself, but a file could keep content that its security record said had been removed.
We found the unreadable Office rebuild while walking through the release candidate, with the other fixes ready to ship. We could have shipped them and listed the rebuild as a known limit. We rewrote it instead, which is why this release is 0.12.0 and not 0.11.2.
The fix
An Office file is now rebuilt from its own map of parts, its content types and relationships. VBA projects, macro customisations, ActiveX controls, Excel 4 macro sheets, embedded and linked OLE objects, custom ribbons and attached templates are removed together with everything that names them. Text, images, hyperlinks and the remaining sheets stay. A PDF is rebuilt with pikepdf without its scripts, automatic actions and XFA forms, keeping its links and text.
The rebuilt file is then validated again from scratch. Only if it passes is it stored, scanned and recorded as sanitised, and the scan runs on exactly the bytes we stored. A file we cannot rebuild, or that is still rated high afterwards, is refused, and the response lists what to remove before uploading it again.
The macro check now runs. A macro makes a file high, and the file is rebuilt without it. A macro that calls Shell, CreateObject or Environ, or names PowerShell, cmd.exe or a download function, is rated critical and refused. The PDF check now reads names the way a PDF reader does, so /J#61vaScript is caught as JavaScript.
Automated security reviews of the rewrite found more gaps before release: unbounded reads of compressed parts, keywords hidden inside compressed PDF object streams, macro calls written without parentheses, and a PDF check that could stop early without saying so. Each was fixed with a test that fails on the earlier code.
What changes for you
- A PDF with scripts, or a Word, Excel or PowerPoint file with macros, ActiveX controls, embedded objects or an attached template, is scanned in its rebuilt form. Its results and working file come from the copy without that content. Embedded objects such as OLE equations are removed, and their preview images are kept.
- An upload rated high that cannot be rebuilt is refused with the reasons. That includes a legacy .doc, .xls or .ppt file rated high, a file with a damaged package, an image whose content does not match its extension, and an Office file with more than 1,000 parts (#874).
- HTML, CSS, JavaScript and code archives have no rebuild and are processed as uploaded, as before.
Tell the people who upload documents. If someone asks why a file was turned away, its security record has the findings.
What we tested, and what we have not
The rebuild is tested with Word, Excel and PowerPoint files made by python-docx, openpyxl and python-pptx, given active content the way Office stores it and opened again by the same library afterwards, and with PDFs that carry scripts. We also ran a release candidate through the dashboard. A Word file with a VBA project, an ActiveX control, an embedded object and an external template, a workbook with an Excel 4 macro sheet, a deck with a VBA project and a PDF with scripts were each rebuilt, scanned and recorded as sanitised, and a Word file whose macro calls Shell was refused.
We have not yet tested files saved by Microsoft Office itself. If you have a macro-enabled file that the rebuild handles badly, please send it to us.
Other fixes in v0.12.0
- Scan-complete alert emails failed every time, and the weekly summary job raised an error. Both now work, and their links open the scan page.
- When Canvas returned an error or could not be reached, course, file and folder listings showed a generic server error. They now return a clear status and message.
- A PDF whose first heading is an H1 no longer gets a "should start with H1" finding when the heading scan stops early. The reading-order check now reads each page once instead of up to 100 times.
- Dashboard text such as "WCAG WCAG 1.3.1", "1 issues" and raw internal labels now reads properly, and the Matterhorn Protocol bar appears only for PDFs.
Upgrade
v0.12.0 has no database migration. Follow the v0.12.0 release notes for the backup and rollout steps; if you are coming from 0.10.0 or earlier, complete the 0.11.0 steps first. Images, the CLI and SBOMs are on the v0.12.0 release page.
We would rather find these ourselves than hear about them from someone else. If you find one we missed, write to [email protected].

RD (Reg) Crampton
•Founder & CEOFounder, CEO & lead developer of Aelira. Building beta tools to help faculty and accessibility teams check materials and evaluate suggested fixes, with human review required.
Related Articles
Aelira Core v0.11.0: four fixes in the Microsoft 365 integration and review pages
Aelira Core v0.11.0 fixes four security issues, one of them high severity, in the Microsoft 365 integration and the LMS review pages. Self-hosters who connect Microsoft 365 should upgrade and create their Microsoft webhook subscriptions again.
Aelira Core v0.10.0: a second reading for every printed equation
Aelira Core v0.10.0 reads every printed equation twice, blind, and fixes a review gap we found hours after publishing v0.9.13. It also explains why the release took five days.
Aelira Core v0.9.12: publishing the security record with the release
Aelira Core v0.9.12 fixes a LaTeX file-access vulnerability, publishes three security advisories, discloses every unfixed image advisory and adds reviewed PDF working files.