SIS CLI

Known limitations

These are behaviours of sis 0.70.0 that are understood, measured and not yet fixed. Check this page before reporting a surprising verdict; if what you see matches an entry, you do not need a new issue unless you have a different symptom or a smaller reproduction.

Each entry gives the symptom you will see, why it happens in one sentence, and what to do meanwhile. Where the entry is about a verdict, the safe reading is the one the project holds throughout: unknown is not clean. Read analysis_coverage in sis scan --format json and the output of sis explain verdict <file> rather than the verdict word alone.

If what you see is not listed here, report it with a minimal reproduction.

Verdicts that can be wrong

The verdict can follow how a file was delivered, not only what it contains

  • Symptom. In the project’s own journey measurements, the same HTML content read differently by delivery shape: delivered as a plain HTML file, hostile and benign variants both read Clean; delivered inside a zip, an email-in-zip or a PDF-in-zip polyglot, benign variants read Suspicious with no content finding behind the verdict. The hostile plain-file cases are false-clean; the benign container cases are false-suspicious. These fixtures are abstract (reserved .invalid destinations, placeholder text), so part of the plain-file result may reflect fixture realism, but the container over-withholding does not depend on content.
  • Workaround. Do not treat a Clean on a plain HTML file as proof of safety, and do not treat a Suspicious on a container as proof of hostile content. Run sis explain members <file> to see what is inside and sis explain verdict <file> to see which triggers fired; a Suspicious with only a container trigger and no content finding is this limitation.

A PDF that opens on %PDF- and carries an unclaimed script body can read Clean

  • Symptom. A file that begins %PDF- at byte 0 and then carries a script or markup body (shell, PowerShell, JavaScript and similar), with no script extension or claimed type, is analysed as a PDF only. The script body is not classified and the file can scan Clean.
  • Why. The format classifier stops at the leading %PDF-. Headerless or offset-header PDFs and PDFs with a claimed script type do report the second reading in this release.
  • Workaround. Look at what follows the last %%EOF without opening the file in a viewer (for example tail -c 1024 <file> | strings). Do not rely on a Clean verdict for a PDF that carries trailing text.

A script hidden behind more than 256 KiB of filler after a PDF is not given a second reading

  • Symptom. A script body appended to a PDF is classified when it sits within 256 KiB after the PDF’s closing structure. A body behind more than that, written to mimic the PDF’s closing tokens, is not. In measurements such files were Suspicious with partial coverage, but nothing pins that.
  • Workaround. Treat partial coverage on a PDF as unknown. Large unexplained trailing data is itself worth investigating by hand.

Some verdicts are calibrated differently from what the file can do

  • Symptom. Four measured disagreements between a finding’s label and what the file can do: a High renderer-divergence finding on a PDF whose only action is a benign OpenAction alert; a High compression-ratio finding on homogeneous NUL padding; capability-named primitives (a font-matrix payload, a form HTML injection) staying Clean; and a heuristic shown as Medium/Certain while sis explain finding labels its reliability a weak heuristic.
  • Status. A measurement is pending; no severity will change before it.
  • Workaround. Read the finding’s reliability in sis explain finding <file> <id> before acting on its severity alone.

One benign noisy PDF reads Suspicious

  • Symptom. A benign PDF with many streams that decode at very high ratios reads Suspicious 0.75, driven by a High pdf:decode_budget_structural finding with no failed decodes.
  • Why. Since the decode-completeness change, decodes that were cut short no longer qualify for the benign-compression demotion. Either that is right and the expectation was stale, or it is a false positive; the decision is open.
  • Workaround. Check pdf:decode_budget_structural in sis explain verdict <file>; if the decode failures are zero and nothing else is High, it is this case.

Two malware classes read Clean

  • Symptom. An evasion-style PDF and a cluster of font-exploit PDFs read Clean in the project’s case studies, because high-volume signals alone need a genuine high-severity finding behind them.
  • Workaround. Do not treat Clean as proof of safety for a PDF with unusual fonts or heavy obfuscation signals; read sis explain verdict <file> and analysis_coverage. A structural discriminator is planned.

Benign PDFs with a contact email address can read Malicious

  • Symptom. A benign PDF that contains a mailto: link and common words such as “account”, “secure” or “verify” can be read as a phishing lure chain and score Malicious.
  • Workaround. Check sis explain verdict <file> for a phishing-chain trigger with no other evidence. A fix is planned.

Name checks are not complete

  • Symptom. A look-alike name is reported when it hides a dangerous extension, not when it imitates a program name. Some carriers do not pass a file name to the name checks: HTML download= attributes, the Windows shortcut target basename, OneNote embedded file names, PDF file-attachment annotations, the display name an embedded Office object carries, and the object name an RTF author attaches to an embedded object. Names the embedding itself declares are checked (an OLE Package’s or RTF object’s payload filename, an MHT part’s Content-Location, an Outlook MSG attachment’s name). A declared text encoding in email bodies, HTML and RTF is not applied before analysis.
  • Workaround. Inspect names in those carriers by hand.

A tag-character scheme hidden inside RTF markup is not reported

  • Symptom. A tag-character run placed inside an RTF control word is discarded by the parser before any text is analysed. In the document’s visible text the same characters are reported.

Encrypted content

Encrypted PDFs: decode is refused, not decrypted by pdf-object

  • Symptom. sis pdf-object <file> <obj> --stream --decode and --hexdump refuse on a PDF whose trailer declares encryption. --raw works.
  • Why. The command does not apply the PDF security handler. The scan path does apply it.
  • Workaround. Use --raw on the command, or scan with sis scan <file> --password-file <FILE> when you hold a claimed password; the password is tried only if it verifies against the document.

Output you may find confusing

A finding id does not identify one observation

  • Symptom. Two distinct findings can share one sis-<hash> id (for example two font-hinting errors of different kinds on one object), and one underlying observation can be reported two or three times, once per container that reaches it (for example a script reported once as an annotation, once as an additional-action event, once as an action). Counts, chains and volume triggers are inflated by the duplicates, and sis explain finding <file> <id> or sis query --from-report can be ambiguous.
  • Workaround. Use kind plus objects and the evidence span to tell findings apart. Do not count findings of one kind as independent observations. A redesign of finding identity is planned and is not part of this release.

Materialised script and font members read “not attempted”

  • Symptom. In the asset graph, a pdf:javascript_* or pdf:font_program_* member shows not_attempted with no findings, while its findings are attached to the PDF root. Embedded-file members do carry their findings.
  • Workaround. Read the findings on the root; they are the analysis of those members.

shape can name a format that no view or finding shows

  • Symptom. The shape probe lists a candidate (for example a flash.swf, image.bmp, image.tiff or document.pdf candidate inside another file) that the report never exposes as a view, asset or finding, and shape.primary can disagree with root_support.format.
  • Workaround. root_support.format (with root_support.lane when present) is the authoritative root identity. Use sis explain detection <file> to see why a format was or was not chosen.

Time budgets can cut low-severity PDF findings under heavy load

  • Symptom. Under heavy machine load, some PDF findings (for example pdf:embedded_file_present, pdf:content_stream_anomaly, pdf:action_automatic_trigger) can be fewer than on an idle run of the same file, because a per-detector time budget expired.
  • Workaround. Read analysis_coverage: when this happens it is not complete and carries an omission detector_wall_clock_exhausted naming the budget (budget.pdf.embedded_files.scan_ms, and so on). Re-scan on an idle host to get the full set. Count-based budgets that remove the dependence on load are planned.

Text heuristics run over font program bytes

  • Symptom. unicode:deletion_control_abuse (experimental, Low) can fire on a binary TrueType program embedded in a PDF, and file:unicode_script_diversity samples raw PDF bytes.
  • Workaround. Check unicode.channel_source; a pdf:stream:... that is a font program is this noise.

Three small reporting defects

  • Symptom. (1) The pdf:multimodal_analysis_skipped omission can carry reason_id: decode_budget_exhausted although the lane is disabled by policy; (2) pdf:embedded_file_present and pdf:embedded_script_present can carry action.initiation: automatic on a PDF with no OpenAction, Launch or additional action; (3) chain.parent_relationship: "pdf->js" can appear on an embedded shell-script finding.
  • Workaround. Check the raw PDF for the trigger before believing automatic; read multimodal.skip_reason in the finding’s metadata for the real reason.

Root format and archive reporting

These affect how the root of a file is labelled and in some cases which parser reads it. They are reported, not hidden: the archive lane still runs unless an entry says otherwise.

  • A valid ZIP or OOXML holding a stored RAR or 7z is analysed as that member. Symptom: the ZIP’s other members go unread and rar_not_extracted appears. root_support.format is correct (zip). Workaround: extract the outer ZIP and scan its members one by one.
  • A leading non-printable magic can name the root before it is checked. Symptom: a \x7FELF (or PNG, JPEG, TIFF) signature followed by zeros in front of a real archive reports root_support.format = "elf". The archive lane still runs. Workaround: read root_support.lane.
  • A complete PDF behind a printable prolog (<?xml, <svg, {\rtf, GIF89a) is not routed to the PDF lane. Workaround: scan with the extension the file should carry.
  • The asset-graph root of a prefixed container still reads zip:root, format: zip. For an ELF or TIFF carrying a RAR the graph root says zip while root_support says elf with lane: zip. Workaround: trust root_support.
  • root_support.format reports pdf for bytes only the PDF default fallback took. A file no classifier identifies reports pdf; sis explain detection <file> shows default_fallback.
  • root_support.format and runtime_support_state can come from different entries. For a carrier-held archive format is the identity and runtime_support_state is the lane’s.

Commands

sis query and sis scan can list different findings for the same file

sis query and sis scan can list different findings for the same file. Legacy sis query always runs the more expensive content detectors, which sis scan runs only with --deep, so sis query can show extra findings, including some Medium ones, for example pdf:content_validation_failed and pdf:declared_filter_invalid; it also skips two file-level checks that sis scan runs, file:hex_string_density and file:analysis_constrained. Findings attributed only to a nested member are not in sis query’s plain findings list. sis scan is authoritative for verdicts; to compare like with like, use sis scan --deep. The query engine planned after this release uses the same detector profile as sis scan.

A benign XML plus HTML-emitting-stylesheet zip still reads Suspicious under sis scan --fast

--fast skips the html lane, so a benign XML plus HTML-emitting-stylesheet zip still raises file:polyglot_signature_conflict and reads Suspicious. Use the default profile.

Preview commands can change (D2)

sis pdf-object and sis pdf-export are previews. Their flags and output may change between releases.

Sanitisation is a preview and refuses rather than guesses

  • Symptom. sis sanitize apply and sis sanitize release cover selected formats. For a PDF they remove every embedded file structurally, and release refuses a derivative that still holds one. Inputs the sanitiser cannot establish as safe are refused with no output written (for example a PDF with an unresolvable /Root, a wrong-context font carrier or an XFA form). ISO, 7z and RAR archives have no sanitiser; only ZIP does. sanitize release runs the isolated sis-cdr-worker, which ships next to sis in every release archive.
  • Workaround. A refusal is never evidence that a file is safe. Read the transform report and omissions, and re-scan the derivative.

HTML, HTA and SVG sanitisation is not supported

  • Symptom. The markup proof for these formats is being rebuilt, so they are refused rather than sanitised. The generated format-support-matrix.md may list a CDR “yes” for them without that qualification.
  • Workaround. Do not use sanitize output for HTML, HTA or SVG as a release decision.

policy-bundle-lint reports contract errors on the shipped bundle

  • Symptom. Two font-analysis kinds have no contract, and 17 known intent-bucket warnings are listed. Calibration is unaffected and the lint is advisory.

Not in this release

  • sis-guardian, sis-guardian-mcp and sis-cdr-gateway are not part of this release.
  • The unified query language is present only as a hidden, unsupported preview command in this build; use sis query.
  • ML and OCR features are not in the release build.
  • HTML, HTA and SVG are not supported for sanitisation in this release.