T09 · Insecure Skill Coding Practices
- Location
scripts/delay_calculator.py:182- Finding
Spreadsheet Formula Injection in Delay Analysis CSV Export
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent local construction-law drafting and deadline toolkit, with some security and confidentiality caveats users should understand.
Install only if you are comfortable with a local legal-workflow aid. Keep matter files and generated reports in approved confidential storage, review CSV outputs before opening them in spreadsheets, and do not set up the suggested BCA mirror or cron refresh unless you explicitly want that background maintenance.
scripts/delay_calculator.py:182Spreadsheet Formula Injection in Delay Analysis CSV Export
The code supports only a narrower subset of the declared description: generating document templates for claims, notices, EOT applications, interim claims, variation claims, disruption/loss-and-expense claims, and final accounts across several construction contract forms. That aligns with the drafting/generation part of the description, but the declared purpose presents a much broader toolkit with analytical and computational features that are absent from the code. In particular, there is no logic for clause analysis, risk allocation assessment, obligations register creation, notice calendar management, statutory deadline calculation, eGazette holiday verification, dispute-resolution workflow support, or MDB procurement analysis. The script is therefore materially narrower than described, making the description inaccurate as a representation of what this code chunk actually does.
Yes, there is a mismatch based on the supplied code chunk. The description claims a wide-ranging construction-contract and statutory-deadline toolkit, but the actual code shown is only a wrapper script whose sole function is to call main() from delay_calculator.py. Since the referenced implementation is not present, none of the declared capabilities can be verified from this chunk. The observable primary purpose here is compatibility/entry-point delegation for a delay calculator, which is materially narrower than the declared toolkit. This is not merely an implementation detail; the supplied code provides far less functionality than advertised.
The code is clearly focused on one specific operational function: delay-event input and simplified delay/EOT analysis. It parses baseline dates and delay events from JSON/CSV/CLI, calculates durations, concurrency, EOT entitlement, projected completion, and LD exposure, and renders a report. While this is loosely related to construction claims and EOT issues, it does not implement most of the declared toolkit capabilities. In particular, there is no clause analysis, no legal drafting, no obligations register creation, no statutory deadline engine, and no retrieval or verification of Singapore holiday/eGazette data. The declared description presents a broad legal/contract-administration toolkit, but the supplied code chunk is a narrow delay calculator. That is a material description-behavior mismatch, even though the subject matter is adjacent.
The declared description presents a comprehensive construction-contract toolkit covering multiple contract regimes, drafting/generation functions, deadline computation against holiday data, and Singapore/MDB-specific legal support. The supplied code does not implement that broad toolkit. Instead, it is a narrow comparator script for selected FIDIC forms only, using hard-coded comparison data and simple command-line formatting/output. While one declared use case—comparing contract forms/risk allocation—is partially consistent with the script, the primary declared purpose is much broader than the actual behavior, and several prominent capabilities are absent. Therefore the description does not accurately represent what this code chunk actually does.
The description promises a comprehensive legal/construction-contract toolkit with drafting, analysis, claims, procurement, dispute-resolution, and Singapore-law support. The supplied code only implements one sub-function: computing deadlines based on day-counting rules and holiday calendars. That deadline feature is consistent with part of the description, but the actual primary behavior is much narrower than the declared purpose. This is a material description-behavior mismatch because the code lacks nearly all of the headline toolkit capabilities and instead behaves as a standalone CLI calculator.
The declared description presents a comprehensive legal-analysis and drafting toolkit with deadline computation against holiday data and broad Singapore/MDB coverage. The supplied code is much narrower: it only selects a hardcoded set of notice/obligation entries for certain contract forms and renders them as CSV or Markdown. Although this partially aligns with the stated use case of building obligations registers or notice calendars, it does not implement most of the described capabilities, especially legal analysis, claims/EOT drafting, or statutory deadline computation. Additionally, the code includes NEC4 support, which is outside the declared scope. Therefore the description does not accurately represent what this code chunk actually does.
The supplied code is materially narrower than the declared description. It only calculates Singapore SOP Act payment/adjudication timelines using local holiday data and emits formatted output. While this partially overlaps with the declared mention of computing statutory deadlines and Singapore SOP Act usage, it does not support the many other advertised functions such as contract-form comparison, clause analysis, drafting notices/claims/EOT applications, obligations registers, or broader FIDIC/PSSCOC/SIA/MDB procurement assistance. Additionally, the description suggests eGazette-verified holiday data, but the code merely reads a bundled JSON file or hardcoded fallback dates, with no verification or external retrieval. This is a description-behavior mismatch because the primary declared scope and capabilities significantly exceed what the code chunk actually does.
The description presents a comprehensive legal/construction-contract toolkit spanning multiple contract forms and substantive legal drafting/analysis tasks. The supplied code, however, only tests a deadline calculator and holiday-loading behavior. There is no evidence here of notice generation, claims preparation, clause/risk analysis, obligations register building, procurement framework comparison, dispute-resolution tooling, or MDB-specific support. While the tested deadline functionality is consistent with one small part of the declared description, the actual behavior in this chunk is materially narrower in primary purpose. There is no sign of harmful undeclared resource access or unrelated behavior; the mismatch is mainly scope and capability overstatement relative to this code chunk.
The declared description is for a domain-specific construction contract/legal drafting and deadline-computation toolkit. The supplied code does not analyze contracts, generate notices or claims, compute statutory deadlines, use holiday data, or perform any construction-law function. Instead, it implements a security guardrail test for Python scripts by scanning source code for prohibited modules and calls. This is a materially different primary purpose and an undeclared capability unrelated to the declared triggers.
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.
> 📂 **Live BCA updates:** BCA publishes circulars at https://www1.bca.gov.sg/resources/circulars/. Recommend mirroring locally (e.g. `bca-circulars/` workspace folder, refreshed weekly via heartbeat/cron) and **consulting the latest circulars first** for current requirements on SOP Act timelines, plan fees, CORENET-X, BC1/structural codes, cost-sharing schemes, productivity grants, and buildability — BCA updates can change procedural requirements without warning.
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.
lower = desc.lower()
has_ok = any(phrase in lower for phrase in ok_phrases)
self.assertTrue(has_ok,
f"Silver {party} references Engineer without disclaimer: {ob}")
def test_md_output_all_forms(self):
"""MD output should work for all forms."""
Without declared permissions the skill's intent is opaque and cannot be validated.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
## Why only Singapore?
Holiday calendars vary by sub-jurisdiction (Malaysian state, UK constituent country, individual emirate), shift by moon-sighting, and are gazetted by each government's authoritative source. Rather than ship best-effort data that users might rely on without verification, we provide a clean extension mechanism and let users bring verified data from their own jurisdiction's gazette.
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.
print("Available commands:\n")
for cmd, (script, desc) in SUB_COMMANDS.items():
print(f" {cmd:12s} {desc}")
print("\nRun any command with --help for its specific options, e.g.:")
print(" python3 construction_law.py notices --help")
print(" python3 construction_law.py claims --help\n")
print("Or call the underlying script directly:")
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.
print("Available commands:\n")
for cmd, (script, desc) in SUB_COMMANDS.items():
print(f" {cmd:12s} {desc}")
print("\nRun any command with --help for its specific options, e.g.:")
print(" python3 construction_law.py notices --help")
print(" python3 construction_law.py claims --help\n")
print("Or call the underlying script directly:")
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
saved_argv = sys.argv
sys.argv = [f"{module_name}.py"] + argv
try:
mod = __import__(module_name)
if hasattr(mod, "main"):
mod.main()
else:
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
saved_argv = sys.argv
sys.argv = [f"{module_name}.py"] + argv
try:
mod = __import__(module_name)
if hasattr(mod, "main"):
mod.main()
else:
The comment says obligations coverage is only 'fidic-red, psscoc, sia', but the code immediately below declares OBLIGATIONS_FORMS to also include 'fidic-yellow' and 'fidic-silver'. This is an active contradiction in inline documentation about what the tool supports, which can mislead operators about the script's actual behavior.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
if fmt == "md":
lines = ["# FIDIC Contract Comparison", "",
f"**Forms:** {', '.join(FORM_NAMES[f] for f in form_list)}",
f"**Generated:** {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M')}",
""]
for t in topics:
The script saves detailed matter-intake data to an arbitrary local file path with no explicit warning, consent checkpoint, or protective handling, even though the data can include sensitive legal strategy, dispute facts, deadlines, and party positions. In the context of a construction-law intake tool, this increases confidentiality risk because users may unknowingly persist privileged or commercially sensitive matter details on shared machines, synced folders, or insecure storage.
The generated report can be written directly to disk without any user-facing warning, despite likely containing sensitive factual summaries, contractual positions, timing assessments, and dispute strategy. For a legal workflow tool, silent persistence is especially risky because output files may be forwarded, indexed, backed up, or exposed through normal workstation and document-management behavior.
The manifest specifically describes support for FIDIC (Red/Yellow/Silver), PSSCOC, SIA, Singapore SOP Act, and MDB procurement frameworks such as ADB and World Bank. This file adds a separate notice calendar dataset for NEC4, which is a substantive legal-content capability not stated in the skill's described scope.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
"contractor": [
{"clause": "4", "obligation": "Execute and complete Works", "timing": "Per programme", "priority": "Critical", "category": "Works"},
{"clause": "5", "obligation": "Provide Performance Bond", "timing": "Before Commencement", "priority": "Critical", "category": "Financial"},
{"clause": "7", "obligation": "No assignment without consent", "timing": "Ongoing", "priority": "High", "category": "Administration"},
{"clause": "10", "obligation": "Appoint site agent/supervisor", "timing": "Before Commencement", "priority": "High", "category": "Administration"},
{"clause": "11", "obligation": "Provide adequate workforce", "timing": "Ongoing", "priority": "High", "category": "Resources"},
{"clause": "16", "obligation": "Take care of Works, materials, plant", "timing": "Until completion", "priority": "High", "category": "Works"},
This code file performs a file write by exporting comparison data to comparison.csv. Although the script prints a success message after saving, there is no warning or confirmation before the write and no comment/docstring disclosing that the demo will create a file in the working directory.
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
No suspicious patterns detected.